为什么我们在没有使用它的情况下继承时会使用super in ruby​​?

时间:2016-09-25 23:16:36

标签: ruby class inheritance initialization super

好的,所以我在这里搜索了这个问题的答案,并且无法找到我追求的东西(确切地说),所以我会稍微贪婪并要求一些社区时间。我希望尽可能地提出我的问题。

所以,在某些情况下,我上周一直在努力学习班级,班级变量和方法,但在过去的两天里,我的理解已经取得了重大进展。然而,现在我面临着继承,并且无法解决为什么在不使用它的情况下继承而使用super的原因。

例如:

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)

正如你所看到的,我已经能够从我的Dog和Cat类继承Animal,我标记为继承,但在我的Fish上我无法继承,因为我没有继承。

如果有人能解释我们为什么使用超级,并指出我理解中的缺陷,我会非常感激,我明白我可能完全误解了这里的用法,但我想要弄清楚。感谢您的时间,感谢您的帮助。

TY。

2 个答案:

答案 0 :(得分:4)

使用super允许类重写从其父级继承的方法并对其进行自定义。

例如,在您的示例中,DogCat#initialize继承Animal - 但如果我们想要Dog的某些特殊逻辑怎么办? / p>

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

这允许Dog自定义其初始化方法的功能,但仍会调用原始的继承方法。

答案 1 :(得分:0)

  

摘自Inheritance - What is inherited?。原作者是nus。归因详情可在contributor page上找到。该来源在CC BY-SA 3.0下获得许可,可以在Documentation archive中找到。参考主题ID:625和示例ID:14883。

继承方法

class A
  def boo; p 'boo' end
end

class B < A; end

b = B.new
b.boo # => 'boo'

继承类方法

class A
  def self.boo; p 'boo' end
end

class B < A; end

p B.boo # => 'boo'

继承常量

class A
  WOO = 1
end

class B < A; end

p B::WOO # => 1

但要注意,他们可以被覆盖:

class B
  WOO = WOO + 1
end

p B::WOO # => 2

继承实例变量:

class A
  attr_accessor :ho
  def initialize
    @ho = 'haha'
  end
end

class B < A; end

b = B.new
p b.ho # => 'haha'

请注意,如果覆盖初始化实例变量而不调用super的方法,则它们将为零。从上面继续:

class C < A
  def initialize; end
 end

c = C.new
p c.ho    # => nil

不继承类实例变量:

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

类变量并未真正继承

它们在基类和所有子类之间共享为1个变量:

class A
    @@foo = 0
    def initialize
        @@foo  += 1 
        p @@foo
    end
end

class B < A;end

a = A.new # => 1
b = B.new # => 2

从上面继续:

class C < A
  def initialize
    @@foo = -10
    p @@foo
  end
end

a = C.new # => -10
b = B.new # => -9