我对构建对象类型有点困惑.鉴于以下示例:
public class Test() { public void method1() { System.out.println("Method 1"); public void method2() { System.out.println("Method 2"); } public class Test1() extends Test{ @Override public void method1() { System.out.println("Method 11"); @Override public void method2() { System.out.println("Method 22"); public void method 3() { System.out.println("Method 3"); public static void main(String[] args) { Test a = new Test1(); a.method1(); //method invokes the overridden method1() of Test1, not Test the superclass a.method2(); //method invokes the overridden method2() of Test1, not Test the superclass a.method3(); //error, must cast == ((Test1)a).method3(); } }
我很困惑的是,当我调用method1和method2时,编译器或JVM能够调用派生或子类的方法,那么为什么还需要下调/转换来调用method3()?
我尝试重载超类的method1和method2而不是覆盖它; 在允许您调用重载方法之前,编译器/ JVM将要求您向下转换对象引用变量.那么,这意味着如果没有向下转换,您只能调用超类的方法以及子类中定义的重写方法?
您的引用a
属于类型Test
,但method3
不存在Test
.
Test a = new Test1(); // ^-reference ^-object // type type
规则:
引用类型告诉我们可见的方法.
对象类型告诉我们可以考虑哪些可见方法的实现.
public class Animal { public void speak() { System.out.println("BLARGHGH"); } } public class Dog extends Animal { @Override public void speak() { System.out.println("Woof"); } } public class Cat extends Animal { @Override public void speak() { System.out.println("Meow"); } public void throwUpFurball() { System.out.println("So fluffy!"); } } public class Test() { public static void main(final String args[]) { Animal animal1 = new Animal(); animal1.speak(); // BLARGHGH animal1.throwUpFurball(); // Compilation error - method not found. It will ask for casting Animal animal2 = new Cat(); animal2.speak(); // Meow ((Cat)animal2).throwUpFurball(); // Must be cast, because throwUpFurball does not exist in Animal Animal animal3 = new Dog(); animal3.speak(); // Woof ((Cat)animal3).throwUpFurball(); // Compiles, but throws ClassCastException at runtime, because the object type of animal3 is Dog Cat animal4 = new Cat(); animal4.speak(); // Meow animal4.throwUpFurball(); // No casting necessary, because animal4 is of type Cat Object animal5 = new Animal(); animal5.speak(); // Again, compilation problem. The type Object does not contain the speak() API, so it will require casting. } }