因为即使Integer
是一个Object
,Object
也不是一个Integer
,因此它没有Integer
' 方法,只有Object
'。
引用的类型,而不是引用的对象的类型,决定了可以执行的操作。
这意味着即使被引用的对象包含更多功能,如果引用的类型与对象的类型不同,那么只有引用类型的功能可用。
在下面的:
Object aThing = new Integer(25);
的类型aThing
被声明为Object
。即使实现包含更多内容,但实现包含的任何其他内容都不再可见,因为变量的类型不是Integer
,而是Object
。两者Object
和Integer
有共同的方法,但从现在开始你只能访问由提供的方法Object
,因为除了你之外没有人知道这真的是一个Integer
,而不仅仅是一个Object
。
在第二个示例中,它们意味着即使两者Object
都有Integer
共同的方法,但当您调用其中一个方法时,将调用实际类型的方法。所以在这种情况下,如果你调用toString()
on aThing
,你会调用Integer
'stoString()
方法,而不是Object
's。因此,这只是一个访问问题。将其声明为 an 的Object
事实并不意味着您将获得Object
' 的方法来响应调用,它仅意味着存在Integer
和不存在的任何方法都Object
将不可用。
例子:
class Computer {
public int getInstalledOperatingSystems() { return 3; }
}
class Desktop extends Computer {
public String getShapeOfCase() { ... }
}
class Notebook extends Computer {
public int getInstalledOperatingSystems() { return 1; }
public String getBrand() { ... }
public void closeLid() { ... }
}
现在让我们创建一个Notebook
:
Notebook n = new Notebook();
假设您有以下方法:
public String showStatistics(Computer computer) {
result = "Operating systems: " + computer.getInstalledOperatingSystems();
return result;
}
如果您使用Notebook
上面定义的方法调用此方法:
showStatistics(n);
然后该方法将收到Notebook
,因为 aNotebook
是 a Computer
。它可以调用Notebook
'getInstalledOperatingSystems()
方法,因为任何人Computer
都有该方法。当它调用它时,它会收到1
结果,因为Notebook
overridesComputer
的实现。但是showStatistics()
将无法调用Notebook
提供的任何其他方法,因为它不知道它正在传递一个Notebook
. 尽管它关心的是,它有 a Computer
,并且它不知道 aComputer
没有的任何其他方法。
您可以很好地发送它Desktop
,或者明天您将创建一个GamingComputer
扩展Desktop
或扩展的Server
类Computer
。你也可以发送那个。但showStatistics()
将无法访问任何Server
特定的、专门的方法,因为showStatistics()
不知道它正在查看Server
. 它甚至在showStatistics()
编写时都没有被发明。
这与即使 aServer
总是 a Computer
, aComputer
并不总是 a的陈述是一致的Server
。
你可以检查一下。因此,如果您知道您可能会传入 a Notebook
,而不仅仅是一台计算机,您可以查找它,甚至可以调用Notebook
's 方法,但您必须确保您正在查看 a Notebook
:
if (computer instanceof Notebook) {
// this is definitely a Notebook, so you can assure the compiler
// of that explicitly, by using a cast
Notebook notebook = (Notebook) computer;
result += "This isn't just a generic computer, it's actually a notebook! ";
// now that you have a variable of type Notebook, you can call
// whatever Notebook provides
result += "It's produced by: " + notebook.getBrand();
}