【问题标题】:How Can I access base class method having same name in derived class using derived class object如何使用派生类对象访问派生类中具有相同名称的基类方法
【发布时间】:2019-03-17 02:26:17
【问题描述】:

我有一个实现接口的基类,还有一个继承基类的专用类。

我已经在基类中实现了接口的方法并将其标记为虚拟,在专用类中也覆盖了相同的方法。

现在我想解决 GetData() 方法,它要么返回基类的方法,要么返回子类的方法。

那么基本上我怎样才能使用专用类的引用或接口的引用来调用基类方法呢?

编辑 1 我有一个现有的数据提供者,我想保持其功能不变,并想使用一些子类或包装类,我可以在其中编写一个新的实现(另一个提供者),请注意我想继续运行现有的提供者现有场景和其他场景的新提供者)。如果我使用装饰器模式来解决这个问题怎么办?任何其他模式可以解决这个问题?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication2
{
    interface IDataProvider
    {
        void GetData();
    }

     abstract class StandardDataProvider : IDataProvider
    {
        public virtual void GetData()
        {
            Console.WriteLine("GetData_StandardDataProvider");
        }
    }

    class ManagedDataProvider : StandardDataProvider
    {

        public override void GetData()
        {
            Console.WriteLine("GetData_ManagedDataProvider");
        }

    }


    class Program
    {
        static void Main(string[] args)
        {       

            IDataProvider dataprovider = new  ManagedDataProvider();

            dataprovider.GetData();

            Console.ReadLine();
        }
    }
}

【问题讨论】:

  • 虚拟/覆盖方法专门设计用于防止这种行为。如果您希望能够访问被ManagedDataProvider 覆盖的StandardDataProvider 成员,那么ManagedDataProvider 将不得不公开一种新方法来获取它们。
  • 在我看来,无论你试图用这种方法解决什么问题,这种方法在我看来都是有缺陷的。您有一个定义一些动作/行为“GetData()”的基类。然后从这个基类继承的具体类将覆盖这个动作/行为。现在您要选择具体类是否会在某些任意外部情况下执行被覆盖的行为。这不是经过深思熟虑的......
  • 我不明白为什么你会覆盖某些东西然后不使用它?如果您需要基本功能,请不要在该类型中覆盖它。
  • 我不确定这是否适合您,但您或许可以将执行哪个操作的决定纳入 ManagedDataProviderGetData() 覆盖/i>,比如:public override void GetData() { if (shouldUseBaseImplementation) base.GetData(); else Console.WriteLine("GetData_ManagedDataProvider"); }

标签: c# oop inheritance interface polymorphism


【解决方案1】:

这是我能为您的问题想出的唯一解决方案:

interface IDataProvider
{
    void GetData();
}

abstract class StandardDataProvider : IDataProvider
{
    public virtual void GetData()
    {
        Console.WriteLine("GetData_StandardDataProvider");
    }
}

class ManagedDataProvider : StandardDataProvider
{

    public override void GetData()
    {
        Console.WriteLine("GetData_ManagedDataProvider");
    }

    public void GetBaseData()
    {
        base.GetData();
    }
}



class Program
{
    static void Main(string[] args)
    {

        IDataProvider dataprovider = new ManagedDataProvider();

        dataprovider.GetData();
        if (dataprovider is ManagedDataProvider)
            {
                (dataprovider as ManagedDataProvider).GetBaseData();
            }


        Console.ReadLine();
    }
}

另一种攻击方法是将 GetBaseData 添加到接口。

interface IDataProvider
{
    void GetData();
    void GetBaseData();
}

abstract class StandardDataProvider : IDataProvider
{
    public virtual void GetData()
    {
        Console.WriteLine("GetData_StandardDataProvider");
    }

    public virtual void GetBaseData()
    {
        Console.WriteLine("GetData_StandardDataProvider");
    }
}

class ManagedDataProvider : StandardDataProvider
{

    public override void GetData()
    {
        Console.WriteLine("GetData_ManagedDataProvider");
    }

    public override void GetBaseData()
    {
        base.GetData();
    }
}



class Program
{
    static void Main(string[] args)
    {

        IDataProvider dataprovider = new ManagedDataProvider();

        dataprovider.GetData();
        dataprovider.GetBaseData();            

        Console.ReadLine();
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-25
    • 1970-01-01
    • 1970-01-01
    • 2015-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多