为了账号安全,请及时绑定邮箱和手机立即绑定

Java-从接口类型而不是类声明

Java-从接口类型而不是类声明

呼啦一阵风 2019-10-28 14:35:00
在正确掌握接口最佳实践的过程中,我注意到一些声明,例如:List<String> myList = new ArrayList<String>();代替ArrayList<String> myList = new ArrayList<String>();-据我所知,原因是因为它有一定的灵活性,以防万一您不想实现ArrayList,但又可能实现另一种类型的列表。通过这种逻辑,我建立了一个示例:public class InterfaceTest {    public static void main(String[] args) {        PetInterface p = new Cat();        p.talk();    }}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()方法,因为它仅适用于Cat。这使我相信,如果仅使用接口中声明的方法(而不是子类中的其他方法),则仅应从接口中声明,否则应直接从类中声明(在本例中为Cat)。我对这个假设是否正确?
查看完整描述

3 回答

?
智慧大石

TA贡献1946条经验 获得超3个赞

如果可以通过“ a” interface或“ a” 来引用对象class,则应首选后者,但前提是存在适当的类型。


考虑一个例子。你不应该只是一味地用在preferrence到所有情况,因为这会剥夺你喜欢简单的操作,等等。StringimplementsCharSequenceCharSequenceStringtrim()toUpperCase()


但是,应该改用String只关心其char值序列的方法,因为在这种情况下,这是合适的类型。实际上,在课堂上就是这种情况。CharSequencereplace(CharSequence target, CharSequence replacement)String


另一个例子是java.util.regex.Pattern它的Matcher matcher(CharSequence)方法。这样一Matcher来Pattern,不仅可以从创建String,而且还可以为所有其他创建的对象CharSequence。


可以在以下位置找到库中的一个很好的例子,该例子中interface应该使用a,但不幸的是没有使用a Matcher:它的appendReplacement和appendTail方法仅接受StringBuffer。StringBuilder从1.5 开始,该类别已被其更快的表亲取代。


A StringBuilder不是a StringBuffer,因此我们不能将前者与中的append…方法一起使用Matcher。但是,它们两者implementsAppendable(也在1.5中引入)。理想情况下Matcher,的append…方法应该接受any Appendable,然后我们就可以使用StringBuilder,以及所有其他Appendable可用的方法!


因此,我们可以看到,当存在适当的类型时,如何通过它们的接口引用对象可以成为强大的抽象,但是前提是这些类型存在。如果类型不存在,那么可以考虑定义自己的类型。Cat例如,在此示例中,您可以定义interface SelfBathable。然后Cat,您可以接受任何SelfBathable对象(例如Parakeet),而不是引用a


如果创建新类型没有意义,那么您可以通过其引用它class。


也可以看看

有效的Java 2nd Edition,项目52:通过其接口引用对象

如果存在适当的接口类型,则应使用接口类型声明参数,返回值和字段。如果您习惯于使用接口类型,那么您的程序将更加灵活。如果不存在适当的接口,则完全可以通过类来引用对象。


查看完整回答
反对 回复 2019-10-28
?
杨__羊羊

TA贡献1943条经验 获得超7个赞

您是正确的,但是如果需要,可以从界面投射到所需的宠物。例如:


PetInterface p = new Cat();

((Cat)p).batheSelf();

当然,如果您尝试将宠物扔给狗,则无法调用batheSelf()方法。它甚至不会编译。因此,为避免出现问题,您可以使用以下方法:


public void bathe(PetInterface p){

    if (p instanceof Cat) {

        Cat c = (Cat) p;

        c.batheSelf();

    }

}

使用时instanceof,请确保不会在运行时尝试让狗自己洗澡。这将引发错误。


查看完整回答
反对 回复 2019-10-28
  • 3 回答
  • 0 关注
  • 691 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信