Java 关于动态绑定的困惑

Java 关于动态绑定的困惑,java,Java,正如我从一本教科书中了解到的,如果我将一个超类类型的变量名,比如说newObject,分配给subclass类型的对象,并且该子类有一些重写的方法,比如methodtoString(),那么当我调用newObject.toString(),就会调用重写的方法,而不是原始方法 但在另一种情况下,我没有意识到这种情况再次发生。例如,我的超类名为Ship,其子类CruiseShip class Ship{} class CruiseShip extends Ship implements Seria

正如我从一本教科书中了解到的,如果我将一个超类类型的变量名,比如说
newObject
,分配给subclass类型的对象,并且该子类有一些重写的方法,比如method
toString()
,那么当我调用
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();