2016-09-26 39 views
-1

我很難理解在C#中的繼承。假設,我有兩班這樣無法檢索方法一旦添加列表<object>在c#

public class Base 
{ 
    public void print() 
    { 
     Console.WriteLine("this is a BASE method"); 
    } 
} 
public class Derived : Base 
{ 
    public void print() 
    { 
     Console.WriteLine("this is a DERIVED method"); 
    } 
} 
現在

當我創建一個List<object>並嘗試添加兩個對象 喜歡這一點,並試圖訪問該方法時,我不能夠這樣做

class Program 
{ 
    static void Main() 
    { 

     List<object> lists = new List<object>(); 
     lists.Add(new Base()); 
     lists.Add(new Derived()); 
     foreach (var a in lists) 
     { 

     } 
     Console.ReadLine(); 
    } 
} 

但當我添加兩個整數值並嘗試訪問它,我能夠訪問它,這怎麼可能?

static void Main() 
{ 
    List<object> lists = new List<object>(); 
    lists.Add(4); 
    lists.Add(5); 
    foreach (var a in lists) 
    { 
     Console.WriteLine(a); 
    } 
    Console.ReadLine(); 
} 

我如何能夠獲得整數值,甚至沒有將它,我在這裏缺少一些關鍵的概念,請幫助我理解

更新1

也讓我嘗試解釋我的問題一次,當我想從添加列表中調用方法時,我必須將其轉換爲相應的類型,如下所示:

A a = lists[0] as A; 
B b = lists[1] as B; 
C c = lists[2] as C;  
a.print(); 
b.print(); 
c.print(); 

但是當我添加int值列表這樣

List<object> lists = new List<object>(); 
lists.Add(4); 
lists.Add(5); 
foreach (var a in lists) 
{ 
Console.WriteLine(a); 
} 

爲什麼是沒有必要先將其轉換成int和然後打印

回答

2

你缺少的關鍵概念是.ToString()被覆蓋在int這使它打印數字而不是System.Int32。您可以通過簡單地將public override string ToString()添加到您的函數中來讓代碼執行此操作。

public class Base 
{ 
    public override string ToString() 
    { 
     return "this is a BASE method"; 
    } 
} 

public class Derived : Base 
{ 
    public override string ToString() 
    { 
     return "this is a DERIVED method"; 
    } 
} 

class Program 
{ 
    static void Main() 
    { 

     List<object> lists = new List<object>(); 
     lists.Add(new Base()); 
     lists.Add(new Derived()); 
     foreach (var a in lists) 
     { 
      Console.WriteLine(a); 
     } 
     Console.ReadLine(); 
    } 
} 

居然能叫print()你需要讓你Base而不是object類型的服務,您需要標記打印功能爲基礎virtualoverride派生

public class Base 
{ 
    public virtual void print() 
    { 
     Console.WriteLine("this is a BASE method"); 
    } 
} 

public class Derived : Base 
{ 
    public override void print() 
    { 
     Console.WriteLine("this is a DERIVED method"); 
    } 
} 

static void Main() 
{ 

    List<Base> lists = new List<Base>(); 
    lists.Add(new Base()); 
    lists.Add(new Derived()); 
    foreach (var a in lists) 
    { 
     a.print(); 
    } 
    Console.ReadLine(); 
} 
+0

我知道如何使這個清單工作在我的例子,但我很困惑如何可以打印一個整數,而無需先轉換它...謝謝 –

1

多態性允許您在使用基類類型時調用子類的正確方法。然而,對此的限制是它所設置的類的類型也必須包含該方法。

您正在創建的列表objectObject類沒有您嘗試在其中調用的方法,因此您無法調用該方法。要糾正這個問題,你應該將列表改爲具有該方法的類型(在這種情況下爲Base)。

+0

你的意思是說,對象的方法是/ for integer? –

+0

@LijinJohn'Integer'類使用'Object'類中的重寫'toString()'方法。你的課不重寫'toString()' – yitzih

+0

@LijinJohn不,yitzih的回答並不涉及你的問題中的整數例子。他只是在談論如何解決你的課程。 Intiger使用別的東西 –

0

Console.WriteLine使用ToString當一般object類型被傳遞 - 該方法始終可用於任何類。

你可以在你的情況下,將其覆蓋:

public class Base 
{ 
    public override string ToString() 
    { 
     return "this is a BASE method"; 
    } 
} 

public class Derived : Base 
{ 
    public override string ToString() 
    { 
     return "this is a DERIVED method"; 
    } 
} 

然後你可以使用它像這樣:

foreach (var a in lists) 
{ 
    Console.WriteLine(a); 
} 

Integer已overrided該方法 - 這就是爲什麼IR工作。

+0

'Integer'不是.NET中的類,它是'System.Int32'或簡稱'int'。 –

+0

@ScottChamberlain您能否幫我理解打印整數時如何不需要轉換的概念......謝謝 –

+0

因爲Console.WriteLine是在寫入對象類型傳遞時調用.ToString()的。 ToString代碼執行作爲int類的一部分的轉換。這個答案顯示瞭如何讓你的班級也做到這一點。 –