以多态访问函数

本文关键字:函数 访问 多态 | 更新日期: 2023-09-27 17:53:54

有A、B、C三个等级。类B和类C继承自类A。B类和C类有一个函数func1(), a类没有。我有一个list<A> OB,其中的每个物体不是B就是C。我想通过OB[0].Func1()来访问func1。我该怎么做呢?谢谢你!

以多态访问函数

您试图在A类上调用func1方法,其中A没有定义它?你不能。如果你想这样做,你可以让Func1A中抽象。

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

您可以在A中将Func1定义为虚拟的,而不是将其设置为抽象的,但我建议您不要这样做,因为这会引入反向的拒绝遗赠设计气味。

将方法添加到类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()
    {
    }
}

如果放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();
    }
}

抽象工厂做同样的事情,你正在寻找我在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();
   }
 }