【问题标题】:c# Is there a way that my base class and derived class can implement Interface methods separately?c#有没有办法让我的基类和派生类分别实现接口方法?
【发布时间】:2016-07-08 14:51:02
【问题描述】:

我知道这个问题令人困惑,但很难为这个问题想出一个好的标题,所以我会在这里描述更多。

我有一个接口 A 有 2 个方法,IsValidRow()IsFileValid() 我有一个基类 B 和一个派生类 C 这里的目标是我希望基类实现IsFileValid(),所以它可以被从基类派生的所有类继承,并且每个派生类都可以实现IsValidRow()

问题是IsFileValid() 在内部调用IsValidRow()。如果我这样做了

B:A

A 需要在 B 中实现 IsValidRow()

目前我的派生类 C 继承自基类和接口 atm。

只要满足这两种方法的要求,我不介意重组一切(一种将在基类或其他东西中实现一次并继承,而另一种将在每个派生类中实现)

interface IFileValidator
{
    Pair<bool, string> IsValidRow(List<string> row);

    bool IsFileValid(string file);
}

class FileValidator : IFileValidator
{
    public bool IsFileValid(string file)
    {
        // calls IsValidRow()
        IsValidRow();
    }
 }

class FacilitiesCalendarValidator : FileValidator, IFileValidator
{

    public Pair<bool, string> IsValidRow(List<string> row)
    {
            //stuff
    }
 }

【问题讨论】:

  • 如果B 被声明为abstract,我认为它不必为所有方法提供实现,即使它们来自接口。

标签: c# class inheritance


【解决方案1】:

这两种情况都有可能。

对于可选的可重写方法,在子类中将基类方法声明为virtualoverride

对于必须由子类提供实现的方法,将类和方法标记为abstract

您不必在子类中重写 virtual 方法,因此除非您明确决定使用 override,否则实现将被继承。

例如:

 interface IInterface
 {
     int Transform(int a, int b);
     int AnotherTransform(int a, int b);
 }

 abstract class A : IInterface
 {
    public virtual int Transform(int a, int b)
    {
        return a + b;
    }

    public abstract int AnotherTransform(int a, int b);
 }

 class B : A
 {
    public override int Transform(int a, int b)
    {
        return a - b;
    }

    public override int AnotherTransform(int a, int b)
    {
       return a * b;
    }
 }

【讨论】:

  • 看来 OP 还需要将类/方法抽象化,您可能还想添加该信息。
  • 不确定他是否这样做,因为他没有明确说 B 一定不能实例化。 ;) 然而,他确实需要澄清IsValidRow(),因为它读起来好像他说它必须在子类中实现而不是可选地实现。
  • 嗯。对于A类,如果我不打算在Transform()中实现任何东西,我只会在B类中实现Transform()?我的意思是我可以看到自己在基类虚方法中返回一些垃圾并在所有派生的方法中覆盖它
  • @ygongdev 如果你不能使用抽象基类,你总是可以把它变成虚拟的并抛出一个`NotImplementedException()`
  • 你需要从你的基类还是只从子类调用 isValidRow ?
【解决方案2】:

您可以将方法IsValidRow()标记为abstract

namespace test
{
    interface A
    {
        bool IsFileValue();
        bool IsValidRow();
    }

    abstract class B : A
    {
        public bool IsFileValue()
        {
            return IsValidRow();
        }

        public abstract bool IsValidRow();
    }

    class C : B
    {
        public override bool IsValidRow()
        {
            return true;
        }
    }
}

【讨论】:

    【解决方案3】:

    我有一个解决方案是使用接口隔离原则。这意味着声明两个interfaces。第一个有一个方法是IsFileValid(),第二个接口实现了第一个接口并有另一个方法是IsFileValid(),就像这样

      Interface A { void IsFileValid(); }
      Interface B : A { void IsValidRow();}
    

    基类实现接口A,所有派生类实现接口B,就像这样。

    public class Base : A
    {
          void IsFileValid(){ // immplementaion details}
    }
    
    public class Child : Base, B
    {
          void IsValidRow(){// immplementaion details}    
    }
    

    快乐编码

    【讨论】:

    • 这并不能解决 OP 的问题,因为基类需要自己调用 IsValidRow,但要在子类中实现。
    • 是的,你是对的,但我认为他说他只需要从子类调用 IsValidRow。
    • 没有OP声明IsValidRow是从IsFileValid调用的,基类实现IsFileValid,子类实现IsValidRow
    • 啊,好吧,所以你是完全正确的。非常感谢您的指出。
    猜你喜欢
    • 2012-03-14
    • 2015-04-11
    • 2014-03-22
    • 2021-07-24
    • 2021-11-16
    • 2015-05-22
    • 2016-06-14
    • 2010-11-22
    • 2011-02-10
    相关资源
    最近更新 更多