【问题标题】:c#, force method implementation in child classc#,在子类中强制实现方法
【发布时间】:2019-07-09 23:47:39
【问题描述】:

我有这个设置:

public class BaseElement
{
    public BaseElement() { }
    public virtual void method01()
    {
        Console.WriteLine("class BaseElement method01");
    }
}
public class Element01 : BaseElement
{
    public Element01() { }
    public override void method01()
    {
        Console.WriteLine("class Element01 method01");
    }
}
public class Element02 : BaseElement
{
    public Element02() { }
    public override void method01()
    {
        Console.WriteLine("class Element02 method01");
    }
}

现在我想强制Element01/Element02/Element03等类实现method01。 我认为正确的方法是使用接口。 但是由于 Element01/Element02/Element03 等继承自 BaseElement,因此不需要在 Element01/Element02/Element03 等中实现 method01,因为它已经在 BaseElement 中实现。但我想强制 Element01/Element02/Element03 等在这些类中的每一个中实现特定的方法 01。另一方面,我还需要 BaseElement 中的 method01 来处理 Element01/Element02/Element03 等作为 BaseElement。 最好的方法是什么?

(这与抽象函数和虚函数的区别无关。我需要一个接口或抽象类的特定排列。)

【问题讨论】:

  • 制作BaseElement类和方法abstract...
  • 为什么不把方法抽象化?
  • @KarthikGanesan,我对此的回应是问 OP 为什么? (正如我在上一条评论中所做的那样)试图弄清楚他试图实现的目标,这导致他们明确要求 BaseElement 是一个可实例化的类......
  • 你能解释一下这部分吗? 另一方面,我还需要 BaseElement 中的 method01 来处理 Element01/Element02/Element03 等作为 BaseElement。 我不完全理解它
  • 我认为你能做的最好的就是“抽象”。如果这不合适,您不能强制派生类的编写者重写虚拟方法,因为由他们决定基类提供的默认行为是否适合他们的需求。

标签: c# class inheritance interface


【解决方案1】:

如果我正确理解了这个问题,您在基类中有一些默认行为,并且您需要强制在派生类中实现一些逻辑,您可以使用控制反转原则和Template method Design pattern,您必须创建另一个内部方法,例如 method01Int 和它将是抽象的,所有派生类都应该实现它,例如:

 public abstract class BaseElement
{
    public BaseElement() { }
    public  void method01()
    {
        Console.WriteLine("class BaseElement method01");
        method01Int();
    }

    protected abstract void method01Int();
}
public class Element01 : BaseElement
{
    public Element01() { }
    protected override void method01Int()
    {
        Console.WriteLine("class Element01 method01");
    }
}
public class Element02 : BaseElement
{
    public Element02() { }
    protected override void method01Int()
    {
        Console.WriteLine("class Element02 method01");
    }
}

即使在派生类中没有一些逻辑你也可以这样实现

    public class Element03 : BaseElement
{
    public Element03() { }
    protected override void method01Int()
    {

    }
}

【讨论】:

  • 很好的解决方案,谢谢!我测试了它并且它有效。但是 Guillaume CR 下面的解决方案更简单,代码更少并且更容易维护 - 在我看来。我想我只能接受一个答案......
  • @manton 实际上,这取决于您的领域模型到底是什么,在某些情况下,您的课程中真正的意义是什么,在另一种情况下它不是一个好的解决方案,它可能会很好!当您尝试引入继承时,您必须三思而后行,因为从可维护性的角度来看,(正如您所说,您需要易于维护的解决方案)继承不好,请改用组合!如果你能给我你的真实案例,我可以更详细地说明你的情况会更好
【解决方案2】:

创建两个界面。一个用于基类,另一个用于子类。并在 BaseElement 类中显式实现 method01()。希望对您有所帮助。

class Program
{
    static void Main(string[] args)
    {
        IBase obj = new BaseElement();
        IElement obj1 = new Element01();
        obj.method01();//call base
        obj1.method01();

        Console.ReadLine();
    }
}
public interface IBase
{
    void method01();
}
public interface IElement
{
    void method01();
}
public class BaseElement : IBase
{
    public BaseElement() { }
    void IBase.method01()
    {
        Console.WriteLine("class BaseElement method01");
    }
}
public class Element01 : BaseElement, IElement
{
    public Element01() { }
    public void method01()
    {
        Console.WriteLine("class Element02 method01");
    }

}
public class Element02 : BaseElement, IElement
{
    public Element02() { }
    public void method01()
    {
        Console.WriteLine("class Element02 method01");
    }
}

【讨论】:

  • 但是是什么迫使 Element01 的编写者将 IElement 接口放入基类型列表中呢?
  • @imk:我测试了您的解决方案,但不幸的是这不起作用,因为我无法在 BaseElement 中调用 method01。 BaseElement 中必须有 method01 可用。此代码将不起作用: Element01 el01 = new Element01(); BaseElement baseel = el01 作为 BaseElement; baseel.method01();
【解决方案3】:

使用中间元素:

public class BaseElement
{
    public BaseElement() { }
    public virtual void method01()
    {
        Console.WriteLine("class BaseElement method01");
    }
}
public abstract class MiddleElement: BaseElement
{
    public abstract override void method01();
};

public class Element01 : MiddleElement
{
    public Element01() { }
    public override void method01()
    {
        Console.WriteLine("class Element02 method01");
    }
}
public class Element02 : MiddleElement
{
    public Element02() { }
    public override void method01()
    {
        Console.WriteLine("class Element02 method01");
    }
}

话虽如此,我想了解您为什么有这些要求。可能有更简单的方法。

【讨论】:

  • 我认为这解决了我的问题。关键是,在 BaseElement 和子类之间放置一个抽象类。所以满足两个要求:1.)子类继承自BaseElement 2.)确保在每个子类中实现method01 谢谢!我将对其进行测试,然后我将接受答案。
  • 在做任何事情之前,你一定要检查一下:stackoverflow.com/questions/2118055/…
猜你喜欢
  • 2010-12-18
  • 2015-10-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-01
相关资源
最近更新 更多