Java多态性行为
我编写了一个代码,其中每个机器对象都有一个使用静态字段“id”自动生成的id。我试图理解JAVA中的多态性。预期的输出是1234,但我得到的输出是1246。有人能解释为什么会发生这种情况吗Java多态性行为,java,oop,polymorphism,Java,Oop,Polymorphism,我编写了一个代码,其中每个机器对象都有一个使用静态字段“id”自动生成的id。我试图理解JAVA中的多态性。预期的输出是1234,但我得到的输出是1246。有人能解释为什么会发生这种情况吗 class Machine{ static int id=1; private int mach_id; private String name; Machine(){ this.mach_id = id; id++; } pub
class Machine{
static int id=1;
private int mach_id;
private String name;
Machine(){
this.mach_id = id;
id++;
}
public int getId(){
return this.mach_id;
}
}
class Camera extends Machine {
private int mach_id;
Camera(){
this.mach_id = id;
id++;
}
}
public class App {
public static void main(String[] args){
Machine mach = new Machine();
Camera cam = new Camera();
Machine mach1 = new Camera();
Machine mach2 = new Camera();
System.out.println(mach.getId());
System.out.println(cam.getId());
System.out.println(mach1.getId());
System.out.println(mach2.getId());
}
}
请注意,
Camera
构造函数也调用Machine
构造函数。因此,每次创建Camera
对象时,将id
增加2–在Machine()
中增加一次,然后在Camera()
中增加一次。如果在机器
和摄影机
构造函数中添加一些输出,可能更容易理解
Camera() {
// the Machine() constructor will be called and executed HERE
this.mach_id = id;
id++;
}
我认为用面向对象的术语来考虑这一点是值得的,而不仅仅是作为构造器的机制——从长远来看,这将帮助您编写更多的代码 思考
扩展
关系的一个简单方法是as-as-A。换言之,您的代码表示摄像机
是机器
。因此,对机器
正确的任何东西对摄像机
都是正确的,并且只要需要机器
,您就可以随时使用摄像机
在你的例子中,你说的是一台机器
递增id
。您已经说过,摄像机
,以及做机器
所做的一切(因为它是机器
),都会增加id
。因此,这自然意味着两个增量,一个作为机器
,一个作为相机
两个构造函数都设置其id,然后递增。您的main
方法创建一台机器和三个摄像头。因此,ID将是:
机器id=1
+1,id=2
摄像机id=2
+2,id=4
摄像机id=4
+2,id=6
摄像机id=6
因此,正如Robin所说,输出1、2、4、6都是关于继承的,而不是多态性的 在Java中,在派生类构造函数中自动调用不带参数的基类构造函数。这很有道理 如果
Human
类具有walk
方法
然后从classStudent s=new Student()
它继承自Human
如果未调用Human
的构造函数,则对象s
无法调用未在内存中初始化的walk方法
因此,超级构造函数在派生类构造函数之前调用。下面是发生的情况:
Machine mach = new Machine();
直接调用机器
构造函数<代码>id当前为1
。因此它为新对象提供了1
的mach\u id
,并且id
是递增的
Camera cam = new Camera();
直接调用摄影机
构造函数
任何构造函数所做的第一件事就是调用超类的构造函数。如果没有显式地告诉它这样做,它将隐式地调用超类的no-arg构造函数。现在调用机器
构造函数
它将该对象的mach\u id
的值(将其视为机器
设置为id
的当前值,即2。然后将id
递增
现在,Camera
构造函数开始它自己的工作。它获取id
的当前值,当前为3
,将其放入mach\u id
,并增加id
。现在为4
现在是棘手的部分。Camera
中的mach\u id
正在机器中隐藏mach\u id
。但是方法getID()Machine
中的没有看到Camera
中定义的mach\u id
。它看到的是Machine
中的一个。因此,当调用它时,它从对supeclass构造函数的调用中获取值,该构造函数为2。它没有看到您在Camera
中创建的私有字段,也不知道它的值,而h是3
然后再次构造新的Camera
对象。将它们放入Machine
变量中,但这不会改变上述任何事实。调用的方法仍然来自超类方法。将id加倍,一次在Machine构造函数中,一次在Camera构造函数中SSE不需要mach_id字段,机器应该为其值提供一个getter。尝试将System.out.println添加到构造函数中,并查看工作流…好的。但我不理解的是,当我创建摄影机对象时,它不会增加2。即,当我创建摄影机cam=new Camera()它只增加了一个。所以当我使用new Camera()创建机器对象时实际上,我只是在调用摄影机构造函数。在这种情况下,为什么它会增加2。我知道我听起来可能很幼稚,但我是OOPs新手,所以请容忍我。谢谢。但我不明白的是,当我创建摄影机对象时,它不会增加2。也就是说,当我创建摄影机cam=new Camera()它只增加了一个。所以当我使用new Camera()创建机器对象时实际上,我只是在调用摄影机构造函数。在这种情况下,为什么它会增加2。我知道我可能听起来很幼稚,但我是OOPs新手,所以请容忍我。谢谢–伊山Bhatt@IshanBhatt我将在回答中解释您创建的对象取决于您调用的构造函数(即=运算符的右侧)。如果调用Camera()
构造函数,则始终会创建一个Camera
对象。=运算符的左侧是存储对象的唯一方法。因此,如果使用Machine=new Camera()
,你创建了一个摄像机
对象,但将其存储为一台机器
,显然是这样。是的,我得到了它。但问题是,当我创建一个摄像机对象Camera Camera=new Camera()时,它不会增加2。是的,它会增加。在设置了自己的摄像机后,它会增加2