你建立了一個銀行帳戶類別:
# encoding: Big5
class Account
def initialize(id, name)
@id = id
@name = name
@balance = 0
end
def deposit(amt)
@balance += amt
end
def withdraw(amt)
if amt >= @balance
@balance -= amt
else
raise RuntimeError, "餘額不足"
end
end
def to_s
"
id\t\t#{@id}
name\t\t#{@name}
balance\t\t#{@balance}
"
end
end
在這個類別中,雖然沒有聲明,但你已經使用了繼承,在Ruby中,所有類別都繼承自Object類別。上例其實相當於:
class Account < Object
...
...
在Ruby中繼承的語法,是在類別名稱旁使用 < 表明要繼承的父類別。例如,你為以上的類別建立了一個支票帳戶:
...
class CheckingAccount < Account
def initialize(id, name)
super(id, name) # 呼叫父類別 initialize 方法
@overdraftlimit = 30000
end
def withdraw(amt)
if amt <= @balance + @overdraftlimit
@balance -= amt
else
raise RuntimeError, "超出信用額度"
end
end
def to_s
super + # 呼叫父類別 to_s 方法
"Over limit\t#{@overdraftlimit}
"
end
end
在上例中,你繼承了Account來定義一個CheckingAccount子類別。如果在子類別中,需要呼叫父類別的方法,可以使用super方法。如果在子類別,沒有定義初始方法,預設就會呼叫父類別初始方法,所有傳給子類別new的引數,都會傳給父類別初始方法。
在上例中,你重新定義了withdraw與to_s方法,在重新定義實例方法時,如果想要呼叫父類別中某個實例方法,也是使用super。在操作實例方法時,是從子類別開始尋找是否有定義,否則就搜尋父類別中是否有定義方法。所以:
acct = CheckingAccount.new("E1234", "Justin Lin")
puts acct # 使用 CheckingAccount 的 to_s 定義
acct.deposit(1000) # 使用 Account 的 deposit 定義
puts acct
acct.withdraw(2000) # 使用 CheckingAccount 的 withdraw 定義
puts acct
puts acct # 使用 CheckingAccount 的 to_s 定義
acct.deposit(1000) # 使用 Account 的 deposit 定義
puts acct
acct.withdraw(2000) # 使用 CheckingAccount 的 withdraw 定義
puts acct
在Ruby中,只能進行單一繼承,也就是一個子類別只能有一個父類別,Ruby中所有類別都是Object的直接或間接子類別。
類別方法屬於類別擁有,基本上沒有繼承問題,不過在子類別中若定義了與父類別同名的類別方法,而又要使用父類別中的類別方法,可以如下:
>> class Some
>> def self.some
>> puts "some"
>> end
>> end
=> nil
>> class Other < Some
>> def self.some
>> Some.some
>> puts "other"
>> end
>> end
=> nil
>> class Another < Some
>> def self.some
>> super
>> puts "another"
>> end
>> end
=> nil
>> Some.some
some
=> nil
>> Other.some
some
other
=> nil
>> Another.some
some
another
=> nil
>>
>> def self.some
>> puts "some"
>> end
>> end
=> nil
>> class Other < Some
>> def self.some
>> Some.some
>> puts "other"
>> end
>> end
=> nil
>> class Another < Some
>> def self.some
>> super
>> puts "another"
>> end
>> end
=> nil
>> Some.some
some
=> nil
>> Other.some
some
other
=> nil
>> Another.some
some
another
=> nil
>>
在Ruby中,類別有個superclass方法,可取得繼承的父類別:
>> Other.superclass
=> Some
>> Other.superclass.superclass
=> Object
>>
=> Some
>> Other.superclass.superclass
=> Object
>>
父類別中的實例變數可以直接被子類別取用,private方法在子類別中也可以不透過self直接呼叫,也可以使用super呼叫,但子類別不可透過self呼叫private方法,在子類別中可透過self呼叫的父類別方法,必須是protected或public。