与Javainheritance混淆
我目前正在通过AP CS考试学习指南,我已经了解了最新情况。 假设我有一个名为Employee的类,我有另一个inheritanceEmployee的类叫做Manager。 以下声明之间有区别吗?
Employee empl1 = new Manager(); Manager empl2 = new Manager();
我基本上混淆了对象名称之前的术语是什么,以及它与新术语之后的术语有何不同。 任何帮助表示赞赏。
名称前面的部分是您正在创建的对象的引用类型 。 在右侧,在new
,您将调用一个特定类的构造函数(在您的示例中为类Manager
)。
你可以写
Employee empl1 = new Manager(); Employee empl2 = new Consultant(); Employee empl3 = new Officer(); Employee empl4 = new Secretary();
因为您在那里创建的所有对象都是Employees 。 但是,你不能写
Manager manager = new Secretary();
因为秘书不是经理。
引用的类型(即名称前面的术语)确定您可以使用此引用调用哪些方法 。 例如,你可以写
Manager manager = new Manager(); manager.doSomethingThatOnlyManagersCanDo();
但你不能写
Employee employee = new Manager(); emplyoee.doSomethingThatOnlyManagersCanDo();
因为你只知道对象是一个雇员,但那不是经理。 (它是一名经理,但你不知道,因为该参考只告诉你它是一名雇员)
左侧的表单是“接口”,inheritance允许您将Manager
用作Employee
因为Manager
是一个 Employee
。 不同之处在于Manager Manager上调用的方法首先来自Manager
,然后从Employee
“inheritance”行为。 另一个区别是你调用了getClass().getName()
。 考虑到每个Java Object都inheritance自java.lang.Object ,这就是为什么你可以在任何Object上调用toString()
或equals()
。
empl1
和empl2
都是Manager
对象。 不同之处在于如何在方法的其余部分中使用变量。
您已声明empl1
可以是Employee
,也可以是Employee
的子类(包括Manager
)的任何对象。 无论empl1
在程序中使用empl1
,编译器都不会知道它实际上是一个Manager
,只是它是某种Employee
。 因此,如果Manager
有Employee
没有的任何新方法,则不能在empl1
上使用它们。 但是,您可以将empl1
重新分配给任何其他Employee
,以便稍后您可以说出类似的内容
empl1 = new Employee(...some data...); empl1 = new Intern(...some data...); empl1 = new Accountant(...some data...);
等等。 你不能用empl2
做到这一点, empl2
仅限于一个Manager
(或任何Manager
子类,如果有的话)。
在您的示例中, empl1
和empl2
都是可以为其分配对象的变量 。 empl1
变量可以包含任何类型的Employee
对象,但empl2
变量只能包含Manager
对象。 由于Manager
是一种Employee
,您可以将Manager
对象放入Employee
变量中。 new
调用告诉Java创建指定类型的新对象。
变量名称前面的类型称为声明类型 ,此类型定义了其余代码可用的接口(API)。 例如,您可以在empl1
或empl2
上调用(假设的) getEmployeeId()
方法,但是您只能在getManagerLevel()
上调用getManagerLevel()
方法。
放入变量的实际对象的类型(在这两种情况下为Manager
)称为运行时类型 ,它可以是扩展或实现声明类型的任何类型。 JVM负责将变量上的路由方法调用转换为运行时类型的正确代码。
当您使用Super类类型的对象引用基类时,该对象只能访问基类的重写方法,或者只能访问这两个类共有的方法…引用基类对象使用超类是我们所谓的java中的虚方法调用…