我有一个名为A
(父级)的班级和班级B
(A的子类)
我的问题是下一行之间的区别是什么:
B b1 = new B();
A b2 = new B();
我知道在对象b2
但是它在内存中是如何工作的?有什么意义呢?何时使用它们?
答案 0 :(得分:1)
使用超类作为变量类型的一个原因:
假设您有一个Animal类,以及像Elephant,Tiger,Giraffe,Hippo等几个子类。
现在你有另一个名为Zoo的类,它包含一个名为animals的数组。然后你可以:
animals[0] = new Tiger();
anumals[1] = new Elephant();
但最好将动物声明为可以增长或缩小的ArrayList:
animals.add( new Tiger() );
animals.add( new Elephant() );
animals.add( new Hippo() );
如果子类的方法不是父方法的重载,您仍然可以通过强制转换它来通过超类变量访问子类方法:
Animal a = animals.get(index);
if ( a instanceof Tiger ) {
((Tiger)a).tigerMethod( ... );
}
并不是说这种类型的东西可能不是最好的设计,但它说明了这一点。
答案 1 :(得分:0)
对象可以有多个接口,比方说B类继承自A类: A类可以有5种公共方法, B类还有5个自己的公共方法, 所以在B组中你会看到所有10种方法,而使用A类你只能看到5种方法。
这很重要,因为通过这种方式,您可以控制您为其他人(其他程序员使用)提供的类的哪个部分(界面)。
例如:
如果您从公开方法返回列表<>,请执行以下操作:
public List<SomeClass> giveMeSomeList() {
// both return statements are perfectly valid as return type is List<>
return new LinkedList<SomeClass>();
// return new ArrayList<SomeClass>();
}
然后您可以使用List&lt;&gt;的任何实现你有例如。你可以创建实现,你构造并返回一个ArrayList&lt;&gt;或LinkedList&lt;&gt;从您的方法,但由于声明的返回类型是List&lt;&gt;它没有任何伤害,没有人会依赖你返回具体的实现(至少你不负责),只是它将是一种List&lt;&gt;。但是如果你从公共方法返回非常具体的类实现,那么你给别人邀请使用并依赖于这个具体的实现,这反过来又阻止了这些方法能够在不损害其他代码的情况下实现底层实现。 因此,通过这种方式(使用适当的类型),您可以对其他程序员进行一些限制,使他们可以使用哪些方法(接口),并为将来更改实现提供一些自由 - 例如在列表的例子中
在方法参数类型中使用接口时,可以使方法更通用,因为它可以与接口(或类型)的任何子类型一起使用。 有时你只需要非常具体的实现作为你的方法的参数,因为没有它你就不能做所需的操作,所以你将依赖非常具体的类型提供给你的方法,并在方法的参数中声明该类型。