c# - 用具体类型覆盖抽象方法

标签 c# generics inheritance design-patterns abstract-class

也许这是一个愚蠢的问题。但是,我不明白我错过了什么。

给定以下类定义

public abstract class AbstractBaseClass
{
    public abstract void Create(AnotherAbstractClass param1);
}

AnotherAbstractClass已定义

public abstract class AnotherAbstractClass
{
}

具体实现

public class AnotherConcreteImplementation : AnotherAbstractClass
{
}

我希望能够覆盖 Create使用具体类型的方法:

public class ConcreteImplementation : AbstractBaseClass
{
    public override void Create(AnotherConcreteImplementation param1) <-- There is no suitable method for override
    {
        // param1 is an instance of the concrete implementation
    }

    public override void Create(AnotherAbstractClass param1) <-- this is working but I'll have to cast on each implementation
    {
        // param1 is an instance of the abstract class and needs a cast
    }
}

这根本不可能还是有什么我不知道的方法?也许使用泛型?

编辑#1(添加更多上下文)

我试图实现/强制在具体实现中只有一个参数有效。 将其视为数据库层。 Create方法将在数据库中创建一个新条目。由于每个表都有不同的值,create-parameter 也有。 内部的类型转换有味道(在我看来),因为可以用 AnotherAbstractClass 的任何具体实现来调用它。 .

public class AddressTable : AbstractBaseClass
{
    public override void Create(AnotherAbstractClass param1)
    {
        // cast to concrete instance
        var casted = (ConcreteAddressCreate)param1;
    }
}

public class CityTable : AbstractBaseClass
{
    public override void Create(AnotherAbstractClass param1)
    {
        // cast to concrete instance
        var casted = (ConcreteCityCreate)param1;
    }
}

拥有 AddressTable 的实例我可以打电话

addressIntance.Create(new ConcreteAddressCreate()); // would be okay

另一方面我可以称之为

addressIntance.Create(new ConcreteCityCreate()); // would be okay but will fail at runtime with InvalidCastException

编辑#2(附加信息)

还应该可以扩展 AbstractBaseClass稍后使用更多抽象方法的类。 因此,对我来说,更可能使用泛型方法,而不是具体的类实现,每个方法要实现 200 个泛型参数。

最佳答案

它违反了里氏替换原则,所以你不能这样做是完全有道理的。也就是说,您不能免费“拥有”这样的协方差:

AbstractBaseClass bcl = new ConcreteImplementation();
bcl.Create(new DifferentImplementationWithoutSecondAbstract());

AbstractBaseClass 定义的契约使得 Create 必须与传入的 AbstractBaseClass任何实现一起工作 - 如果您对可以执行的内容给出约束你违反了它定义的契约(Contract)。

就像您假设的那样 - 您可以使用泛型:

// notice the recursive definition, we require the generic parameter
// to be a generic parameter of itself - allowing AbstractBaseClass
// to not be aware of its subclasses like in the other answers.
public abstract class AbstractBaseClass<T> where T : AbstractBaseClass<T>
{
    public abstract void Create(T param1);
}

public class Concrete : AbstractBaseClass<Concrete>
{
    public override void Create(Concrete param1)
    {
        Console.WriteLine("Hello!");
    }
}

关于c# - 用具体类型覆盖抽象方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33369749/

相关文章:

C# - MEF - 从可移植类库导入

C# 泛型 : Simplify type signature

Java 泛型困惑

c# - 关于 C# 和继承

c++ - 为什么必须使用继承类的全名调用基类中具有相同名称(不是签名)的方法?

c# - 在 C# 中从图像中提取帧

c# - 如何将泛型类的对象复制到具有继承类型的另一个对象?

c# - 需要什么来证明本契约(Contract)的要求?

java - 如何使用两个对象中最特殊的类型作为返回类型?

c++ - 为父类(super class)的非常量成员赋予初始值? (C++)