如何在类已经有父类时“继承”方法

时间:2016-04-28 00:52:57

标签: c# .net oop

public class StudentDm : EntityBaseDm {
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string FormattedName
    {
        get
        {
            return LastName + ", " + FirstName;
        }
    }
}

public class ProviderDm {
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string FormattedName
    {
        get
        {
            return LastName + ", " + FirstName;
        }
    }
}

我有一个继承EntityBaseDm的Student类。 我有一个Provider类,我不想继承EntityBaseDm。

我想将FormattedName get方法和实现提取到泛型类中,但我不想将它放在EntityBaseDm中,因为它是通用的。我将不得不创建一个接口,如IFirstLastName,但接口不允许我实现功能。我知道有很多设计模式,其中一个可以解决这个问题。我想知道是否有人可以指出我正确的方向(至少使用正确的模式)

4 个答案:

答案 0 :(得分:3)

在进一步讨论之前,请考虑如果您创建另一个方法,其中某些对象应该共享,将会发生什么,但其他方法不应该。试图通过继承将函数组合在一起可能会突然变得混乱。它不会比它更频繁地工作。

您可能听说过“赞成合成而非继承”的建议。从广义上讲,它意味着最好将所需的功能集中在一起,而不是尝试实现所需功能在基类中的层次结构。

如果“名称”需要一致的功能,如格式化,那就是将其作为自己的类。

public class Name
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string FormattedName { get { return LastName + ", " + FirstName; } }
}

然后在StudentDm

上有一个属性
public Name StudentName { get; set;}

但是你这样做了,我不建议仅仅因为一些共享属性而将类放在层次结构中。迟早(通常更早)出现的东西属于某些继承的类而不属于其他类,然后它变得复杂。

答案 1 :(得分:2)

我同意@ ScottHannen对此的建议。对象组合将是一个很好的选择。

但是,您可以创建您提到的IFirstLastName接口,然后创建扩展方法。

public interface IFirstLastName
{
    string FirstName { get; }
    string LastName { get; }
}

public static class IFirstLastNameExtensions
{
    public static string FormattedName(this IFirstLastName fln)
    {
        return $"{fln.LastName}, {fln.FirstName}";
    }
}

public class StudentDm : EntityBaseDm, IFirstLastName
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

public class ProviderDm : IFirstLastName
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

然后,您可以在任何实现FormattedName的类上调用IFirstLastName方法:

var dm = new ProviderDm();
dm.FormattedName();

答案 2 :(得分:0)

答案是abstract class。这类似于一个接口,您可以为实现类定义声明,但您也可以在抽象类本身中定义实现。

例如,你可以有一个抽象的NameBase类,如下所示:

public abstract NameBase : EntityBaseDm
{
    public string FirstName { get; set; }
    public string LastName { get; set; }

    public string FormattedName
    {
        get
        {
            return LastName + ", " + FirstName;
        }
    }
}

然后,您的实现类继承抽象类:

public class StudentDm : NameBase {
}

public class ProviderDm : NameBase {
}

注意,您不需要在这些类中定义名称属性,但仍可使用它们:

var student = new StudentDm();
student.FirstName = "John";
student.LastName = "Smith";

var fullName = student.FormattedName; // returns Smith, John

答案 3 :(得分:0)

你要求多重继承,而c#是不可能的。您可以选择创建一个继承自EntityBaseDM的中间类,并仅实现所需的方法。您的ProviderDmStudentDm来自IntermediateBaseDM并提供更多属性。

class IntermediateBaseDM : EntityBaseDM
{
    public string FirstName { get; set; }
    public string LastName { get; set; }

    public string FormattedName
    {
        get
        {
            return LastName + ", " + FirstName;
        }
    }
}