簡體   English   中英

實例化其他類型的類型

[英]Instantiate a Type of a different type

出於好奇,我總是看到代碼,有人可以實例化窗簾類型的對象,然后將其分配給其他類型。 我的問題是,您為什么要這樣做?我們將要完成什么工作,例如:

SampleClassA sampleclassA = new SambleClassB();

此代碼是什么意思,他試圖投射還是什么。 提前致謝。

在幾種情況下,我們希望引用具有超類型變量的子類類型。

就您而言:

SampleClassA sampleclassA = new SambleClassB(); 

將使您能夠靈活地使變量sampleclassA引用任何從SampleClassA派生的類型。 那就是說,只有當您有許多衍生自SampleClassA類型並且想要執行以下提到的操作之一時,才想執行此操作。 如果只有SampleClassA一個子類型,那么您寧願做SambleClassB sampleclassA = new SambleClassB();


有時我們也可以將超類型用作方法參數,方法返回類型或對象集合的類型。

這個:

  • 使我們能夠創建一個方法參數,該參數可以接受從超類型派生的任何類型的輸入,您可以將其視為實際的多態。
  • 同樣,我們可以將超類型用作方法返回類型,這將再次使我們能夠返回從超類型派生的任何類型。
  • 使我們能夠存儲所有從特定類型派生的對象集合,並對集合中的所有對象執行一些通用邏輯。

請注意,只有在SampleClassBSampleClassA “兼容”時,您才能執行此操作。 可能是前者繼承了后者,或者前者實現了后者,或者前者可以隱式轉換為后者。

在這個答案中,我將只討論前兩種情況(繼承和接口實現)的有用性,因為我認為最后一種情況(隱式轉換)的有用性很明顯。

假設您有以下4種類型:

interface IPet {
    ...
}

class Dog : IPet {
    ...
}

class Cat : IPet {
    ...
}

class Person {
    public IPet Pet { get; set; }
}

如您所見,每個Person對象都可以養寵物。 Pet屬性聲明為IPet 使用此Person類時,將遇到為IPet屬性分配DogCat對象的IPet

Person me = new Person();
me.Pet = new Dog();

那么,將Pet聲明為IPet的目的是什么? 您說:“為什么不將其聲明為Dog ?上面的代碼仍然可以使用。” 好吧,如果您這樣做了,那么一個人對象就不能把那些可愛的小貓當作寵物! 太遺憾了! :)

基本上,將屬性/變量聲明為接口而不是具體類通常是因為我們希望將來在其中存儲不同類型的對象。 這使其更靈活,並且對於基類/派生類也是如此。

我同意當前的答案,並想補充一個原因:因為它減少了程序兩個不同位之間的糾纏。

想象一下我有一個這樣的課程:

public class Astronomy()
{
    public void CalculateOrbit()
    {
       Planet myVar = new Planet();
       // some code that does stuff with myVar
       // some *more* code that does stuff with myVar
       // etc
    }
}

那個“天文學”課-現在已經與您的“行星”交織在一起。 每當您接觸該“行星”課程時,您很有可能會無意中打破較大的“天文學”課程。

但是關於...

public class Astronomy()
{
    public void CalculateOrbit()
    {
       StellarObjectInterface myVar = new Planet();
       // some code that does stuff with myVar
       // some *more* code that does stuff with myVar
       // etc
    }
}

有什么變化? 您仍在創建Planet的實例...除了現在,您將其放入'StellarObjectInterface'對象。 現在,無論何時在myVar上進行操作,您都將無法僅使用Planet類willy-nilly的任何方法/屬性/字段/等-您必須遍歷StellarObjectInterface。

這對你有什么幫助? 這意味着只要Planet類遵循其實現的接口,就可以更改Planet,而不必擔心在Astronomy類中引起不良影響。

更好的是,您可以執行以下操作:

public class Astronomy()
{
    public void CalculateOrbit(StellarObjectInterface myVar)
    {
       // some code that does stuff with myVar
       // some *more* code that does stuff with myVar
       // etc
    }
}

現在,您的天文學課程不再與Planet相關! 當然,你可以傳遞一個地球,如果你喜歡,但你不必 您可以傳入任何恆星對象。

無論如何,希望這是有道理的。 如果您有興趣進一步研究,請查看一些SOLID原理以獲取更多信息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM