blob blob - 6 months ago 17
Ruby Question

Ruby - initialize inheritance, super with only certain arguments?

I've been playing around with Ruby as of late and I can't seem to find the answer to my question.

I have a class and a subclass. Class has some

initialize
method, and subclass has it's own
initialize
method that is supposed to inherit some (but not all) variables from it and additionally add it's own variables to the subclass objects.

My
Person
has
@name
,
@age
and
@occupation
.

My
Viking
is supposed to have a
@name
and
@age
which it inherits from
Person
, and additionally a
@weapon
which
Person
doesn't have. A
Viking
obviously doesn't need any
@occupation
, and shouldn't have one.

# doesn't work
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) # this seems to cause error
@weapon = weapon
end
end

eric = Viking.new("Eric", 24, 'broadsword')
# ArgError: wrong number of arguments (2 for 3)


You can make it work in the following ways, but neither solution appeals to me

class Person
def initialize(name, age, occupation = 'bug hunter')
@name = name
@age = age
@occupation = occupation
end
end

class Viking < Person
def initialize(name, age, weapon)
super(name, age)
@weapon = weapon
end
end

eric = Viking.new("Eric", 24, 'broadsword')
# Eric now has an additional @occupation var from superclass initialize


class Person
def initialize(name, age, occupation)
@name = name
@age = age
@occupation = occupation
end
end

class Viking < Person
def initialize(name, age, occupation, weapon)
super(name, age, occupation)
@weapon = weapon
end
end

eric = Viking.new("Eric", 24, 'pillager', 'broadsword')
# eric is now a pillager, but I don't want a Viking to have any @occupation


The question is either

1) is it by design and I want to commit some Cardinal Sin against OOP principles?

2) how do I get it to work the way I want to (preferably without any crazy complicated metaprogramming techniques etc)?

Answer

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.

Comments