-
Notifications
You must be signed in to change notification settings - Fork 4
Koans AboutInheritance
class AboutInheritance < Neo::Koan
class Dog
attr_reader :name
def initialize(name)
@name = name
end
def bark
"WOOF"
end
end
class Chihuahua < Dog
def wag
:happy
end
def bark
"yip"
end
end
A class Dog was defined and a class Chihuahua was defined and declared to inherit from Dog. It will inherit all of the methods that Dog has.
def test_subclasses_have_the_parent_as_an_ancestor
assert_equal true, Chihuahua.ancestors.include?(Dog)
end
def test_all_classes_ultimately_inherit_from_object
assert_equal true, Chihuahua.ancestors.include?(Object)
end
Chihuahua has ancestors of Dog and Object
def test_subclasses_inherit_behavior_from_parent_class
chico = Chihuahua.new("Chico")
assert_equal "Chico", chico.name
end
We didn't initialize name in Chihuahua we didn't make it an attr_reader
yet it when we call Chihuahua.new
we pass it a name and that name is initialized. It is getting this behavior from the parent class - Dog.
def test_subclasses_add_new_behavior
chico = Chihuahua.new("Chico")
assert_equal :happy, chico.wag
assert_raise(NoMethodError) do
fido = Dog.new("Fido")
fido.wag
end
end
We created the wag method in the Chihuahua class. So Dog class doesn't know what it is. wag is a valid method call on Chihuahua and not on Dog. Child class has all the ancestor methods but the ancestor does not have the child methods.
def test_subclasses_can_modify_existing_behavior
chico = Chihuahua.new("Chico")
assert_equal "yip", chico.bark
fido = Dog.new("Fido")
assert_equal "WOOF", fido.bark
end
We can overwrite the method that the subclass inherited from the ancestor by creating a method of the same name. Chihuahua inherited the method bark
from Dog so chico.bark
would return ''' "WOOF" just like
fido.bark ``` except that we defined a bark method in the Chihuahua class to return "yip" so this overrides what it inherited.
class BullDog < Dog
def bark
super + ", GROWL"
end
end
def test_subclasses_can_invoke_parent_behavior_via_super
ralph = BullDog.new("Ralph")
assert_equal "WOOF, GROWL", ralph.bark
end
Super will grab what the ancestor class returns so we can add to it instead of overriding the whole thing.
class GreatDane < Dog
def growl
super.bark + ", GROWL"
end
end
def test_super_does_not_work_cross_method
george = GreatDane.new("George")
assert_raise(NoMethodError) do
george.growl
end
end
end
You can not call super on a different method and pull it in. If you're calling super, the method of the parent class needs to have the same name. Here we throw an error because we are trying to call super.bark in the growl method.