Java 关于动态绑定的困惑
正如我从一本教科书中了解到的,如果我将一个超类类型的变量名,比如说Java 关于动态绑定的困惑,java,Java,正如我从一本教科书中了解到的,如果我将一个超类类型的变量名,比如说newObject,分配给subclass类型的对象,并且该子类有一些重写的方法,比如methodtoString(),那么当我调用newObject.toString(),就会调用重写的方法,而不是原始方法 但在另一种情况下,我没有意识到这种情况再次发生。例如,我的超类名为Ship,其子类CruiseShip class Ship{} class CruiseShip extends Ship implements Seria
newObject
,分配给subclass类型的对象,并且该子类有一些重写的方法,比如methodtoString()
,那么当我调用newObject.toString()
,就会调用重写的方法,而不是原始方法
但在另一种情况下,我没有意识到这种情况再次发生。例如,我的超类名为Ship
,其子类CruiseShip
class Ship{}
class CruiseShip extends Ship implements Serializable {
int getSize() {
return 42;// value is not important now
}
}
我序列化了CruiseShip
的实例,然后反序列化它
CruiseShip cs = new CruiseShip();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(cs);
oos.close();
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(
baos.toByteArray()));
Object obj = ois.readObject();
ois.close();
现在返回对象的类型为object
,因此我将类型转换为Ship
,以便将其分配给变量名newShip
,其类型为Ship
Ship newShip = (Ship)obj;
问题是我不能调用类CuiseShip
的某个方法,说getSize()
未在超类Ship
中定义。只有在将对象强制转换为CruiseShip
时,我才能调用该方法
int size = ((CruiseShip)newShip).getSize();//OK
那么,这里发生了什么?我希望动态绑定允许我使用
newShip
调用方法getSize() 这是预期的行为
父母——比如希普——对他们的孩子一无所知。你可以有数千个不同的班级,它们都是船上的孩子 动态绑定的工作原理并非如此。如果该方法存在于超类中,并且在子类中被重写,则即使在对声明类型超类的对象调用时,如果该对象实际上是subclass类型的对象,也会调用subclass的方法。但是,如果该方法未在超类中定义,则无法从声明为该类型的对象调用该方法。否则就没有意义了——如果对象不是subclass类型,而只是superclass类型——那将是一个类型错误
如果您不能在超类中实现该方法,那么您要么没有执行动态绑定适用的示例,要么您的超类实际上应该是一个接口或抽象
例如:
class Animal
{
void Eat(){
System.out.println("Yum!");
}
}
class Dog extends Animal
{
void Eat(){
System.out.println("Arf!");
}
}
现在,如果你写信
Animal rex = new Dog();
rex.Eat();
输出将为“Arf!”
但是,如果您将类狗
更改为
class Dog extends Animal
{
void Eat(){
System.out.println("Arf!");
}
void Bark(){
System.out.println("Woof!");
}
}
写
Animal rex = new Dog();
rex.Bark();
您将收到一个错误-动物不能吠叫。事实上,如果rex是一条鱼,它真的没有意义。不要描述你的代码,而是发布真实的代码示例,再现你想要解决的问题。这里重要的不是代码,而是概念。正如我所说,我打字很容易。但我无法解释为什么动态绑定不适用于这里。我明白你想问的问题,但为了让你的问题更容易理解,让未来的读者更容易理解,最好包含代码示例,而不仅仅是代码描述。明白了。我将更新我的帖子。父类不知道它的子个体方法。就是这样。那么你如何解释第一种情况呢?newObject类的祖先是Object。对象具有名为toString()的方法,因此即使在newObject中也可以访问该方法。
Animal rex = new Dog();
rex.Bark();