2011-02-19 111 views
1

如果我有一个抽象类名为狗与一个构造函数来设置它的权重(双)和一个名为SpecialDog类延伸狗,并有一个构造函数接受一个双和传递给狗使用超级()。快速JAVA继承问题

什么(如果有的话)之间的差异:

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

除了下面的答案,请看看所谓的“策略”设计模式。如果你能理解这种模式会发生什么,你会看到这个想法的力量。 – jmq 2011-02-19 01:49:45

+1

JAVA,我想是1995年了。 – 2011-02-19 05:36:47

回答

5

回答您的问题(他们都是不同的):

Dog dog = new SpecialDog(12.0); 

在这里,你正在创建一个SpecialDog,但使用狗参考指向它。对象一种特殊的狗,但是,除非您下载dog变量,否则您只能将dog视为Dog而不是SpecialDog

SpecialDog dog = new SpecialDog(12.0); 

在这里,您正在创建一个SpecialDog,并使用SpecialDog引用指向它。

Dog dog = new Dog(12.0); 

这是一个编译器错误,因为您不能实例化抽象类。

SpecialDog dog = new Dog(12.0); 

这只是一个编译器错误。您不能将超类分配给子类引用。记住:继承是一个“是-A”的关系。虽然SpecialDog始终是可能并不总是SpecialDog

3

如果您Dog类是抽象然后

Dog dog = new Dog(12.0); 
SpecialDog dog = new Dog(12.0); 

将无法​​编译。

为了回答您的评论一个问题:

如果使用Dog变量,你将只能使用Dog类的方法。 如果在这种情况下尝试使用SpecialDog的方法,则编译器将生成错误。

+0

这样想。谢谢:) 如果我将它声明为Dog或SpecialDog,它会改变什么吗?我的意思是,如果狗被声明为狗的类型,我可以使用在类SpecialDog中找到的方法,如下所示:dog.someMethod() – n0pe 2011-02-19 01:36:22

0

创建一个SpecialDog,将其分配给Dog变量,如果您想使用SpecialDog唯一功能,则需要进行强制转换。

Dog dog = new SpecialDog(12.0); 

创建一个SpecialDog并将其分配给一个SpecialDog变量。没什么特别的。

SpecialDog dog = new SpecialDog(12.0); 

剩下的两个尝试创建一个抽象类的实例,并且不会编译。

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是一个抽象类,那么你就不能使用它来创建另一个狗,因为一个抽象类只有部分实现。所以,创建一个抽象类的狗是不可能的。在现实世界中,你可能会得到一条3条腿,抽象的Dog ...但至少在编程世界,你会得到一个编译错误,因为编译器上帝不想要一条三条腿的狗。 :)