使用 switch 语句的多态性
Polymorphism using switch statement
我们有一些文档类型:
class Document
{
public void virtual Print()
}
class PDF : Document
{
public void override Print()
{
Console.WriteLine("PDF Printed");
}
}
class Excel : Document
{
public void override Print()
{
Console.WriteLine("Excel Printed");
}
}
假设我们有一个文档列表(Document 对象),我们对所有文档调用了虚函数 Print()。
foreach(Document doc in DocumentsList)
{
doc.Print();
}
我知道多态性是一种非常复杂的实现方式,但是我们真的可以使用 switch 语句来做同样的事情吗?我和一个人就此争论了很久,他说这是可能的。是吗?
多态性是解决这个问题的方法。如果选择 switch
语句,则需要使用 Reflection
或 is
关键字来确定要调用哪个对象的 Print()
。
是的,你可以,当然你可以在每次迭代时询问列表的成员,并且有很多技术可以实现这一点(例如属性、内部类型字段等)。
事实上,您在 C# 中所做的一切您也可以在汇编程序中完成!
然而,我几乎看不出避免 OOP 的优势有什么好处。
这个问题有点搞笑,因为使用开关的例子通常是用来演示你通常不想这样做的。
不使用继承,您的文档 class 可以这样:
class Doc {
public:
enum DocType{PDF,EXCEL}
private:
DocType docType;
}
然后你只需使用
switch (doc.getDocType()){
...etc...
}
但是,通常使用继承更好的原因有几个。想象一下,例如,您想要添加另一种文档类型。然后,您不仅必须添加另一个枚举字段,而且(这里出现了一个大问题)您还必须更改所有使用您的文档 class 的代码中的每个 switch 语句。这很烦人,通常你不想这样做。
是的,您始终可以使用开关(或 if-else 链)来询问类型。您可以将文档类型信息保存在您的对象中,例如作为枚举,并在开关中使用它。
为什么你不应该那样做?因为在添加新的派生类型时必须扩展所有这些开关。
为避免这种情况,您可以实现更自动化的操作:拥有一个指向函数(或 C# 中的委托)的指针列表,您可以使用适合该特定对象的函数(例如 print
委托将指向 print_pdf()
(对于 PDF 文件)和 print_excel()
(对于 excel 文件)。嘿,你手工制作了一个可怜人的多态性。
多态性的好处在于,使用 多态对象的代码可以是类型不可知的。它不知道对象实际具有什么精确类型,也不想知道。当编写代码 handling 对象时,精确类型可能不存在。所有详细信息都隐藏在类型中,这对于维护来说非常棒。
我们有一些文档类型:
class Document
{
public void virtual Print()
}
class PDF : Document
{
public void override Print()
{
Console.WriteLine("PDF Printed");
}
}
class Excel : Document
{
public void override Print()
{
Console.WriteLine("Excel Printed");
}
}
假设我们有一个文档列表(Document 对象),我们对所有文档调用了虚函数 Print()。
foreach(Document doc in DocumentsList)
{
doc.Print();
}
我知道多态性是一种非常复杂的实现方式,但是我们真的可以使用 switch 语句来做同样的事情吗?我和一个人就此争论了很久,他说这是可能的。是吗?
多态性是解决这个问题的方法。如果选择 switch
语句,则需要使用 Reflection
或 is
关键字来确定要调用哪个对象的 Print()
。
是的,你可以,当然你可以在每次迭代时询问列表的成员,并且有很多技术可以实现这一点(例如属性、内部类型字段等)。
事实上,您在 C# 中所做的一切您也可以在汇编程序中完成! 然而,我几乎看不出避免 OOP 的优势有什么好处。
这个问题有点搞笑,因为使用开关的例子通常是用来演示你通常不想这样做的。
不使用继承,您的文档 class 可以这样:
class Doc {
public:
enum DocType{PDF,EXCEL}
private:
DocType docType;
}
然后你只需使用
switch (doc.getDocType()){
...etc...
}
但是,通常使用继承更好的原因有几个。想象一下,例如,您想要添加另一种文档类型。然后,您不仅必须添加另一个枚举字段,而且(这里出现了一个大问题)您还必须更改所有使用您的文档 class 的代码中的每个 switch 语句。这很烦人,通常你不想这样做。
是的,您始终可以使用开关(或 if-else 链)来询问类型。您可以将文档类型信息保存在您的对象中,例如作为枚举,并在开关中使用它。
为什么你不应该那样做?因为在添加新的派生类型时必须扩展所有这些开关。
为避免这种情况,您可以实现更自动化的操作:拥有一个指向函数(或 C# 中的委托)的指针列表,您可以使用适合该特定对象的函数(例如 print
委托将指向 print_pdf()
(对于 PDF 文件)和 print_excel()
(对于 excel 文件)。嘿,你手工制作了一个可怜人的多态性。
多态性的好处在于,使用 多态对象的代码可以是类型不可知的。它不知道对象实际具有什么精确类型,也不想知道。当编写代码 handling 对象时,精确类型可能不存在。所有详细信息都隐藏在类型中,这对于维护来说非常棒。