假设我有一个由ParentClass继承的GrandParentClass,它由ChildClass继承。
为什么我只能“上链”而不是下来?
为什么我只能动态绑定“链中”但不能上传?
我正在寻找一些可以应用于这些问题而不仅仅是记住模式的推理。我真的希望这不仅仅是“那就是它的回答”。
施法示例:
ParentClass object = new ParentClass();
System.out.println((GrandParentClass)object); //casting ChildClass throws compiler error
动态绑定示例:
GrandParentClass = new ChildClass(); //Switching GrandParentClass with ChildClass throws run time error.
答案 0 :(得分:2)
可能很容易将其视为动物。假设祖父母类为Animal
,父类为Dog
,子类为GermanShepherd
。
你的第一个例子是这样的:
Dog dog = new Dog();
System.out.println((Animal)dog);
//casting GermanShepherd throws compiler error
狗可以永远是动物,但狗可能并不总是德国牧羊犬(它可能是一只贵宾犬)。
你的第二个例子:
Animal animal = new GermanShepherd();
//Switching Animal with GermanShepherd throws run time error.
同样地,德国牧羊犬将永远是动物,但动物可能不是德国牧羊犬(可能是乌龟)。
答案 1 :(得分:1)
这些转换规则(不仅仅是Java)的一般推理是继承允许您构建类的树,而不仅仅是列表。换句话说,并非GrandParentClass
类型的每个对象都必须是ParentClass
类型的对象,并且类型ParentClass
中的每个对象都不一定是ChildClass
类型的对象。您可以设想从ParentClass2
继承的替代GrandParentClass
,或者只是实例化GrandParentClass
类型的对象。想象一下,如果允许您访问GrandParentClass
对象,就好像它是一个ChildClass
对象,其中包含仅在ChildClass
但不在上面定义的所有方法和变量,会发生什么。没有有意义的解决方案。
因此,构建“向上链”总是有意义的,因为继承关系在编译时是已知的。你的动态绑定示例是一样的;您正在绑定“链上”(根本不是“链中”),因为您要将派生类型对象分配给它派生类型的引用。
答案 2 :(得分:0)
ParentClass的方法为getWidget
; ChildClass具有继承的方法getWidget
并声明了一个新方法getAnotherWidget
。这意味着当编译器发现您有一个ChildClass
对象时,它知道ChildClass
可以执行ParentClass
可以执行的所有操作,因此将ChildClass
视为一个安全的做法是安全的。 ParentClass
。但是,当编译器看到ParentClass
时,不知道ParentClass
有getAnotherWidget
方法 - 您可以在运行时确定(通过例如{ {1}}),或者在编译时你可以告诉编译器“这个ParentClass对象真的是一个ChildClass - 相信我,我知道我正在做什么”通过执行一次演员instanceof ChildClass
- 如果你错了然后你会得到一个ChildClass childClass = (ChildClass)parentClass
。即使ClassCastException
仅仅继承ChildClass
而不添加任何其他方法,您也需要执行此转换 - 编译器不够聪明,不知道ParentClass
基本上等同于{{1} }}
动态绑定只能以一种方式工作,因为ChildClass
不知道它的所有子节点 - 您可以在运行时加载其他继承类。相比之下,ParentClass
知道其ParentClass
是谁,因此它可以覆盖ChildClass
的方法。 (这就是为什么ParentClass
可以拨打ParentClass
,但ChildClass
无法拨打super.getWidget()
的原因 - 即使ParentClass
知道所有的孩子都是谁,怎么会知道你指的是哪个子类?如果你想使用它的方法而不是通过child.getWidget()
来调用它,那么Java要求你实例化一个ParentClass
对象,而不是让语法负担过重。 / p>
答案 3 :(得分:0)
动态绑定和铸造齐头并进。他们我理解它是ALWAYS
从右到左阅读,以弄清楚你是否可以绑定和演员......例如:
object A
←object B
是