2016-09-25 29 views
1

好的,所以我在這裏搜索了一個關於這個問題的答案,並且找不到我以後的(確切的說),所以我會稍微貪婪並要求一些社區時間。我希望儘可能提出我的問題。因此,在上下文中,我一直在努力應對上週的類,類變量和方法的想法,但在過去的兩天裏,我的理解已經取得了重大進展。但是現在我面臨着繼承問題,無法解決爲什麼只有在不使用超級繼承的情況下才能使用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) 

正如你所看到的,我已經能夠從動物繼承在我的兩個狗和貓類,這標誌着我繼承,但在我的魚我一直沒能到,因爲我沒有繼承。

如果有人可以解釋爲什麼我們使用超級,並指出我的理解缺陷,我會非常感激,我明白,我可能完全誤解了這裏的用法,但我想澄清它。感謝您的時間,感謝您的幫助。

ty。

+0

你想知道顯式調用'super'? (比如,當一個方法調用'super'來運行它的父類的方法版本時)? – gmcnaughton

+2

如果你想自定義'Dog'類的'initialize'方法,只需繼承'Animal'類就不會讓你自定義它。如果在'Dog'類中,你做了類似'def初始化(類型,品種,年齡,顏色)',然後有'super(type,breed,age)'和'@color = color',這將允許你改變你繼承的initialize方法,而'super'調用它的父類'Animal'來初始化你有的其他實例變量 –

+0

你是否在示例中使用'super'?我不明白這個問題是如何與代碼示例相關的。 –

回答

4

使用super可以讓一個類覆蓋它從父類繼承並定製它的方法。

例如,在你的榜樣,DogCat繼承#initializeAnimal - 但如果我們想要一些特殊的邏輯Dog

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定製它的初始化方法做什麼,但仍然可以通過撥打原來的繼承的方法。

+0

是的。總而言之,你的子類的方法「幾乎但不完全」就像他們的父類一樣。 – tadman

+0

所以我們基本上使用super來增加額外的功能,同時繼承現有的父功能? –

+0

_「使用super可以讓一個類重載它從其父類繼承的方法」_具有誤導性。一個類可以通過簡單地定義它而不用'super'來覆蓋在它的Parent類中定義的方法。 'super'從父類調用原始方法。 –

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 
相關問題