2类同方法同继承怎么写?

How to write 2 classes with the same method and inheritance?

我有 X 类 具有不同的信息和计算方法,应该共享但可以被覆盖,所以:

class Rule1 {
    int type = 1;
    string name = "Rule";
    public float Calc()
    {
        return 1 + 2 + type; // SAME
    }
}

class Rule2 {
    int type = 2;
    string name = "Rule2";
    public float Calc()
    {
        return 1 + 2 + type; // SAME
    }
}

class Rule3 {
    int type = 3;
    string name = "Rule3";
    public float Calc()
    {
        return 3 + 4 + type; // DIFFERENT
    }
}

调用方法中我想写的是这样的:

class Calculator
{
    public void Do(List<IRules> ruleList)
    {
        foreach(var rule in ruleList)
        {
            rule.Calc();
        }
    }
}

那么我的界面应该是什么样子以及如何将 calc 方法抽象为默认实现但可覆盖?

如果您有一个适用于大多数但不是所有继承者的实现,请在派生的 class:

中将其标记为 virtualoverride
public class BaseCalculation
{
    public virtual float Calculate()
    {
        return 42;
    }
}

public class HalfCalculation : BaseCalculation
{
    public override float Calculate()
    {
        return 21;
    }
}

您现在可以使用基础 class、BaseCalculation,而不是接口。如果您坚持仍然使用接口,那么您仍然可以在接口中定义 Calculate() 方法并将其应用于您的基础 class:

public interface IRules
{
    float Calculate();
}

public class BaseCalculation : IRules
{
    // same as above

额外的好处是,您可以将此接口应用到 其他 classes,它们也可以计算一些东西,但没有 [=14= 中的任何逻辑].

您可以使用 asbtract 基础 class 和 Calc 上的多态性进行尝试。

What is polymorphism

除非您有充分的理由,否则无需使用界面。

What is the difference between an interface and a class

我们使用受保护的构造函数来传播参数。

class Calculator
{
  public void Do(List<RuleBase> ruleList)
  {
    foreach ( var rule in ruleList )
    {
      // do what you want with the result of rule.Calc();
    }
  }
}
public abstract class RuleBase
{
  public int Type { get; private set; }
  public string Name { get; private set; }
  public abstract float Calc();
  protected RuleBase(int type, string name)
  {
    Type = type;
    Name = name;
  }
}
public class Rule1 : RuleBase
{
  public override float Calc()
  {
    return 1 + 2 + Type;
  }
  public Rule1()
    : base(1, "Rule1")
  {
  }
  protected Rule1(int type, string name)
    : base(type, name)
  {
  }
}
public class Rule2 : Rule1
{
  public Rule2()
    : base(2, "Rule2")
  {
  }
  protected Rule2(int type, string name)
    : base(type, name)
  {
  }
}
public class Rule3 : RuleBase
{
  public override float Calc()
  {
    return 3 + 4 + Type;
  }
  public Rule3()
    : base(3, "Rule3")
  {
  }
  protected Rule3(int type, string name)
    : base(type, name)
  {
  }
}

如果您想要一个接口,请创建它并将其添加到 RuleBase:

public interface IRule
{
  float Calc();
}

public abstract class RuleBase : IRule

每个class都必须支持该接口。每个 class 中方法 Calc 的实现并不重要。它们可以相同或不同。

如果你想要一个标准的实现(虚拟实现),你可以使用基础 class 并在某些 class 中覆盖该方法(在你的示例 Rule3 中)。

如果您不想要标准实现(虚拟实现),您可以使用抽象基础 class 并覆盖所有 classes 中的方法(在您的示例 Rule1、Rule2 和 Rule3 中).

但这与您要使用的界面无关。

完整的工作示例(仅使用界面):

using System;
using System.Collections.Generic;

namespace Temp
{
    class Program
    {
        static void Main(string[] args)
        {
            var calc = new Calculator();
            var rules = new List<IRule>() { new Rule1(), new Rule2(), new Rule3() };
            calc.Do(rules);
            Console.WriteLine(calc.GetTotal());
            Console.ReadKey();
        }
    }

    public interface IRule
    {
        float Calc();
    }

    public class Rule1 : IRule
    {
        int type = 1;
        string name = "Rule";
        public float Calc()
        {
            return 1 + 2 + type; // SAME
        }
    }

    public class Rule2 : IRule
    {
        int type = 2;
        string name = "Rule2";
        public float Calc()
        {
            return 1 + 2 + type; // SAME
        }
    }

    public class Rule3 : IRule
    {
        int type = 3;
        string name = "Rule3";
        public float Calc()
        {
            return 3 + 4 + type; // DIFFERENT
        }
    }

    public class Calculator
    {
        private float _total = 0;

        public void Do(List<IRule> ruleList)
        {
            foreach (var rule in ruleList)
            {
                _total += rule.Calc();
            }
        }

        public float GetTotal()
        {
            return _total;
        }
    }
}

您正在搜索继承的 class 和虚拟方法(允许覆盖):

class GenericRule {
    int type = 1;
    string name = "Rule";
    public virtual float Calc()
    {
        return 1 + 2 + type; // SAME
    }
}

class Rule3 : GenericRule
{
    int type = 3;
    string name = "Rule3";
    public override float Calc()
    {
        return 3 + 4 + type; // DIFFERENT
    }
}

class Calculator
{
    public void Do(List<GenericRule> ruleList)
    {
        foreach(var rule in ruleList)
        {
            rule.Calc();
        }
    }
}