我刚开始从Java的头开始学习面向对象的编程,它说多态使我能够创建超类类型的数组,然后将所有子类作为数组元素,但是当我尝试编写代码时使用相同的原理,它会出错
error: cannot find symbol
我将类设为动物的超类,而狗类使用自己的获取方法扩展了动物类,但是当我将dog变量引用为动物时,代码在这里不起作用
动物课
public class animal{
String family;
String name;
public void eat()
{
System.out.println("Ghap Ghap");
}
public void roam()
{
System.out.println("paw paw");
}
}
狗类
public class dog extends animal{
public void fetch(){
System.out.println("Auoooooooo");
}
}
测试人员课程
public class tester{
public static void main(String args[]){
animal doggie = new dog();
doggie.fetch();
doggie.eat();
doggie.roam();
}
}
错误
tester.java:4: error: cannot find symbol
doggie.fetch();
^
symbol: method fetch()
location: variable doggie of type animal
1 error
答案 0 :(得分:6)
使用多态时,如果创建子类的实例并将其引用存储在超类类型的变量中,则您只能在存在的新创建实例上调用那些方法 。
在代码中,您创建了dog
类的实例,并将其引用存储在doggie
类型(dog的超类)的animal
中,在这种情况下,您可以不要在dog
类实例中调用animal
类实例上的任何方法。
fetch
方法未在animal
类中定义,因此会出现错误。
解决方案
在fetch
类中定义animal
方法
OR
更改
animal doggie = new dog();
到
dog doggie = new dog();
答案 1 :(得分:2)
您引用的是doggie.fetch()
,但这不是动物定义的方法。
由于您将doggie
对象用作动物,因此不能使用此方法。
如果您想使用此方法,则可以执行类似实例检查的操作:
if(doggie instanceOf dog){
((dog)doggie).fetch();
}
答案 2 :(得分:2)
由于fetch()方法在动物中不存在,因此会引发错误。 您可以在动物中定义提取方法,并在狗类中覆盖它。
答案 3 :(得分:1)
如果你真的想了解这个概念的深度,你应该了解Liskov Substitution Principle,简要描述如下:
<块引用>在计算机程序中,如果 S 是 T 的子类型,则类型 T 的对象可以替换为类型 S 的对象(即,类型 T 的对象可以替换为子类型 S 的任何对象),而无需更改程序所需的任何属性。
这个概念背后的核心思想是不破坏与父类型“签署”的契约(即扩展类或实现接口)。
如果您能够调用存储在其父类型中的引用的子类型中可用的任何方法,而忽略子类型与其超类型之间的约定,则您可能会遇到意外故障 - 运行时异常,更准确。
最后但并非最不重要的一点:请遵循 Java naming conventions 并使用 Pascal Case 约定命名您的类。这很重要。