Reputation: 69
I'd appreciate knowing why the instance of "Cat"
below isn't also putting the "This animal can:"
text before its specific instance attributes. I'm expecting an output like this:
This animal can:
Say it's name: 'Rover'
Bark
This animal can:
Say its name: 'Satan'
Meow
Here's the code:
class Animal
puts "This animal can:"
end
class Dog < Animal
def initialize(name)
@name = name
puts "Say its @name: '%s'" % [name]
end
def bark
puts "Bark"
end
end
class Cat < Animal
def initialize(name)
@name = name
puts "Say its @name: '%s'" % [name]
end
def meow
puts "Meow"
end
end
rover = Dog.new("Rover").bark
satan = Cat.new("Satan").meow
What I'm seeing is this:
This animal can:
Say it's name: 'Rover'
Bark
Say its name: 'Satan'
Meow
Doesn't "cat"
also inherit from the Animal
class? Shouldn't its output also begin with "This animal can:"
?
Upvotes: 0
Views: 202
Reputation: 12578
Install name_magic
(gem install y_support
) and have fun
require 'y_support/name_magic';
class Animal
include NameMagic
def initialize; puts "This animal #{sound}s." end
def sound; "growl" end
def speak; puts "#{sound.capitalize}!" end
end
class Dog < Animal
def sound; "bark" end
end
class Cat < Animal
def sound; "meow" end
end
def hullo( animal )
Animal.instance( animal ).speak
end
Rover = Dog.new
#=> This animal barks.
Satan = Cat.new
#=> This animal meows.
hullo :Rover
#=> Bark!
Animal.instances.each( &:speak )
#=> Bark!
#=> Meow!
Upvotes: -1
Reputation: 4264
Exactly!
class Animal
def initialize(name)
puts "This animal can:"
end
end
def initialize(name)
@name = name
puts "Say its @name: '%s'" % [name]
super # initializer from parent class
end
why that don't work ?
class Animal
puts "This animal can:"
end
when ruby parser read code it evaluate everything on way. I mean even if you will not create any object it will display "This animal can:" That's why you saw that for the first time and had impression that Dog class worked correctly
Upvotes: 0
Reputation: 7361
The "This Animal can:" line only occurs when the class is defined, since it doesn't live in a method. Since both animals have common behavior in their initializers, you might want to promote the initializer to the Animal class.
class Animal
def introduce_myself
puts "Hello! My name is #{@name} and I know how to: "
end
def initialize(name)
@name = name
introduce_myself
end
end
class Dog < Animal
def bark
puts "Woof!"
end
end
class Cat < Animal
def meow
puts "Meow!"
end
end
Dog.new("Fido").bark
Cat.new("Sparky").meow
Output:
Hello! My name is Fido and I know how to:
Woof!
Hello! My name is Sparky and I know how to:
Meow!
Upvotes: 2
Reputation: 16638
Your Animal class doesn't define a constructor, nor is it called by inheritors:
class Animal
def initialize
puts "This animal can:"
end
end
class Dog < Animal
def initialize(name)
super()
@name = name
puts "Say its @name: '%s'" % [name]
end
def bark
puts "Bark"
end
end
Upvotes: 1
Reputation: 78523
The problem in your code is that:
puts "This animal can:"
is run when the Animal class gets defined. It seems like you want this in the initializer:
class Animal
def initialize(name)
puts "This animal can:"
end
end
You'll then need to call super
in the other initializers for the result you're expecting.
Upvotes: 5