How to implement protected members using the closure approach to OOP?

I am now using closure to implement OOP in Lua. The following is a shortened example. My problem arises when trying to implement stronger_heal inside infested_mariner .

 -------------------- -- '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 

If I put the definition of infested_mariner in another .lua file, it will not be able to access the global private variables or access the private variables defined in the base .lua file. How can I protect members that only infested_mariner can access, and the solution does not imply all the derived classes in the same file as the parent?

Note. I am currently using getters and setters in a child class.

+6
source share
2 answers

In Lua, you can only access local variables in your area. In order for other functions to see your variables, you will need to rewrite them so that the protected variables are in a table accessible by the child class.

One way to do this is to simply make the properties publicly available in the current class and use naming conventions (e.g. names starting with underscores) to denote protected things. You probably know this, but I have to say that I think that this approach is usually much easier to implement than real protected variables.

If you need real protected variables, you need to separate the table from public and protected materials. One approach is to change the blessing function so that it receives both of these tables:

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

How to set things up so that the designers pass the protected table to each other remains an exercise. If you are following this route, you probably want some function to execute it for you, so that you cannot instantly touch the protected table.

+1
source

This is a limitation of the closure approach. No access to hp due to shutdown.

This is a kind of ideological problem ... Some people say that protected members inhibit encapsulation, so they should be avoided: make all data confidential and expand the interface if necessary (add public functions). People who speak tend to close.

If you want to use protected members, I probably would not use a closure approach. A good naming convention is probably the easiest.

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

Of course, the data is actually publicly available, but this approach works very well. This is pretty much what Python does. This is useful when you want to mess with internal components, for example, for testing.

+1
source

Source: https://habr.com/ru/post/945868/


All Articles