【问题标题】:Multiple derived abstract classes?多个派生抽象类?
【发布时间】:2011-06-30 06:57:25
【问题描述】:

我必须创建一个包含课程类别的课程管理系统:

Cooking, sewing and writing courses

cookingwriting 各有 2 门课程(意大利语、海鲜、创意写作和商务写作)。这将创建派生摘要:

abstract course -> abstract cooking -> concrete seafood

抽象的烹饪和写作有共同的领域和一些共同的方法,但它们也有抽象的方法,在基类中是抽象的。

这可以在 C# 中完成吗?如果我使派生的抽象类方法抽象,Visual Studio 说它们隐藏了基类抽象,然后具体的类方法有错误说基类必须是抽象的(它是但不能注册)。我一直在寻找答案。我知道在 C# 中使用了单继承,但继承会沿着链条进行。最佳答案是什么?

这是一个代码 sn-p - 我希望它能澄清问题:

public abstract class Course
{
    public abstract void AddStudent(StudentName sn, int f);
    public abstract decimal CalculateIncome();
}

public abstract class WritingCourse : Course
{
    public void AddStudent(StudentName sn, int f)
    {
     //Add student
    }
    public abstract decimal CalculateIncome(); // can only be claculated in concrete
}

public class BusinessWritCourse : WritingCourse
{
    public void AddStudent(StudentName sn, int f):
    base(sn, false){}

    public decimal CalculateIncome()
    {
       return //do stuff
    }
}

public class SewingCourse : Course
{
    public override void AddStudent(StudentName sn, int f)
    {
        //do stuff
    }

    public override decimal CalculateIncome()
    {
       return //do stuff
    }
}

【问题讨论】:

  • 你能贴出你遇到的问题的示例代码吗?

标签: c# .net c#-4.0 abstract-class multiple-inheritance


【解决方案1】:

如果我创建派生抽象类 方法抽象 Visual Studio 说 他们隐藏了基类抽象和 那么具体的类方法有 错误说基类必须是 摘要(可以但不能注册)

如果你有一个基类'A',它有一个抽象方法'b()',那么你不必在B:A中再次声明'b()'作为抽象,让C:B覆盖它,只是不要使用它。即使你在 B 类中重写了 'b()' 方法,你也可以在 'c()' 类中再次重写它(甚至使用 base.(); 来执行 B 的实现。

一些代码:

public abstract class A{
    public abstract void b();
}

public class B : A{
    public override void b() { //do stuff }; //overrides b from a
    public virtual void c() { //do stuff }; //creates an implemented method c in B that can be overriden by childs.
    public void d() { //do stuff};
}

public class C : B{
    public override void b() { //do stuff}; //overrides b from A, works!
    public override void c() {//do stuff}; //overrides c from B, works!
    public override void d() {//do stuff}; //doesn't work since d from B isn't abstract or virtual (hides it)
    public new void d() {//do stuff}; //works, hides d, but when you use inheritance this method will not be called, instead B's d() method will be called, only if you see C as  the specific class C this will work
}

还要澄清:声明为抽象的方法必须被覆盖(就像在接口中一样,并且只能由声明抽象方法的类的直接子级来覆盖)。声明为 virtual 的方法可以被覆盖,但不是必须的。

【讨论】:

  • 只是澄清一下-如您所见,我有一个来自A的具体类A1以及一个抽象A2-即使它在A2中是抽象的,我也不想实现它-我必须....我无法将抽象方法从 A2 传递到 B...
【解决方案2】:

我认为这类问题最好使用接口而不是抽象类来解决: 例如:

//
interface IInterface1
{
    void SameMethod();
}

interface IInterface2
{
    void SameMethod();
}


class TestClass : IInterface1, IInterface2
{
    void IInterface1.SameMethod()
    {
        // do one thing for Interface 1
    }

    void IInterface2.SameMethod()
    {
        // do something elsefor Interface 2
    }
}

class Program
{
    static void Main(string[] args)
    {
        TestClass test = new TestClass();

        IInterface1 i1 = test;
        i1.SameMethod(); // will call IInterface1.SameMethod()

        IInterface2 i2 = test;
        i2.SameMethod(); // will call IInterface2.SameMethod()

    }
}

【讨论】:

  • 我曾想过使用接口 - 但是在讨论区中,一个学生提到了它们,讲师说不要寻找不存在的实现......
【解决方案3】:
public class StudentName
{ }

public abstract class Course
{
    public abstract void AddStudent(StudentName sn, int f);
    public abstract decimal CalculateIncome();
}

public abstract class WritingCourse : Course
{
    override public void AddStudent(StudentName sn, int f)
    {
        //Add student
    }
    override public abstract decimal CalculateIncome(); // can only be claculated in concrete
}

public class BusinessWritCourse : WritingCourse
{
    override public void AddStudent(StudentName sn, int f)
    { base.AddStudent(sn, 0); }

    override public decimal CalculateIncome()
    {
        return (decimal)3.4;//do stuff
    }
}

public class SewingCourse : Course
{
    public override void AddStudent(StudentName sn, int f)
    {
        //do stuff
    }

    public override decimal CalculateIncome()
    {
        return (decimal)10; //do stuff
    }
}

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

    }
}

【讨论】:

    【解决方案4】:

    如果我理解正确,我认为您想在要覆盖的抽象方法上使用“virtual”关键字?

    如果您谈论的错误是“某些方法隐藏了继承的成员,如果要隐藏,请添加新关键字”,那么基方法上的 virtual 和继承方法上的覆盖就可以了:

    public abstract class BaseClass
    {
        public virtual void SomeMethod()
        {
        }
    }
    
    
    public abstract class InheritingClass : BaseClass
    {
        public override void SomeMethod()
        {
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2018-04-17
      • 1970-01-01
      • 1970-01-01
      • 2011-02-01
      • 2015-05-30
      • 2021-08-04
      • 1970-01-01
      • 2018-09-12
      • 2013-11-30
      相关资源
      最近更新 更多