关于Java多态和铸造的问题 [英] Question about Java polymorphism and casting

查看:153
本文介绍了关于Java多态和铸造的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个类C.类E扩展它。

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

为什么

  e =(E)c; 

进一步审查:虽然数字转换与转换对象具有相同的语法,但是出现了一些混乱。在任何情况下,上面没有给出编译,而是一个运行时错误 - 所以一个类可以在一些实例中转换为子类(否则代码不会编译)。



还可以:

  K extends M 

K k = new K();

((M)k).getClass()给出 K 。这是为什么?它被抛到更一般的 M



假设我有一个doIt K.执行

 ((M)k).doIt 

给予M或K的doIt()?



谢谢!

解决方案

考虑一个真实的例子:

  public class Dog extends Animal 

所有的狗都是动物,不是所有的动物都是狗。因此...

  public class Cat extends Animal 

只有当所讨论的动物确实是狗时,才能将动物投射到狗。否则,它会迫使宇宙推断一个狗特有的属性(摇尾巴,吠叫等)到一个动物。该动物可能是一个具有独特属性的猫(purring,严格的自我清洗的制度,等等)。如果不能执行强制转换,那么在运行时会抛出ClassCastException异常。



没有人想要一个可以转换的狗。


((M)k).getClass()给出K.为什么?它被转换为更一般的M!


你将k转换为M,但是所有类都有一个getClass()方法。 k的类总是K,不管你把它的引用M。如果你把狗放到动物身上,问它是什么动物,它仍然会回答这是一只狗。



事实上,转换成超类是多余的。狗已经是一个动物,它有动物的所有方法,以及它自己的。许多代码分析工具(如FindBugs)会通知您多余的投射,因此您可以删除它们。







((M)k).doIt();

$ b

假设我有一个在M和K中实现的doIt
$ b

给出M的或K的doIt()?


K的doIt 。铸造操作在参考;它不会将对象转换为不同的类型。







(狗狗=(狗)myAnimal)有意义吗?


当然可以。想象一个方法,接收动物的列表进行处理。所有的狗需要被带走散步,所有的猫需要玩一个鸟形玩具。为此,我们调用仅存在于Dog上的 takeForWalk()方法,或者只有 play()存在于Cat。

  public void amuseAnimals(List< Animal> animals){
for(Animal animal:animals) {
if(animal instanceof Dog){
狗狗=(狗)动物;
doggy.takeForWalk(new WalkingRoute());
} else if(Animal instanceof Cat){
猫猫=(猫)动物;
puss.play(new BirdShapedToy());
}
}
}


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()?

Thanks!

解决方案

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<Animal> 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;
             puss.play( new BirdShapedToy() );
         }
     }
}

这篇关于关于Java多态和铸造的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆