Question about Java polymorphism and casting

后端 未结 9 2269
谎友^
谎友^ 2020-12-29 12:02

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

相关标签:
9条回答
  • 2020-12-29 12:36

    Just because E extends C, C doesn't become an E... E on the other hand is a C

    Edit: To expand Mark's comment below... Just because every woman is a human, not all humans are women. All humans share the "human interface" with legs, hands, faces, etc. Women extends it with functionality that returns good feelings when you provide diamonds and gold.

    The int => double conversion is not even related as it is not a class cast but a conversion telling the compiler to store whatever is in x in y (which happens to be a double).

    ((M) k).getClass() gives K.

    because k is still a K even if you cast it to an M or an Object (or something else it happens to be).

    Edit: I think the confusion here is because you consider k to "become" an M when you cast it, it doesn't. You are just treating it as an M. If you ask someone who is a "dog owner" what kind of breed it is he will not return "It's a dog", the reason is simply that the getBreedName() method is likely to have been overridden in the subclass LabradorOwner to return "Labrador". It is the same with getClass(), it will return the class of the implementation. It will not be an M but a K that happens to be an M as well just because K extends M.

    0 讨论(0)
  • 2020-12-29 12:36

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

    A useful analogy (that I got from Bill Venners' site artima.com) that may help clear the confusion is that the difference between classes and objects is like the difference between an architect's blueprint and the actual house that is built. The blueprint exists on paper and is a concept, while the house exists in real life. You can have more than one house built to the same blueprint.

    How is that relevant to this question? Let's say there's a McMansion blueprint and a McMansionWithHeatedPool blueprint. A McMansionWithHeatedPool is an extension of a McMansion with a heated pool.

    Now, if you see a real McMansionWithHeatedPool, for that object:

    1. Conceptually (i.e., if you look at the architect's blueprints), you would see that a McMansionWithHeatedPool is clearly also a McMansion. Hence the upcast is allowed. (For the same reason, a McMansion object cannot be type cast into a McMansionWithHeatedPool : no heated pool!)

    2. ((McMansion) k).getClass() gives McMansionWithHeatedPool because k is still a McMansionWithHeatedPool. The type cast is on the expression, not on the object.

    0 讨论(0)
  • 2020-12-29 12:37

    For the first question, you cannot cast a superclass to a subclass because a subclass adds members that the superclass doesn't have. How is the compiler supposed to know what values to put there when it's casting? Basically, an E is a C, but a C is not an E.

    getClass() gets the type of the object in memory. Casting to M simply hides the fact that it's a K, it doesn't change the underlying object.

    0 讨论(0)
提交回复
热议问题