与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()

empl1empl2都是Manager对象。 不同之处在于如何在方法的其余部分中使用变量。

您已声明empl1可以是Employee ,也可以是Employee的子类(包括Manager )的任何对象。 无论empl1在程序中使用empl1 ,编译器都不会知道它实际上是一个Manager ,只是它是某种Employee 。 因此,如果ManagerEmployee没有的任何新方法,则不能在empl1上使用它们。 但是,您可以将empl1重新分配给任何其他Employee ,以便稍后您可以说出类似的内容

 empl1 = new Employee(...some data...); empl1 = new Intern(...some data...); empl1 = new Accountant(...some data...); 

等等。 你不能用empl2做到这一点, empl2仅限于一个Manager (或任何Manager子类,如果有的话)。

在您的示例中, empl1empl2都是可以为其分配对象的变量empl1变量可以包含任何类型的Employee对象,但empl2变量只能包含Manager对象。 由于Manager是一种Employee ,您可以将Manager对象放入Employee变量中。 new调用告诉Java创建指定类型的新对象。

变量名称前面的类型称为声明类型 ,此类型定义了其余代码可用的接口(API)。 例如,您可以在empl1empl2上调用(假设的) getEmployeeId()方法,但是您只能在getManagerLevel()上调用getManagerLevel()方法。

放入变量的实际对象的类型(在这两种情况下为Manager )称为运行时类型 ,它可以是扩展或实现声明类型的任何类型。 JVM负责将变量上的路由方法调用转换为运行时类型的正确代码。

当您使用Super类类型的对象引用基类时,该对象只能访问基类的重写方法,或者只能访问这两个类共有的方法…引用基类对象使用超类是我们所谓的java中的虚方法调用…