[英]in c# oop how to explain why a base class can take a derived class instance
如果Y繼承X,則Y是X 的一種,可以在X可以使用的任何地方使用。
無論X是否為抽象,這都將起作用。
Y類要么繼承X類,要么X是Y繼承的接口。
但是如果有人問我在工作面試中,我會告訴他們我不想在開發人員使用單個字符名稱創建類型的任何地方工作。
為了擴展BrankoDimitrijević的答案,這可能是由於Liskov替代原理 。
在您的評論中,您說
基類和派生類可以具有各自不同的方法/屬性/字段定義。 因此,從邏輯上講,該語句不應該編譯...但是可以編譯...我不知道其背后的原理
的確,基類和派生類具有自己的成員定義,但它們並不完全不同。 具體來說, 基類的每個成員也是派生類的成員。 例如,您總是可以說
object o = anything;
Console.WriteLine(o.ToString());
Console.WriteLine(o.GetHashCode());
Console.WriteLine(o.GetType().Name);
您可以執行此操作,因為每個對象都具有ToString,GetHashCode和GetType方法 ,因為每個對象的運行時類型直接或間接地從對象繼承。
您可以對object以外的基類執行相同的操作:
class X
{
public string Exclamation { get { return "Inherit this!"; } }
}
class Y : X
{
public string Question { get { return "What's up with that?"; } }
}
那是完全合法的說法
X x = new Y();
Console.WriteLine(x.Exclamation);
但是你當然不能說
X x = new Y();
Console.WriteLine(x.Question); //does not compile!
為了使用Question屬性,您需要具有類型Y的引用。
回顧一下:由於基類的每個成員也是派生類的成員,因此可以將派生類的實例當作基類的實例一樣使用。 派生的類實例具有基類的所有成員。
您提出了抽象類的主題。 當然,不能實例化抽象類。 您只能實例化從抽象類派生的類。 這並不影響替換原則,但是,不同之處為暗示一個變量,其類型是一個抽象類必須引用派生類型的一個實例,而一個變量,其類型是一個非抽象(未密封)類可以指派生類型的實例。
讓我們假設
class Animal
{
}
class Tiger:Animal
{
}
Animal fooAnimal = new Tiger()
這是可能的,因為Tiger
是Animal
。
C#支持所謂的協方差和逆方差。 協方差是隱式地(無需任何額外代碼)將派生類(在這種情況下為Y)轉換為基類(在這種情況下為X)的能力。這是可能的,因為Y擴展了X,這意味着Y具有與X相同的所有成員。這允許將類型X的變量分配給派生類。
這對於擴展類和重載很重要。 如果類X包含一個名為Foo的方法,而派生類X創建一個名為Foo的方法,則即使將Y的方法強制轉換為類型X,也將對其進行調用。這是一個示例:
public class X
{
public void Foo()
{
Console.WriteLine("Something");
}
}
public class Y : X // y derives from X
{
public override void Foo()
{
Console.WriteLine("Class Y");
}
}
public class Program
{
static void Main()
{
X item = new Y(); // covariance.
item.Foo(); // prints "Class Y"
}
}
我希望這不是隨便的,我不知道您的技能水平。 來自MSDN的這篇文章對其進行了解釋, 網址為http://msdn.microsoft.com/zh-cn/library/ee207183.aspx 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.