From: "Eustaquio Rangel de Oliveira Jr." Date: 2004-12-30T22:17:17+09:00 Subject: Inheritance of class variables Hello there. I was talking with chris2 and matju on the irc channel and they gave me good explanation about this point, but I'd like to share it with you and discuss something about it. I was asking about if, when defined on a parent class, a class variable overwrites the class variables with the same name on it's children. For example: ------------------------------------------------------------------------ class CarBuilder @@total_of_cars=0 def initialize(name) @name = name end def build puts "#{@name} building another car ..." @@total_of_cars +=1 end def total_of_cars "#{@name} built #{@@total_of_cars} cars" end end class Honda < CarBuilder @@total_of_cars=0 def initialize super("Honda") end end class Ford < CarBuilder @@total_of_cars=0 def initialize super("Ford") end end h = Honda::new f = Ford::new puts h.total_of_cars puts f.total_of_cars h.build h.build h.build f.build puts h.total_of_cars puts f.total_of_cars ------------------------------------------------------------------------ Running this code we have: ------------------------------------------------------------------------ Honda built 0 cars Ford built 0 cars Honda building another car ... Honda building another car ... Honda building another car ... Ford building another car ... Honda built 4 cars Ford built 4 cars ------------------------------------------------------------------------ So, there is a mistake here. Honda built 3 cars and Ford 1, and not 4 for Honda and 4 for Ford. They are sharing the parent class variable, not matter if it was defined on the children also. Matsu told me that who came first is the boss, so if @@total_of_cars was defined on the parent, not matter what, all the other children will refer to it. I can live with that making some hacks ehehe but let me see: ------------------------------------------------------------------------ class CarBuilder def initialize(name) @name = name end def build puts "#{@name} building another car ..." increase end def increase end end class Honda < CarBuilder @@total_of_cars=0 def initialize super("Honda") end def increase @@total_of_cars +=1 end def total_of_cars "#{@name} built #{@@total_of_cars} cars" end end class Ford < CarBuilder @@total_of_cars=0 def initialize super("Ford") end def increase @@total_of_cars +=1 end def total_of_cars "#{@name} built #{@@total_of_cars} cars" end end h = Honda::new f = Ford::new puts h.total_of_cars puts f.total_of_cars h.build h.build h.build f.build puts h.total_of_cars puts f.total_of_cars ------------------------------------------------------------------------ Running it I got: ------------------------------------------------------------------------ Honda built 0 cars Ford built 0 cars Honda building another car ... Honda building another car ... Honda building another car ... Ford building another car ... Honda built 3 cars Ford built 1 cars ------------------------------------------------------------------------ That is the correct behaviour. But let check what I changed there on the code: - I removed @@total_of_cars from CarBuilder, and put it on *each* child class (there was one row of code, now there is two - or more, if more children), and could be a problem if I miss the point on some child class and forget to declare that variable there). - On the CarBuilder, I create an empty method there called "increase" just to call it on the "build" method (that I want the children inherit it's funcionality). Two more rows there. - I also removed the total_of_cars method from CarBuilder, but needed to write it on each children. 3 rows less on the parent, but 3 more on each child. - Also on the children I needed to write the increase method, 3 more rows on each child. Sorry if I'm missing some point here, because I'm a Ruby newbie, but is that correct? I mean, seems that we need to write more code with this kind of behaviour. And if we forget to implement some of the needed methods or the @@total_of_cars on each CarBuilder child (CarBuilder could have a lot of other methods that I could want to inherit also!), it could not work normally. On another point, if all this methods and variables could be inherited from the parent class, will be no problem. I don't really know if there is a strong and well-defined OOP concept on the fact that a child cannot overwrite it's parent class variables, but could you - Tell me if there is some kind of OOP concept like that and - Tell me if the way I made the code, even with more lines, is the correct and more efficient way to control how many cars each CarBuilder child made? Thanks for your attention. :-) ---------------------------- Eust�quio "TaQ" Rangel eustaquiorangel@yahoo.com http://beam.to/taq Usu�rio GNU/Linux no. 224050