Question on the polymorphism and casting of Java

综合编程 2017-12-31

I have a class C. Class E extends it.

E e = new E();
C c = new C();

Why is

e = (E) c;

Upon further review: though numeric conversions have the same syntax as casting objects, some confusion arose. At any event, the above does not give a compilation, but rather a runtime error - so a class can be casted to subclass in some instances (otherwise the code would not compile). Any examples that anyone can give where the above works?

And also:

K extends M

K k = new K();

((M) k).getClass()
gives K
. Why is that? It was casted to the more general M

Suppose I have a doIt() method implemented in both M and K. executing

((M) k).doIt();

gives M's or K's doIt()?


Consider a real-world example:

public class Dog extends Animal

All dogs are animals, but not all animals are dogs. Hence...

public class Cat extends Animal

Casting an Animal to a Dog can only be done if the Animal in question is indeed a Dog. Otherwise it would force the Universe to infer properties unique to a dog (wagging tail, barking, etc.) onto an Animal. That Animal might well be a Cat with properties unique to it (purring, rigorous regime of self-cleaning, etc.). If the cast is not possible then a ClassCastException is thrown at runtime.

Nobody wants a dog that purrs.

((M) k).getClass() gives K. Why is that? It was casted to the more general M!

You've casted k to M, but all classes have a getClass() method. k's class is always K, regardless of whather you cast its reference to M or not. If you cast a Dog to an Animal and ask it what animal it is it'll still answer that it's a dog.

In fact, casting to a superclass is redundant. A Dog already is an Animal and it has all the methods of an Animal as well as its own. Many Code Analysis tools such as FindBugs will notify you of redundant casts so you can remove them.

Suppose I have a doIt() method implemented in both M and K. executing
((M) k).doIt();
gives M's or K's doIt()?

K's doIt() for the same reasons as above. The cast operates on the reference; it doesn't transform an object to a different type.

Can you give an example of when casting (Dog doggy = (Dog) myAnimal) makes sense?

Sure can. Imagine a method that receives a list of animals for processing. All the dogs need to be taken for a walk, and all the cats need to be played with using a bird-shaped toy. To do this we call the takeForWalk()
method that only exists on Dog, or the play()
method which only exists on Cat.

public void amuseAnimals( List animals ) {
    for ( Animal animal : animals ) {
         if ( animal instanceof Dog ) {
             Dog doggy = (Dog)animal;
             doggy.takeForWalk( new WalkingRoute() );
         } else if ( animal instanceof Cat ) {
             Cat puss = (Cat)animal;
    new BirdShapedToy() );
Hello, buddy!

责编内容by:Hello, buddy! (源链)。感谢您的支持!


微博爬虫“免登录”技巧详解及Java实现... 一、微博一定要登录才能抓取? 目前,对于微博的爬虫,大部分是基于模拟微博账号登录的方式实现的,这种方式如果真的运营起来,实际上是一件非常头疼痛苦的事,你可能每天都过得提心吊胆,生怕新浪爸爸把你的那些账号给封了,而且现在随着实名制的落地,获得账号的渠道估计也会变得越来越少。 但是日子还得继续,...
Gnirehtet —— Android 反向网络连接工具 Gnirehtet 该项目通过 adb 为 Android 设备提供 reverse tethering(反向网络连接),允许设备在插入计算机后,使用计算机的网络而不用消耗自身的流量。适用于 GNU / Linux、Windows 和 Mac OS,无需任何 root 权限。 Gnireh...
Discussions in Java and Python i have few questions about threads in Python and Java... Is it possible to give priorities to Python threads, as it is in Java? How can I k...
Java引用类型:强引用、软引用、弱引用和虚引用... 介绍 在JDK 1.2以前的版本中,若一个对象不被任何变量引用,那么程序就无法再使用这个对象。也就是说,只有对象处于可触及(reachable)状态,程序才能使用它。从JDK 1.2版本开始,把对象的引用分为4种级别,从而使程序能更加灵活地控制对象的生命周期。这4种级别由高到低依次为:强引用、软...
Java之构造函数 Java的构造函数方便又很不同于其他语言(其实我也只学过python,==),这个构造函数需要好好的总结下,毕竟我觉得这是个奇怪的家伙,虽然它真的很方便== 一、特点 函数名与类名相同; 不用定义返回值类型; 没有具体的返回值; 构造函数具有重载的特点。 ...