2011-08-25 114 views
0

假設我有3個類:C#繼承問題

GrandDad,爸爸和兒子。兒子從父親繼承,繼承自GrandDad。

爺爺有2種方法:

public virtual void foo(); 
public virtual void do(); 

爸爸繼承FOO(),但覆蓋做();

public override void do(); 

如果兒子想修改FOO(),是可以接受的:

讓爸爸覆蓋FOO(),但只需調用foo.base()?然後兒子可以覆蓋foo(),但爸爸的foo()功能保持不變?

或者這是一個黑客的方式?

+0

在一個側面說明,繼承不是一個好的模型,這種關係,作爲一個兒子並不總是一種爸爸和爸爸並不總是一種GrandDad。這些概念比'是'關係更具有「所有權」關係,並且可以通過類之間或整個FamilyTree中的引用進行組合更好地建模。人類繼承與類繼承並不相似。 –

回答

3

只要Dad從未定義一個foo(),沒有理由他做任何事情。 Son應該能夠從GrandDad覆蓋foo()

2

Dad不必覆蓋foo()。由於Dad只是繼承Granddad(仍然爲virtual)提供的版本,這意味着這也是Son獲得的版本,允許Son覆蓋foo()

public class Granddad { 
    public virtual void foo() {...} 
    public virtual void do() {...} 
} 

public class Dad { 
    public override void do() {...} 
} 

public class Son { 
    public override void foo() {...} 
} 
+0

這是什麼意思「它需要聲明覆蓋和虛擬?」 –

+1

@Kevin:我的這一部分實際上是不正確的,一旦在基類中聲明瞭'virtual',它就會在所有派生類中被覆蓋。如果您嘗試聲明兩者,則會出錯。 –

0

你是什麼意思修改foo?如果你的意思是覆蓋,那麼Son可以簡單地覆蓋foo()。無需讓爸爸覆蓋foo()呼叫基地實施。

2

如果我理解了你的問題,就沒有必要對爸爸做任何事情。只需在Son中實現foo()。因爲兒子是爸爸的後裔,兒子內部沒有任何東西改變爸爸,所以如果兒子執行foo(),爸爸的foo()保持不變,繼承自GrandDad。

0

父親不需要重寫Foo for Son以覆蓋Foo。 Foo在繼承鏈中一直是虛擬的,除非有人超越它並聲明它是封閉的。

1

問題的語義可能導致你誤入歧途。

如果你真的做父親,兒子,祖父...

你只需要一個類:人。它將有一個名爲Father的成員屬性,指向另一個Person。這樣,你可以有很多代,而不是被鎖在三個。