我遇到了一些代码,虽然我做了一些广泛的搜索,却无法理解它的某个方面!
我的问题是:为什么类有时会在括号中声明,如下面的代码所示?
public class Animal {
public static void hide() {
System.out.println("The hide method in Animal.");
}
public void override() {
System.out.println("The override method in Animal.");
}
}
public class Cat extends Animal {
public static void hide() {
System.out.println("The hide method in Cat.");
}
public void override() {
System.out.println("The override method in Cat.");
}
public static void main(String[] args) {
Cat myCat = new Cat();
Animal myAnimal = (Animal)myCat;
myAnimal.hide();
myAnimal.override();
}
}
我特别关注这一行代码:
Animal myAnimal = (Animal)myCat;
我认为它与一个类扩展另一个类的事实有关,但我不确定括号中定义的类是什么意思。
对此有任何帮助表示赞赏。提前谢谢。
答案 0 :(得分:10)
您所看到的是一个演员,告诉编译器可以将Cat分配给Animal。
强制转换适用于编译器无法安全地将一种类型转换为另一种类型的情况,因为它不知道所涉及的类型是什么,或者因为转换会丢失信息(例如,如果你有一个双你想存储在float类型的变量中。
在你的例子中,演员是完全没必要的,因为Cat扩展了Animal;由于所有Cats都是Animal,编译器不需要显式强制转换来告诉它可以将Cat分配给Animal。
铸造应保留用于特殊场合。如果你经常使用显式的强制转换,那么这可能意味着你没有从类型系统中获得最大的好处。
答案 1 :(得分:7)
这是一个演员表 - myCat
变量类型Cat
正在转换为基类Animal
。
这意味着它可以被视为Animal
。
这是Java中inheritance的基本功能。
作为@Sebastian Koppehel commented,在这种情况下不需要强制转换 - myAnimal
变量(类型Animal
)可以接受任何实现{{1}的类型}。
答案 2 :(得分:1)
即使代码生成正确的输出,如果必须将对象强制转换为父类,然后调用父类的静态方法,则可能需要以更好的方式设计类。 Java中的继承应该提供对常用方法和字段的访问。如果需要在Parent类中编写静态方法并使用子类的对象调用它,则父类和子类之间的关系不明确。
答案 3 :(得分:0)
您明确保证编译器/运行时您传递的cat引用类型是Animal的类型。在java中,它被称为强制转换。
虽然运行时如果不遵守此合同(这意味着cat和Animal之间没有定义任何关系),您将获得ClassCastException
。