【java基础】JAVA 引用对象时应该用接口类型还是实现类的类型
先上代码把标题的问题说清楚,下面两种接收对象的方式选择哪一种?
//implA 为接口 ClassB为其实现类
implA A=new ClassB(); //接口类型的引用变量A 去接收对象地址
or
ClassB A=new ClassB(); //类类型的引用变量A 去接收对象地址
先抛出结论:应该优先使用接口而不是类来引用对象,但只有存在适当的接口类型时。
《Effective Java》中说到:
“如果存在适当的接口类型,那么参数,返回值和字段都应该使用接口类型。
如果你养成使用接口类型的习惯,你的程序将更加灵活。 如果没有合适的接口存在,则通过类来引用对象是完全合适的。”
那么什么时候不存在适当的接口类型呢?看看下面的例子:
public class InterfaceTest {
public static void main(String[] args) {
PetInterface p = new Cat();
p.talk();
p.batheSelf();//无法调用 ,报错The method batheSelf() is undefined for the type PetInterface
}
}
interface PetInterface {
public void talk();
}
class Dog implements PetInterface {
@Override
public void talk() {
System.out.println("Bark!");
}
}
class Cat implements PetInterface {
@Override
public void talk() {
System.out.println("Meow!");
}
public void batheSelf() {
System.out.println("Cat bathing");
}
}
我们看到,方法batheSelf()仅仅存在实现类中时,若我们仍然使用接口来引用对象时PetInterface p = new Cat(),那些仅仅存在实现类中的方法,是无法直接调用的即p.batheSelf()无法调用会报错。所以这时使用Cat p = new Cat()即类来引用是更好的。
总而言之,使用接口类去引用对象是有前提条件的——即实现类中全是接口类的方法的实现,没有自己单独的方法。当实现类存在自己的方法时,使用实现类来声明变量。
优点:1.假如一个类实现了多个接口,那么用接口类型来定义它的引用变量的话,一眼就可以明白,这里是需要这个类的哪些方法。
2.程序更加灵活。当你决定更换实现时,只需要改变构造器中类的名称。其他使用list地方的代码根本不需要改动。如下:
List<?> list= new Vector<?>();
//更改为ArrayList
List<?> list= new ArrayList<?>();