不添加新字段/方法的继承有意义吗?

时间:2019-06-29 19:41:53

标签: c# inheritance

我现在想知道当我们不想在派生类中引入添加字段/方法时继承是否很好。假设我有一个名为Place的基类,以及一个派生类-ToiletRestaurantToiletRestaurant均未引入新字段或方法。它们只是让我检查PlaceToilet还是Restaurant-在创建List<Place>时很有用:

if(Place is Toilet)
    ...
else if(Place is Restaurant)
    ...

这是不好的做法吗?还是应该创建一个名为PlaceType的枚举并将其放在Place类中,然后在必要时进行检查?我更喜欢使用第一种解决方案,因为将来可以根据需要轻松添加新的字段和方法。

2 个答案:

答案 0 :(得分:0)

出于您自言自语的原因,我不会考虑您本身的不良做法:

  

如果将来需要,可以轻松添加新的字段和方法

但是我个人会采用您建议的第二种选择:

  

创建一个名为PlaceType的枚举并将其放在Place类中

主要是因为如果您决定要在数据库中存储地方或将其序列化为JSON,那么使用一个指示类型的字段会使其变得更加容易。 / p>

如果您需要引入依赖 type 的功能,则最好将两者结合使用,这是最佳选择:

enum PlaceType
{
    Toilet,
    Restaurant
}

class Place
{
    public Place(PlaceType type)
    {
        Type = type;
    }

    public PlaceType Type { get; }
}

class Toilet : Place
{
    public Toilet() : base(PlaceType.Toilet)
    {

    }
}

编辑:

除此之外,我想补充一点,您应该避免使用is关键字来执行操作,具体取决于 place 的类型(如代码段所示) )。 在大多数情况下,使用Polymorphism可以更好地做到这一点。

例如,如果所有这些地方都应具有访问权限,则可以执行以下操作:

class Place
{
    public virtual void Visit()
    {
        // What happens during visit,
        // if the derived class doesn't override the Visit method
    }
}

class Toilet : Place
{
    public override void Visit()
    {
        // Visit functionality specific to the Toilet Place
    }
}

现在,如果您有一个List<Place>并对其成员之一调用Visit,它将在基类中调用Visit的默认实现,或者如果该方法在派生类将调用此方法。一旦引入更多应该也可以访问的 places ,您就可以摆脱很多ifswitch语句。

答案 1 :(得分:0)

那么你可以做到这一点;但是,当您必须做if(Place is Toilet) ... else if(Place is Restaurant) ...时,则可以改善设计并改用polymorphysm。

让我们举个例子(让我们使用带模式匹配的开关)。 Console.WriteLine只是您真实代码的占位符。

switch (place)
{
    case Toilet toilet:
        Console.WriteLine($"This is toilet {toilet.Name}");
        break;
    case Restaurant restaurant:
        Console.WriteLine($"This is restaurant {restaurant.Name}");
        break;
}

相反,请向Writeline()添加抽象(或虚拟)方法Place并在具体位置覆盖它

public abstract class Place
{
    public Place(string name) => Name = name;
    public string Name { get; }
    public abstract void WriteLine();
}

public class Toilet : Place
{
    public Toilet (string name) : base(name) {}
    public override void WriteLine() => Console.WriteLine($"This is toilet {Name}");
}

// do the corresponding thing with Restaurant

现在您可以使用

进行打印
place.WriteLine(); // `place` could be a Toilet or a Restaurant or
                   // anything else deriving from Place. No "if" or "switch" required.

,如果以后再添加更多地点类型,则无需在代码中添加任何新的else ifcase。只需让新类实现所需的方法即可。

另请参阅:Polymorphism (C# Programming Guide)