如果我有一个名为Dog的抽象类,其构造函数设置其权重(double)和一个名为SpecialDog的类,它扩展了Dog并且有一个接受double的构造函数并将其传递给Dog使用超级()。
以下是什么(如果有的话):
Dog dog = new SpecialDog(12.0);
SpecialDog dog = new SpecialDog(12.0);
Dog dog = new Dog(12.0);
SpecialDog dog = new Dog(12.0);
谢谢!
答案 0 :(得分:5)
回答你的问题(它们各不相同):
Dog dog = new SpecialDog(12.0);
在这里,您正在创建一个SpecialDog,但使用Dog引用指向它。对象 是一只特殊的狗,但是,除非你向下转换dog
变量,否则你只能将dog
视为Dog
而不是SpecialDog
。
SpecialDog dog = new SpecialDog(12.0);
在这里,您正在创建一个SpecialDog,并使用SpecialDog引用指向它。
Dog dog = new Dog(12.0);
这是一个编译器错误,因为您无法实例化抽象类。
SpecialDog dog = new Dog(12.0);
这只是一个编译器错误。您不能将超类指定给子类引用。请记住:继承是“is-a”关系。虽然 SpecialDog 始终是 Dog ,但 Dog 可能并非总是 SpecialDog 。
答案 1 :(得分:3)
如果您的Dog
课程抽象,那么
Dog dog = new Dog(12.0);
SpecialDog dog = new Dog(12.0);
不会编译。
回答评论中的问题:
如果您使用Dog
变量,则只能使用Dog
类的方法。
如果在这种情况下尝试使用SpecialDog
的方法,编译器将生成错误。
答案 2 :(得分:1)
使用Dog dog = new SpecialDog(12.0);
在您的代码中宣传polymorphism。换句话说,它将来会促进API的可扩展性。
例如,如果您的方法接受Dog
作为参数,则可以将任何狗传递到该方法: -
// you can pass SpecialDog, SkinnyDog, UglyDog into this API to make the dog fat
public void makeMeFat(Dog dog) {
...
}
但是,如果该方法仅接受某种类型的狗,那么该方法中只能使用该狗: -
// you can only pass SpecialDog into this API
public void makeMeFat(Special dog) {
...
}
如果使Dog
成为抽象类,则不能使用它来创建另一个Dog,因为抽象类只有部分实现。因此,不可能创建具有抽象类的狗。在现实世界中,你可能会得到一条带有抽象Dog
的3条腿的狗...但至少在编程世界中,你得到编译错误,因为编译器上帝不想要一条三条腿的狗。 :)
答案 3 :(得分:0)
创建一个SpecialDog,将其指定给Dog变量,如果只想使用SpecialDog函数,则需要进行强制转换。
Dog dog = new SpecialDog(12.0);
创建一个SpecialDog并将其分配给SpecialDog变量。没什么特别的。
SpecialDog dog = new SpecialDog(12.0);
其余两个尝试创建抽象类的实例,并且不会编译。