无法使用以下行从子类访问方法,
Parent p = new Child(); p.print();
假设我在Child类中有一个方法print()
,而在Parent类中有一个否的方法。在这种情况下,我们无法使用上述代码行访问子类方法print()
。但是请注意,如果父类中具有相同的方法print()
,则可以使用上面的代码访问它。
在现实生活中可能不会出现这样的情况,但是如果我们没有在父级中定义相同的方法,则试图理解为什么我无法使用类型为Parent的子对象访问子类print()
课。
示例代码如下:
public class Main {
public static void main(String[] args)
{
Parent p = new Child();
p.print(); //Compiler throws an error saying "cannot resolve print method".
}
}
class Parent {
int x = 10;
}
class Child extends Parent {
void print(){
System.out.println("Child");
}
int x = 20;
}
更多说明-如果我在父类中定义print()
方法,则可以使用类型为Parent的对象访问子类print()
方法。因此,我假设我们不能说父类型的对象只能访问父类内部定义的成员/方法。
另外,我知道我们可以通过将父类型强制转换为子类型来访问子方法。我想知道为什么我们不能在不进行强制转换的情况下访问子类方法,并且如果不在父类中定义相同的方法。
我已经编辑了问题,以确保它与另一个问题-https://getbootstrap.com/docs/4.1/components/popovers/#four-directions
没有关系答案 0 :(得分:1)
如果父级未声明方法(作为具体方法或抽象方法),则子级在父变量内部实例化时将无法使用该方法。您可以使用以下代码示例来使用它
Parent p = new Child();
if(p instanceof Child){
((Child) p).print();
}
其背后的解释是变量p在运行时实际上并不知道哪个子实例存储在其中(可能有多个子实例,只有一个拥有print()
方法,也许您会在编译时知道Parent p
中存储的对象的实际类型,但是执行是另一个世界,因此,如果p对象是Child的实例,则意味着p被键入为Child或以下类型之一子对象,则可以将其转换为((Child) p)
,所有方法都将被识别为子对象(因为是)。
请注意,您可以强制转换一个不具有Casteable的类,并且将具有ClassCastException。在这个具体示例中,不需要写if
语句,因为我们可以确定p类型,但是在运行时有时会变得混乱,并且我们不知道存储在什么位置,因此确保了您的健康铸件变得至关重要。说到转换变量,如果您只希望Child类访问方法print而不是其子类,则可以使用
Parent p = new Child();
if(p.getClass() == Child.class){
((Child) p).print();
}
如果您不想强制转换子代,并且您的父类适合打印方法(并非始终是一个选项),那么您可以在父级中将其声明为具体方法,并在其中覆盖该方法孩子)
class Parent {
int x = 10;
void print(){
System.out.println("Parent");
}
}
或者您可以在父对象中将该方法声明为抽象方法,并且所有子代方法都必须实现该方法,但是,如果必须是抽象方法,则您将无法创建父对象。
abstract class Parent {
int x = 10;
abstract void print();
}
继续,如果父母有孩子,则孩子将拥有父母的所有方法,但只要父母有,孩子的任何方法都不会。将需要铸造。如果在子级和父级中都写入了print方法,则最低的改写方法将是执行的一种(本例中的子级)。另外,您可以使用在父级中使用“ super”实现的方法(与构造函数相同)
class Child extends Parent {
void print(){
super.print("Child");
}
int x = 20;
}
答案 1 :(得分:0)
Parent p = new Child();
您正在创建带有子类的Parent对象。因此,父对象p没有方法print()很简单。但是Child对象具有方法print(),因此,如果创建Child对象,则可以从Child类访问方法print()。
在这里,方法的优先级开始发挥作用。如果两个类都具有print()方法,则子类方法优先于父类方法。
注意:继承是单向的,而不是双向的。