2014-03-26 31 views
0

有3個類A,B,C。 B和C類從A繼承。 B類和C類有一個函數 - func1(),A doesnt。 我有一個list<A> OB其中它的每個對象都是B或C. 我想通過OB[0].Func1()訪問func1。 我該怎麼做? 謝謝!訪問多態中的函數

+1

你不能這樣做,沒有定義在'A'該方法或者不使用定義'func1'的通用接口。 –

回答

0

的方法添加到A級虛擬,使者B,C重寫它:

public class A 
{ 
    public virtual void Foo() 
    { 

    } 
} 

public class B : A 
{ 
    public override void Foo() 
    { 

    } 
} 

public class C : A 
{ 
    public override void Foo() 
    { 

    } 
} 
+1

@ user3371183您應該更新問題並解決您嘗試解決的問題,您可能會得到一個更相關的答案,以不同的方式解決您的問題。 – Matthew

2

您正在嘗試撥打A上的方法func1,其中A未定義它嗎?你不能。如果您想這樣做,您可以在A內使0123'摘要。

abstract class A 
{ 
    public abstract Func1(); 
} 

class B : A 
{ 
    public override Func1() 
    { 
     MessageBox.Show("Hello World"); 
    } 
} 

class C : A 
{ 
    public override Func1() 
    { 
     MessageBox.Show("Goodbye World"); 
    } 
} 

事實上,Func1是,你不能直接實例A抽象的手段,但你可以實例B

var listOfA = new List<A>(); 

listOfA.Add(new B()); 
listOfA.Add(new C()); 

listOfA[0].Func1(); // hello world 
listOfA[1].Func1(); // goodbye world 

你可以做Func1A定義爲虛擬,而不是將其設置爲抽象的,但我建議你不要因爲這將引入一個反向Refused Bequest設計的氣味。

0

如果它沒有意義把FUNC1()或不能改變A類,你可以創建一個具有func1()並且只有B類和C類的接口實現該接口。然後,當你需要調用func1()使用as操作符將你的對象轉換爲那個接口。當使用as運算符時,如果轉換失敗,則不會拋出異常。

public interface MyInterface 
{ 
    void func1(); 
} 

public class B : MyInterface 
{ 
    public func1() {...} 
    .... 
} 

public class C : MyInterface 
{ 
    public void func1() {...} 
    .... 
} 

//example of calling func1() 
List<A> list = new List<A>(stuff); 
foreach(A item in list) 
{ 
    MyInterface tmp = item as MyInterface; 
    if(tmp != null) 
    { 
     tmp.func1(); 
    } 
} 
0

抽象工廠做你正在尋找 同樣的事情,我發現這個代碼在CodeProject 這可能幫助你

//Let's define type of bread bases 
public enum BreadBase 
{ 
HotIndianMasalaBase, 
PunjabiTadkaBase, 
ItalianCheeseBase, 
VeggieBase, 
} 
//This is a breadfactory where people visit to get their favorite bread bases 
public interface BreadFactory 
{ 
    Bread GetBread(BreadBase BreadBase); 
} 
//The abstract bread 
public interface Bread 
{ 
    void Bake(); 
} 

//create concrete classes 

public class HotIndianMasalaBread :Bread 
{ 
public void Bake() 
{ 
    Console.WriteLine ("For you::Hotindian Masala base Bread."); 
} 
} 
public class VeggieBread : Bread 
{ 
public void Bake() 
{ 
    Console.WriteLine("For you::Veggie base Bread."); 
} 
} 

public class ItalianCheeseBread : Bread 
{ 
public void Bake() 
{ 
    Console.WriteLine("For you::Italian cheese base Bread."); 
} 
} 
public class PunjabiTadkaBaseBread : Bread 
{ 
public void Bake() 
{ 
    Console.WriteLine("For you::Punjabi tadka base bread."); 
} 
} 
//Lets create bread factories aka concrete classes 

public class AmericanBreadFactory :BreadFactory 
{ 
public Bread GetBread(BreadBase BreadBase) 
{ 
    Bread vBread = null; 
    switch (BreadBase) 
    { 
     case BreadBase.VeggieBase: 
      vBread = new VeggieBread(); 
      break; 
     case BreadBase.ItalianCheeseBase: 
      vBread = new ItalianCheeseBread(); 
      break; 
    } 
    return vBread; 
    } 
} 

    public class IndianBreadFactory :BreadFactory 
    { 
public Bread GetBread(BreadBase BreadBase) 
{ 
    Bread vBread = null; 
    switch (BreadBase) 
    { 
     case BreadBase.HotIndianMasalaBase: 
      vBread = new HotIndianMasalaBread(); 
      break; 
     case BreadBase.PunjabiTadkaBase: 
      vBread = new PunjabiTadkaBaseBread(); 
      break; 
    } 
    return vBread; 
    } 
} 

//lets order breads 

class Program 
{ 
static void Main(string[] args) 
{ 
//example of abstract factory 
AmericanBreadFactory vAmericanBread = new AmericanBreadFactory(); 
Bread vBread = vAmericanBread.GetBread(BreadBase.VeggieBase); 
vBread.Bake(); 

//lets bak indian punjabi tadka bread 
IndianBreadFactory vIndianBreadFactory = new IndianBreadFactory(); 
Bread vIndianBread = vIndianBreadFactory.GetBread(BreadBase.PunjabiTadkaBase); 
vIndianBread.Bake(); 
    } 
}