Java 为什么我能够访问父类中的子方法?
我在理解Java中的继承时遇到了一个问题:当我将子类转换回父类时,我能够访问子类的重写方法 例如,给出了以下两类: 父对象:Java 为什么我能够访问父类中的子方法?,java,inheritance,Java,Inheritance,我在理解Java中的继承时遇到了一个问题:当我将子类转换回父类时,我能够访问子类的重写方法 例如,给出了以下两类: 父对象: public class Parent { public void whatAreYou() { System.out.println("parent"); } } public class Child extends Parent { @Override public void whatAreYou() {
public class Parent {
public void whatAreYou() {
System.out.println("parent");
}
}
public class Child extends Parent {
@Override
public void whatAreYou() {
System.out.println("child");
}
public void onlyChildrenCanDoThis() {
//...
}
}
Child c = new Child();
Parent p = c;
p.whatAreYou();
child
和子类:
public class Parent {
public void whatAreYou() {
System.out.println("parent");
}
}
public class Child extends Parent {
@Override
public void whatAreYou() {
System.out.println("child");
}
public void onlyChildrenCanDoThis() {
//...
}
}
Child c = new Child();
Parent p = c;
p.whatAreYou();
child
当我现在执行以下操作时:
public class Parent {
public void whatAreYou() {
System.out.println("parent");
}
}
public class Child extends Parent {
@Override
public void whatAreYou() {
System.out.println("child");
}
public void onlyChildrenCanDoThis() {
//...
}
}
Child c = new Child();
Parent p = c;
p.whatAreYou();
child
我得到这个输出:
public class Parent {
public void whatAreYou() {
System.out.println("parent");
}
}
public class Child extends Parent {
@Override
public void whatAreYou() {
System.out.println("child");
}
public void onlyChildrenCanDoThis() {
//...
}
}
Child c = new Child();
Parent p = c;
p.whatAreYou();
child
这对于我理解Java中的继承是非常奇怪的。我希望得到一个parent
输出,因为我将子类缩小到父类,这样我就可以访问父类的变量和方法
这是使用p.onlyChildrenCanDoThis()
,因为我无法访问它,因为它没有在父类中实现
…但是对于被覆盖的方法,Java不会这样做这是为什么?由于行
父级p=c,输出保持原样代码>
想象一下:
class Car {
public void whatAreYou() {
System.out.println("Car");
}
}
class Cadillac extends Car {
public void whatAreYou() {
System.out.println("Caddillac");
}
}
如果你现在说
Cadillac coolCar = new Cadillac();
Car testCar = coolCar;
testCar.whatAreYou();
很明显,输出是“凯迪拉克”,不是吗?以下是您看待继承的方式:
凯迪拉克的物体总是汽车。汽车对象可以是凯迪拉克
由于我显式地将凯迪拉克参考coolCar
设置为指向凯迪拉克的一个对象,并且将汽车参考testCar
设置为指向同一个对象,因此我们得到了输出“凯迪拉克”
更明显的是,你甚至可以说
Car coolCar = new Cadillac();
Car testCar = coolCar;
testCar.whatAreYou();
由于行parent p=c,输出保持原样代码>
想象一下:
class Car {
public void whatAreYou() {
System.out.println("Car");
}
}
class Cadillac extends Car {
public void whatAreYou() {
System.out.println("Caddillac");
}
}
如果你现在说
Cadillac coolCar = new Cadillac();
Car testCar = coolCar;
testCar.whatAreYou();
很明显,输出是“凯迪拉克”,不是吗?以下是您看待继承的方式:
凯迪拉克的物体总是汽车。汽车对象可以是凯迪拉克
由于我显式地将凯迪拉克参考coolCar
设置为指向凯迪拉克的一个对象,并且将汽车参考testCar
设置为指向同一个对象,因此我们得到了输出“凯迪拉克”
更明显的是,你甚至可以说
Car coolCar = new Cadillac();
Car testCar = coolCar;
testCar.whatAreYou();
你现在要处理的是c
被实例化为new child()
,这就是为什么将child
作为输出。p
属于parent
类型的事实并没有改变这一事实,它仍然指向child
的实例c
被实例化为new child()
,这就是为什么将child
作为输出。p
属于parent
类型的事实并没有改变这一事实,它仍然指向child
的实例
child c=新的child()
您创建了子类的对象并将其引用指定给c
父母p=c
在这里,您已将子对象的引用复制到p。请记住,对象仍然是子对象而不是父对象
p、 whatAreYou()
这里你称之为whatAreYou方法。您正在使用指向子对象的引用变量p调用此函数。因此将调用child的方法。
另一种解释
以下是您所做的
child c=新的child()
您创建了子类的对象并将其引用指定给c
父母p=c
在这里,您已将子对象的引用复制到p。请记住,对象仍然是子对象而不是父对象
p、 whatAreYou()
这里你称之为whatAreYou方法。您正在使用指向子对象的引用变量p调用此函数。因此将调用child的方法。
另一种解释
而不是Car.whatAreYou()你的意思是什么代码>?我不会称之为“明显的”,因为汽车
当然“仍然”是凯迪拉克
,但是汽车
对象不能使用任何凯迪拉克
变量和方法。或者举个例子:根据您的解释,家长应该仍然能够调用p.onlyChildrenCanDoThis()
,因为(正如您所说)“p
仍然是child
”。@Robert您可以访问的方法是通过引用的类型定义的,在我的例子中,testCar
被定义为Car
。如果实际对象属于子类,并且该子类重写了任何方法,则可以访问这些方法,但不能访问引用类型(在本例中也是Car
)中未定义的其他方法,而不是Car.whatAreYou()你的意思是什么代码>?我不会称之为“明显的”,因为汽车
当然“仍然”是凯迪拉克
,但是汽车
对象不能使用任何凯迪拉克
变量和方法。或者举个例子:根据您的解释,家长应该仍然能够调用p.onlyChildrenCanDoThis()
,因为(正如您所说)“p
仍然是child
”。@Robert您可以访问的方法是通过引用的类型定义的,在我的例子中,testCar
被定义为Car
。如果实际对象属于某个子类,并且该子类重写了任何方法,则您可以访问这些方法,但不能访问引用类型中未定义的其他方法(在本例中,也是Car
)简短回答:非静态方法在运行时调度。否则无法使用方法重写。简短回答:非静态方法在运行时调度。否则,您不能使用任何方法重写。但是根据您的解释,我仍然可以调用p.onlyChildrenCanDoThis()
,因为p
只是对c
的引用……不,您不能,因为p是父对象的引用变量,它不包含唯一的childrencandoth