2014-03-24 54 views
1

有什麼區別這關於從繼承的類實例化一個類

DerivedClass classinst = new DerivedClass(); 

BaseClass classinst = new DerivedClass(); 

我似乎無法看到任何差別和編譯器不抱怨,所以我可以用互換?

+0

DrivedClass從基類繼承? – user3401335

+2

這是密切相關[亞型多態性101(http://en.wikipedia.org/wiki/Subtyping)... –

回答

2

兩者之間唯一的區別是,如果你做

DerivedClass classinst = new DerivedClass();

編譯器解釋classinst作爲DerivedClass,並允許您使用所有的具體方法/屬性/等你聲明在派生類中,而不在基類中。

在另一方面,如果你這樣做 BaseClass classinst = new DerivedClass();

編譯器將解釋classinst作爲BaseClass,您將無法訪問這些成員。

不要意識到對象的實際不會改變。無論您使用兩個聲明中的哪一個,對該對象的引用都保持不變。唯一改變的是如何參考解釋,因此什麼成員可用;那些基類或派生類。

0

那麼,在第二個版本中,您將無法使用您的實例訪問特定於Derived類的屬性/方法(不會轉換爲派生類型)。

想象

public class Animal { 
    public int NbOfEyes {get;set;} 
} 

public class Dog : Animal { 
    public bool IsPolite {get;set;} 
} 

Animal dog = new Dog(); 

dog.IsPolite = false; //you can't do that. dog is an animal, it doesn't know it can be polite. 
dog.NbOfEyes = 2;//you can do that, you have access to animal's properties /methods 

Dog dog2 = new Dog(); 
dog2.IsPolite = false; // you can do that. 
dog2.NbOfEyes = 4; //you can also do that, you have access to base class's properties/methods. 
+0

並非完全如此,你仍然可以施展它,因爲它被實例化的狗:'(如狗Dog).IsPolite = false;'會工作得很好。看來OP對多態對象的理解很少。 – Dan

+0

@Dan當然,但這是另一個演員。 –

+0

你**將有**訪問這些成員!編譯器不會將它解釋爲衍生物! – aevitas

0

使用:

BaseClass classinst = new DrivedClass(); 

你讓yourselft也做:

BaseClass classinst = new DrivedClassOne(); 
BaseClass classinst = new DrivedClassTwo(); 

可以在這裏可以說你有一個道路的情況下,是很好對象,其中包含汽車列表。然後,您可以添加一輛新的福特或一輛新的本田,因爲它是汽車類型,而不是僅僅是分區或本田

0

區別在於「classinst」變量的類型。

試試下面的代碼:

string typename = typeof(classinst).ToString(); 
+1

謝謝,這是很好的提示! – paulnara

+0

@paulnara如果您發現我的答案有幫助,歡迎隨時致詞,但無論哪種方式,我建議您閱讀C#中的多態性(請參閱Patryk的評論)。 – Dan

+1

對不起丹,需要15分才能投票。我還沒有。 – paulnara

1

在您需要的方法或DrivedClass性能沒有訪問,因爲您的變量定義爲BaseClass第二個例子。即使DrivedClass的實例在幕後,您也將無法訪問特定於該類型的成員。

0

如果你想使用多態行爲 - 即有一個基類中定義的方法,其行爲有所不同,取決於它在派生類中的重寫方式,但不需要派生類的知識,則將其指定爲基類類。這是典型的面向對象的行爲 - 如果你爲此目的使用子類,它們幾乎總是被稱爲基類(或者更典型的是,這些日子是多個相關類實現的接口)。

0

的面向對象編程中最重要的原則2 繼承多態性

繼承允許創建一個類從現有的類繼承數據和行爲。然後,子類可以專門化(通常通過重寫)超類的行爲。

多態性允許子類的行爲就好像它是超類,所以在你的情況下,DerivedClass的實例可以用於需要實例BaseClass的任何地方。

因此,DerivedClass的一個實例可以分配給BaseClass(感謝多態性)類型的變量。但是,即使分配到BaseClass類型的變量,它會像的DerivedClass一個實例,因此任何被覆蓋的行爲將被自動使用。

實施例:

class BaseClass 
{ 
    public virtual void ShowMe() 
    { 
     Console.WriteLine("I'm the base class"); 
    } 
} 

class DerivedClass : BaseClass 
{ 
    public override void ShowMe() 
    { 
     Console.WriteLine("I'm the derived class"); 
    } 
} 

// This will print "I'm the base class" 
BaseClass baseClass = new BaseClass(); 
baseClass.ShowMe(); 

// This will print "I'm the derived class" 
DerivedClass derivedClass = new DerivedClass(); 
derivedClass.ShowMe(); 

// This will print "I'm the derived class" 
// Reason: even if assigned to a BaseClass variable, 
// it's still a DerivedClass instance 
BaseClass baseClass2 = new DerivedClass(); 
baseClass2.ShowMe(); 

// This will generate a compiler error 
// Subclasses can behave like superclasses, 
// but the opposite is not possible 
DerivedClass derivedClass2 = new BaseClass();