我正准备参加SCJP,看起来我不懂班级原则。
class Dog extends Animal
创建Dog()
实例的第一种方法 - 制作Animal的实例并将其转换为Dog(upcast):
Animal a = new Dog();
Dog d1 = (Dog)a;
VS
创建Dog()
实例的第二种方式 - 直接创建:
Dog d2 = new Dog();
这种情况下d1
和d2
对象有什么区别?
答案 0 :(得分:3)
在a
到Dog
的演员之后,d1
和d2
之间没有区别。演员阵容可能存在问题。如果a
实际上不是Dog
,那么您将在运行时获得ClassCastException
。因此,最好使用instanceof
验证运行时类型:
Animal a = new Dog();
Dog d1 = null;
if(a instanceof Dog)
{
d1 = (Dog)a;
}
真正的问题是,如果您需要Dog
,请将变量声明为Dog
,而不是Animal
。如果您正在使用任何类型的Animal
,请使用基类。
变量的类型仅指定要使用的接口 - 无论是基类提供的接口,某个类的实现还是实际的interface
。变量的类型不指示其运行时类型。
答案 1 :(得分:2)
Animal a = new Dog();// a dog is created but it will be referred by reference of animal as dog is an animal
Dog d1 = (Dog)a;//now we know that this animal is Dog so we are casting it to dog.
Dog d2 = new Dog();// we are creating instance of dog which is referred by reference of Dog
这种情况下d1和d2对象有什么区别?
d1
和d2
只是对狗的引用,两者最终都会引用Dog的一个实例。
没有区别
另见
答案 2 :(得分:2)
第一种方式是多态的,因为动物可以是狗,猫,大象等......而后者则不是。否则,2之间没有太大区别。
答案 3 :(得分:1)
这些片段之间的实例化没有区别:在这两种情况下,您都可以使用Dog
实例化new Dog()
类型的对象。实际上,它是关于对象类型(运行时类型)和变量类型(静态类型)之间的区别。
但是在第一种情况下,您将对该对象的引用分配给Animal
类型的变量,然后将该变量的值赋给另一个类型为Dog
的变量。这需要强制转换,因为Animal
类型的变量可能包含对Dog
以外类型的对象的引用,但在您的情况下,它引用类型Dog
的对象,以便强制转换成功。
在第二种情况下,您可以直接为Dog
类型的变量指定类型Dog
的值。