2010-05-28 44 views
3

編程時,我們通常使用一些類型鑄造操作。有關OOP中「鑄造操作」的問題

當鑄件發生在「同一層」的物體上時,感覺沒問題。但是當它出現在「不同層次」的主體(主要是父子之間)時,感覺很奇怪。

考慮到這一點:

Class Son extends Father 

Son s = (Son)father;,這是絕對不合理的。因爲「兒子」不再是「父親」了,「兒子」可能會伴隨着「父親」所沒有的一些新屬性而長大,鑄造操作使得這些屬性不爲人知。

在另一方面,Father f = (Father)son似乎是合理的,但根據LSP

「衍生的一個實例應該能夠取代它的超類的任何實例」

A「兒子」可以做他的「父親」所能做的任何事情,所以鑄造操作似乎毫無用處。

所以我可以說這些鑄造操作是惡性的OO設計原則,但必要的?

回答

2

在OOP中投射對象通常是類繼承或接口繼承的產物。人們必須始終記得,類繼承表示「是」關係,並且接口繼承表示「有」關係。

讓我們繼續看你的例子:Class Son extends Father聽起來不像一個合理的抽象,因爲每個男性是兒子,但並不是所有的男性都是父親。事實上,相反可能更適用:Class Father extends Son,因爲每個父親總是人的兒子。另一方面,我們可以忽略整個抽象,並說我們有一個Class Person,可以是男性或女性,也可以是母親或父親,等等。每個人將有一個屬性,其中包含Person的集合,其名稱爲Children

在這個抽象中,如果Person的性別是男性,並且Person.Children.Count > 0只被認爲是Father。這比單獨定義一個Father類要簡單得多。

+0

我想我們有同樣的想法:)我只是忘了性別,愚蠢的性別:P – 2010-05-28 05:30:01

2

我找到像這總是很有趣的問題,它本身借給某種辯論,我認爲:)

這裏是我的想法。 在一流的設計我想在這種情況下,創建一個類人

class Person 
{ 
    public bool IsFather { get; set; } // this variable will change depending on the count of children 
    public List<Person> children { get; set; } 
} 

當我創建一個派生類,類應該是一個專業的人,在父親和兒子的情況下,我不會創建父親班和兒子班。

0

這對我來說似乎不合理。什麼似乎更合理:

Son s = (Son)person   //Valid 
Father f = (Father)person //Valid 
1

你有一個不好的例子繼承。

一個更好的可以是

Class Person 
{ 
    public void walk(); 
} 
Class Man extends Person 
{ 
    public void shaveBeard(); 
} 

繼承是表示一個關係的方式;例如「a ManPerson」。

使用這些線路的對象

要麼是OK。

Person p = new Person(); 
Person m = new Man(); 

這是罰款,呼籲兩國p.walk。但是要調用shavebeard()方法,m必須是Man對象。由於類型安全的原因,您必須將其投射到一個Man對象;例如(Man) m.shaveBeard();演員在這裏會失敗,所以最好檢查變量是指Man一個實例:

if(m instanceof Man) 
{ 
    (Man) m.shaveBeard(); 
} 
0

這裏有一個提示:在左側的類是超類,並且在右側子類,所以如果我們有這個: 對象p = new Student(); //是正確的 學生s = new Object()//是錯誤的......這就像說每個對象都是學生.. 在進行顯式轉換時必須小心謹慎,因爲它可能看起來是正確的,但可能無法按預期工作。你不能將你父親的私人財產實例化給你自己。