9 java polymorphism inheritance casting type-conversion
我知道这个问题已被问到很多,但在我看来,通常的答案远非令人满意.
给定以下类层次结构:
class SuperClass{}
class SubClass extends SuperClass{}
Run Code Online (Sandbox Code Playgroud)
为什么人们使用这种模式来实例化SubClass:
SuperClass instance = new SubClass();
Run Code Online (Sandbox Code Playgroud)
而不是这一个:
SubClass instance = new SubClass();
Run Code Online (Sandbox Code Playgroud)
现在,我看到的通常答案是,这是为了instance作为参数发送到需要SuperClass实例的方法,如下所示:
void aFunction(SuperClass param){}
//somewhere else in the code...
...
aFunction(instance);
...
Run Code Online (Sandbox Code Playgroud)
但我可以将一个SubClass实例发送到aFunction,而不管它持有它的变量类型!意味着以下代码将编译并运行而没有错误(假设先前提供的aFunction定义):
SubClass instance = new SubClass();
aFunction(instance);
Run Code Online (Sandbox Code Playgroud)
实际上,AFAIK变量类型在运行时是没有意义的.它们仅由编译器使用!
将变量定义为SuperClass的另一个可能的原因是,如果它有几个不同的子类,并且该变量应该在运行时将它的引用切换为其中的几个,但我举例说,这只发生在类中(不是超级,而不是子类).只是上课).绝对不足以要求一般模式......
这种类型的编码的主要论据是因为Liskov Substituion Principle,它声明if X是类型的子类型T,那么任何实例都T应该能够被替换掉X.
这样做的好处很简单.假设我们有一个包含属性文件的程序,如下所示:
mode="Run"
Run Code Online (Sandbox Code Playgroud)
你的程序看起来像这样:
public void Program
{
public Mode mode;
public static void main(String[] args)
{
mode = Config.getMode();
mode.run();
}
}
Run Code Online (Sandbox Code Playgroud)
简而言之,这个程序将使用配置文件来定义该程序将要启动的模式.在Config类中,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();
}
}
Run Code Online (Sandbox Code Playgroud)
为什么这不起作用
现在,因为您有类型的引用,所以Mode只需更改mode属性的值即可完全更改程序的功能.如果有public RunMode mode,您将无法使用此类功能.
为什么这是一件好事
这种模式已经很好地发挥作用,因为它为可扩展性打开了程序.这意味着如果作者希望实现这种功能,那么这种类型的所需功能可以通过最少量的更改实现.我的意思是,来吧.您可以更改配置文件中的一个单词并完全更改程序流,而无需编辑任何一行代码.这是可取的.