Reputation: 935
I have searched on here for an answer to this question and couldn't find what I was after (in exact terms) so I'm gonna be slightly greedy and ask for some of the communities time. I hope to make my question as applicable as possible.
So, some context, I've been struggling with the idea of classes, class variables and methods for the last week but over the last 2 days have made serious headways in my understanding. However now I am faced with inheritance and can't work out why super would be used when I can just inherit without using it.
For example:
class Animal
def initialize (type, breed, age)
@type = type
@breed = breed
@age = age
end
end
class Dog < Animal
end
class Cat < Animal
end
class Fish
end
woof = Dog.new("dog", "shitzu", 12)
meow = Cat.new("cat", "tabby", 5)
fish = Fish.new("fish", "gold", 2)
Output:
=> #<Dog:0x00000001447680 @type="dog", @breed="shitzu", @age=12>
=> #<Cat:0x0000000140c918 @type="cat", @breed="tabby", @age=5>
ArgumentError: wrong number of arguments (given 3, expected 0)
As you can see, I have been able to inherit from Animal on both my Dog and Cat classes, which I marked for inheritance, but on my Fish I have not been able to, because I didn't inherit.
If someone could explain why we use super, and point out flaws in my understanding, I'd be very grateful, I understand that I may be completely just misunderstanding usage here, but I'd like to just get it clarified. Thanks for your time, appreciate the help.
Upvotes: 1
Views: 1098
Reputation: 9586
Excerpted from Inheritance - What is inherited?. The original author was nus. Attribution details can be found on the contributor page. The source is licenced under CC BY-SA 3.0 and may be found in the Documentation archive. Reference topic ID: 625 and example ID: 14883.
Methods are inherited
class A
def boo; p 'boo' end
end
class B < A; end
b = B.new
b.boo # => 'boo'
Class methods are inherited
class A
def self.boo; p 'boo' end
end
class B < A; end
p B.boo # => 'boo'
Constants are inherited
class A
WOO = 1
end
class B < A; end
p B::WOO # => 1
But beware, they can be overridden:
class B
WOO = WOO + 1
end
p B::WOO # => 2
Instance variables are inherited:
class A
attr_accessor :ho
def initialize
@ho = 'haha'
end
end
class B < A; end
b = B.new
p b.ho # => 'haha'
Beware, if you override the methods that initialize instance variables without calling super
, they will be nil. Continuing from above:
class C < A
def initialize; end
end
c = C.new
p c.ho # => nil
Class instance variables are not inherited:
class A
@foo = 'foo'
class << self
attr_accessor :foo
end
end
class B < A; end
p B.foo # => nil
# The accessor is inherited, since it is a class method
#
B.foo = 'fob' # possible
Class variables aren't really inherited
They are shared between the base class and all subclasses as 1 variable:
class A
@@foo = 0
def initialize
@@foo += 1
p @@foo
end
end
class B < A;end
a = A.new # => 1
b = B.new # => 2
So continuing from above:
class C < A
def initialize
@@foo = -10
p @@foo
end
end
a = C.new # => -10
b = B.new # => -9
Upvotes: 0
Reputation: 2293
Using super
lets a class override a method that it inherits from its parent and customize it.
For instance, in your example, Dog
and Cat
inherit #initialize
from Animal
- but what if we wanted some special logic for Dog
?
class Dog < Animal
def initialize(type, breed, age)
raise "Sorry, dogs don't live that long!" if age > 100
# Everything looks good - let Animal#initialize run now
super
end
end
This lets Dog
customize what its initialize method does, but still call through to the original inherited method.
Upvotes: 4