我现在想知道当我们不想在派生类中引入添加字段/方法时继承是否很好。假设我有一个名为Place
的基类,以及一个派生类-Toilet
和Restaurant
。 Toilet
和Restaurant
均未引入新字段或方法。它们只是让我检查Place
是Toilet
还是Restaurant
-在创建List<Place>
时很有用:
if(Place is Toilet)
...
else if(Place is Restaurant)
...
这是不好的做法吗?还是应该创建一个名为PlaceType的枚举并将其放在Place类中,然后在必要时进行检查?我更喜欢使用第一种解决方案,因为将来可以根据需要轻松添加新的字段和方法。
答案 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 ,您就可以摆脱很多if
和switch
语句。
答案 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 if
或case
。只需让新类实现所需的方法即可。