2013-05-26 18 views
6

Hiện tại tôi đang sử dụng closures for implementing OOP ở Lua. Một ví dụ tóm tắt sau. Vấn đề của tôi xảy ra khi cố gắng triển khai stronger_heal bên trong infested_mariner.Làm thế nào để thực hiện các thành viên được bảo vệ khi sử dụng phương pháp đóng cửa cho OOP?

-------------------- 
-- 'mariner module': 
-------------------- 
mariner = {} 

-- Global private variables: 
local idcounter = 0 
local defaultmaxhp = 200 
local defaultshield = 10 

function mariner.new() 
    local self = {} 

    -- Private variables: 
    local hp = maxhp   

    -- Public methods: 

    function self.sethp (newhp) 
     hp = math.min (maxhp, newhp) 
    end 
    function self.gethp() 
     return hp 
    end 
    function self.setarmorclass (value) 
     armorclass = value 
     updatearmor() 
    end 


    return self 
end 

----------------------------- 
-- 'infested_mariner' module: 
----------------------------- 

-- Polymorphism sample 

infested_mariner = {} 

function infested_mariner.bless (self) 

    -- New methods: 
    function self.strongerheal (value) 
    -- how to access hp here? 
    hp = hp + value*2 
    end  

    return self 
end 

function infested_mariner.new() 
    return infested_mariner.bless (mariner.new()) 
end 

Nếu tôi đặt định nghĩa infested_mariner của tôi trong một file .lua, nó sẽ không thể truy cập các biến tin toàn cầu, hoặc truy cập vào các biến tư nhân, được định nghĩa trong tập tin cơ sở .lua. Làm cách nào để tôi có các thành viên được bảo vệ mà chỉ infested_mariner mới có thể truy cập và giải pháp không liên quan đến việc có tất cả các lớp dẫn xuất trong cùng một tệp với cha mẹ?

Lưu ý: Hiện tại tôi đang sử dụng getters và setters trong lớp con.

Trả lời

1

Trong Lua, bạn chỉ có thể truy cập các biến cục bộ trong phạm vi của chúng. Để cho phép các hàm khác nhìn thấy các biến của bạn, bạn sẽ cần viết lại nó để các biến được bảo vệ nằm trong một bảng có thể truy cập được bởi lớp con.

Một cách để làm điều này là chỉ cần tạo thuộc tính công khai trong lớp hiện tại và sử dụng quy ước đặt tên (như tên bắt đầu bằng dấu gạch dưới) để biểu thị nội dung được bảo vệ. Bạn có thể biết điều này nhưng tôi phải nói rằng tôi nghĩ rằng phương pháp này thường là nhiều hơn đơn giản hơn để thực hiện so với các biến được bảo vệ thực.

Nếu bạn muốn các biến được bảo vệ thực sự, bạn cần phải tách bảng cho công chúng và nội dung được bảo vệ. Một cách tiếp cận là để thay đổi ban phước cho chức năng để nó nhận cả hai bảng:

function infested_mariner.bless (pub, pro) 
    -- New methods: 
    function pub.strongerheal (value) 
    pro.hp = pro.hp + value*2 
    end 
    return pub 
end 

Làm thế nào để thiết lập những điều để nhà xây dựng vượt qua bảng được bảo vệ với nhau là để lại một tập thể dục. Nếu bạn đi tuyến đường này bạn có thể muốn có một số chức năng làm điều đó cho bạn để bạn không có cơ hội chạm vào bảng được bảo vệ trong một ngày này sang ngày khác.

1

Đây là giới hạn của cách tiếp cận đóng. Không có cách nào để truy cập hp từ bên ngoài việc đóng cửa.

Đó là một vấn đề tư tưởng ... Một số người nói rằng các thành viên được bảo vệ đóng gói phanh, vì vậy cần tránh: Làm cho tất cả dữ liệu riêng tư và mở rộng giao diện nếu cần (thêm các chức năng công cộng). Những người nói rằng có xu hướng thích cách tiếp cận đóng cửa.

Nếu bạn muốn sử dụng thành viên được bảo vệ, tôi có thể không sử dụng cách tiếp cận đóng. Một quy ước đặt tên tốt có lẽ là điều dễ nhất.

self.public_thing = "asdf" 
self._protected_thing = "asdf" 

Chắc chắn, dữ liệu thực sự là công khai, nhưng cách tiếp cận này hoạt động khá tốt. Đây là khá nhiều những gì Python làm. Nó có ích khi bạn muốn gây rối với nội bộ, như để thử nghiệm.

Các vấn đề liên quan