有3个班级A,B,C。 B和C类继承自A.
B类和C类有一个函数 - func1(),A不。
我有一个list<A> OB
,其中的每个对象都是B或C.
我想通过OB[0].Func1()
访问func1。
我怎样才能做到这一点?
谢谢!
答案 0 :(得分:2)
您是否尝试在课程func1
上调用方法A
,其中A
没有定义它?你不能。如果您愿意,可以在Func1
内提取A
摘要。
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
您可以在Func1
中将A
定义为虚拟,而不是将其设置为抽象,但我建议您不要这样做,因为这会引入反转的Refused Bequest设计气味。
答案 1 :(得分: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()
{
}
}
答案 2 :(得分: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();
}
}
答案 3 :(得分: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();
}
}