Java 我应该如何调用实现抽象方法的实例

Java 我应该如何调用实现抽象方法的实例,java,eclipse,subclass,abstract,Java,Eclipse,Subclass,Abstract,我有一个抽象类和一个类,该类扩展了抽象类并实现了方法,而无需添加自己的其他方法。 让我们调用类A和B。B扩展了A。我应该像这样创建类B的实例吗 A newInstance = new B(); B newInstance = new B(); A newInstance = new B(); 还是像这样 A newInstance = new B(); B newInstance = new B(); A newInstance = new B(); 这有什么区别吗?哪种做法更好 这

我有一个抽象类和一个类,该类扩展了抽象类并实现了方法,而无需添加自己的其他方法。 让我们调用类A和B。B扩展了A。我应该像这样创建类B的实例吗

A newInstance = new B();
B newInstance = new B();
A newInstance = new B();
还是像这样

A newInstance = new B();
B newInstance = new B();
A newInstance = new B();
这有什么区别吗?哪种做法更好

这有什么区别吗?哪种做法更好

编程到接口而不是实现这是首选方式,请在此处阅读更多-->。不同之处在于,您遵循的是契约而不是实现,如果必须使用相同的契约更改实现,那么您可以确保只需更改对象创建部分

在您的示例中,如果您这样定义

A newInstance = new B();
B newInstance = new B();
A newInstance = new B();
您只能使用合同中可见的方法

在这种情况下:

B newInstance = new B();

您可以使用在
B
合同中可见的方法,并且由于B与
a
IS-a
关系,您也可以使用
a
方法

关于可维护性,我选择第二个:

B newInstance = new B();
显然,目前这并不重要,因为
A
B
在字段和方法方面是相同的(根据您所说的)

但是,假设您的班级
B
发生了变化。您可以添加一个方法或字段。如果将新实例声明为
A newInstance=new B()
,则无法访问在
B
中所做的更改


正如第二点一样,从外行的角度来看,使用第二种方法更有意义。

如果该方法是a方法,您可以使用任何一种形式。您所使用的取决于具体情况。如果您的
newInstance
变量可能被分配到A的几个子类中的任何一个子类,那么您显然必须使用A。如果您打算将B视为A(不使用B特有的任何方法,例如),那么您通常应该将其称为A。但如果您在任何地方都将对象视为B,则应将其称为A B。(这是一个判断调用。)@SotiriosDelimanolis-我不确定这是否是一个重复(至少是该线程)。在某些方面,对抽象类的编程类似于对接口的编程,但在其他方面却有很大的不同。@TedHopp在我看来,
interface
不应该被字面理解为Java的
接口
。它应该被视为一个编程接口/契约的含义。此外,考虑到,如果选择似乎是任意的,则在层次结构中更喜欢更高的点。您通常不希望约束类型超过您需要的范围。例如,如果您有一个保存一个集合的变量,而实际上您并不关心它是什么类型的集合,请将其设置为
集合
,而不是,例如
哈希集
。然后,如果需要,您可以在不更改代码的情况下切换到其他类型集。-1对于可维护性,第一种是首选方式
A A=new B()
。我想我的意思是,当
B
更改时,第一种选项将不再是首选。对吗?对接口进行编程的全部要点是,您看不到来自客户端源代码的实现中的更改。你的观点是没有意义的。事实上,@SotiriosDelimanolis是对的,你抽象了实现细节,你关注的是它们做什么,而不是如何做。