簡體   English   中英

C#創建類和派生類的實例

[英]C# creating an instance of a class and derived class

我在c#程序中嘗試了以下代碼。 這僅是為了學習OOP概念。

 class a
    {      
        public void testa()
        {
        }
    }
    class b:a
    {     
        public void testb()
        {
        }
    }

  a a1 = new b();

  b b1 = new a();

關於上述代碼,我有以下查詢。

  1. 為什么我在第二行出現錯誤?
  2. 什么是a a1=new b() ;
  3. 為什么即使將b構造函數分配給a1也無法訪問a1.testb()
  4. a a1=new a()a a1=new b()什么區別?

1)如果您的意思是這一行:

b b = new a();

這是因為每個b都是a但並非每個a都是b

2-3) a a1=new b();是什么意思a a1=new b(); 為什么即使將b構造函數分配給a1也無法訪問a1.testb()

這意味着用戶可創建的對象b類,但得到引用它作為a (你可以把它低谷而無需進行轉換只能作為參考這樣a甚至是b

我將您的類和方法名稱更改為現實世界中的等效名稱,以便更好地理解。 我將a命名為Animal ,將testa命名為Eat ,將b testbHuman ,將testbTalk 因此,我們有:

class Animal {      
    public void Eat() { }
}

class Human : Animal {     
    public void Talk() { }
}

Animal a1 = new Human();

Human b1 = new Animal();

好的,返回您的問題。

1)在第二行出現錯誤,因為每個動物都不是人類。 是嗎?

2)根據我們的新命名約定, a1=new b()變為a1 = new Human ,這意味着Animal a1 = new Human 所以,這是正確的,因為人類是一種動物。

3) a1.testb()根據我們的新的命名慣例,轉向a1.Talk() 好吧, a1是一種動物( Animal a1 ),我們不能指望動物說話。

更多:

認為一個class是一組屬性和行為。 例如,我們有一個名為Animal的組,它定義了Eat行為。 另一個名為Human組擴展了Animal組,它也有自己的行為稱為Talk 我們知道, Human有其超級組的行為太-例如, Eat這個例子一樣。

當我們有一個Animal組的實例時,我們可以期望它會吃。 但是我們不能要求它說話。 這是不可能的。 另一方面,我們從“ Human組中選擇的每個項目實際上都是Animal 所以我們可以請他吃飯。

當我們有一個Human實例時,我們可以要求他表現為HumanAnimal 我的意思是,我們可以請他Talk ,也可以請他Eat 每個Human都可以位於人類組和動物組中。

1)當我們說Human b1 = new Animal(); 它說的很准確:從“ Animal組-右部分中拾取一個項目,然后將其放入“ Human組-左部分中-這是不可能的。 因為有很多動物不是人類。

2)當我們說Animal a1 = new Human :從Human組-右部分-拾取一個項目,然后將其放入Animal組-左部分-這很容易實現。

3)當我們說a1.Talk() ,我們希望Animal說話。 我的意思是我們期望Animal表現出不可能的Human行為。

對您來說, 繼承多態概念可能還不清楚。 本文可能會為您提供幫助。

如果類b從繼承a ,你可以把它想象成一條“專業化”的a 所以,你可以很容易地明白, b ,可以使用/視為a實例,但相反的是不是真的!


為什么我在第二行出現錯誤?

因為b b1 = new a(); 不是有效的分配。 如前所述,您可以將繼承的類實例分配給基類變量,但不能相反!

a1 = new b()是什么意思;

這種分配是正確的,因為您可以肯定地使用更具體的類實例作為基類實例。

為什么即使將b的構造函數分配給a1,也無法訪問a1.testb()?

當您從一個類繼承時,該類的所有public方法和protected方法都將被繼承,並且您可以在新類中訪問或重寫該方法。 但是testb()不是繼承的方法。 是在類b內定義的新方法,因此只有b b1=new b();以下分配時才可以使用它: b b1=new b();

如果定義a1 = new b(),要使用b中聲明的方法,可以將a1強制轉換為b

 a a1 = new b();
 ((b)a1).testb();

將您的課程視為合同,以保證某些操作的存在。 a定義了一個操作,類b繼承所有操作a ,定義了自己的另一個。

第一行:

a a1 = new b();

聲明一個名為的變量a1型的a ,這意味着你把這個變量應該有所有的操作類型的任何值a要求。 new b()創建類b的新實例,並將其分配給變量a1 由於類b繼承了類型a所有操作,因此可以將類型b的值分配給類型a的變量。

在第二行:

b b = new a();

同樣,您定義一個變量,該變量應具有類型b定義的所有操作。 但是由於您輸入的類型a的值testb類型b所需的testb操作,因此編譯器不會接受此值。

關於第三個問題,編譯器僅知道變量( a )的類型,而不知道您實際為其分配的值。 您基本上告訴編譯器“我保證這個值將定義testa操作。現在讓它執行testb操作!” 編譯器不知道變量的實際值,因此就其而言,這是不可能的。

至於a a1=new a()a a1=new b()之間的區別:在兩種情況下,都會創建類型a a的變量。 在第一個表達式中,分配給該變量的值是類型a的新創建實例,而在第二個表達式中,值是類型b的新創建實例。 由於“B”型基本型的擴展版本a ,編譯器知道這一切,你可以問類型的實例的a也可以通過類型的實例滿足b ,所以它只是把值,好像它是鍵入a

1)每個b是一個a但反之則不成立。

2)是多態的一個例子多態-僅用兩個句子定義

3)無法訪問a1.testb()因為您將其視為對testb()沒有定義的a的實例

暫無
暫無

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

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