我知道这个问题已经被问了很多次,但在我看来,通常的答案远不能令人满意。
给定以下类层次结构:
class SuperClass{}
class SubClass extends SuperClass{}
为什么人们使用这种模式来实例化子类:
SuperClass instance = new SubClass();
而不是这个:
SubClass instance = new SubClass();
现在,我看到的通常答案是这是为了发送instance
作为需要 SuperClass 实例的方法的参数,如下所示:
void aFunction(SuperClass param){}
//somewhere else in the code...
...
aFunction(instance);
...
但我可以将 SubClass 的实例发送到 aFunction,无论保存它的变量类型如何!这意味着以下代码将编译并运行而不会出现错误(假设之前提供了 aFunction 的定义):
SubClass instance = new SubClass();
aFunction(instance);
事实上,据我所知,变量类型在运行时毫无意义。它们仅由编译器使用!
将变量定义为 SuperClass 的另一个可能原因是,如果它有几个不同的子类,并且该变量应该在运行时将其引用切换到其中的几个子类,但我只在类中看到这种情况(不是 super,不是 sub。只是上课)。绝对不足以需要一般模式......
这种类型编码的主要论点是因为里氏替换原则,其中指出如果X
是类型的子类型T
,那么任何实例T
应该可以换成X
.
这样做的好处很简单。假设我们有一个具有属性文件的程序,如下所示:
mode="Run"
你的程序看起来像这样:
public void Program
{
public Mode mode;
public static void main(String[] args)
{
mode = Config.getMode();
mode.run();
}
}
简而言之,该程序将使用配置文件来定义该程序启动的模式。Config
class, getMode()
可能看起来像这样:
public Mode getMode()
{
String type = getProperty("mode"); // Now equals "Run" in our example.
switch(type)
{
case "Run": return new RunMode();
case "Halt": return new HaltMode();
}
}
为什么这行不通?
现在,因为您有类型的引用Mode
,您只需更改程序的值即可完全更改程序的功能mode
财产。如果你有public RunMode mode
,您将无法使用此类功能。
为什么这是一件好事
这种模式非常流行,因为它开放了程序的可扩展性。这意味着,如果作者希望实现此类功能,则可以通过最少的更改来实现此类所需的功能。我的意思是,来吧。您更改配置文件中的一个单词并完全改变程序流程,而无需编辑一行代码。这是可取的。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)