Ruby - initialize inheritance, super with only certain arguments?
You can avoid setting a default value to your occupation
parameter in Person Class
by simply passing the nil
argument for occupation
in super()
. This allows
you to call Viking.new
with your 3 arguments (name, age, weapon)
without
having to take extra consideration for occupation
.
class Person
def initialize(name, age, occupation)
@name = name
@age = age
@occupation = occupation
end
end
class Viking < Person
def initialize(name, age, weapon)
super(name, age, nil)
@weapon = weapon
end
end
eric = Viking.new("Eric", 24, 'broadsword')
p eric
output Viking:0x00007f8e0a119f78 @name="Eric", @age=24, @occupation=nil, @weapon="broadsword"
How super handles arguments
Regarding argument handling, the super keyword can behave in three ways:
When called with no arguments, super automatically passes any arguments received by the method from which it's called (at the subclass) to the corresponding method in the superclass.
class A
def some_method(*args)
puts "Received arguments: #{args}"
end
end
class B < A
def some_method(*args)
super
end
end
b = B.new
b.some_method("foo", "bar") # Output: Received arguments: ["foo", "bar"]
If called with empty parentheses (empty argument list), no arguments are passed to the corresponding method in the superclass, regardless of whether the method from which super was called (on the subclass) has received any arguments.
class A
def some_method(*args)
puts "Received arguments: #{args}"
end
end
class B < A
def some_method(*args)
super() # Notice the empty parentheses here
end
end
b = B.new
b.some_method("foo", "bar") # Output: Received arguments: [ ]
When called with an explicit argument list, it sends those arguments to the corresponding method in the superclass, regardless of whether the method from which super was called (on the subclass) has received any arguments.
class A
def some_method(*args)
puts "Received arguments: #{args}"
end
end
class B < A
def some_method(*args)
super("baz", "qux") # Notice that specific arguments were passed here
end
end
b = B.new
b.some_method("foo", "bar") # Output: Received arguments: ["baz", "qux"]
Really this is just 2 ways - auto include all attributes (just the word super) and super where you pick which arguments get passed up. Doing super() is picking no arguments to hand to the parent class.
Edit: This was meant as a comment on the above comment but they don't allow comments when someone is new... oh well.
Yes, you are committing a Cardinal Sin (obviously, you are aware of it, since you are asking about it). :)
You are breaking Liskov substitution principle (and probably some other named or unnamed rules).
You should probably extract another class as a common superclass, which does not contain occupation
. That will make everything much clearer and cleaner.