当前位置: 首页 > 面试题库 >

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

鲁华灿
2023-03-14
问题内容

在正确掌握接口最佳实践的过程中,我注意到一些声明,例如:

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)。我对这个假设是否正确?


问题答案:

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

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

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

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

可以在以下位置找到库中一个很好的示例,该示例中interface应该使用a,但不幸的是没有使用a Matcher:它的appendReplacementappendTail方法仅接受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:通过其接口引用对象
如果存在适当的接口类型,则应使用接口类型声明参数,返回值和字段。如果你习惯使用接口类型,那么你的程序将更加灵活。如果不存在适当的接口,则完全可以通过类来引用对象。



 类似资料:
  • 我写了自己的类加载器,它与类一起工作,实现了接口插件。但是我不能将类转换为插件。怎么了? 错误:(18,47)java:不兼容的类型:java。lang.类无法转换为插件 我补充说,这是我的SimpleClassLoader类的主要部分,它扩展了ClassLoader。

  • 问题内容: 一般情况下,我无法优雅地获取图像像素作为数组。 现在,功能getPixels如下所示: 但是我认为这很丑。Golang知道图像的类型,我希望这样: 我也不能坚持。也许有一种方法可以从接口获取类型? 问题答案: 通过使用如下所示的类型开关,可以简化大型结构: 您仍然必须列出所有可能的类型,但这更好。 由于所有图像实现都是具有名为的字段的结构指针,因此您可以使用反射来获取该字段。此实现将处

  • 我有一个类扩展了另一个类(),并实现了一个接口(),如下所示: 接口类和父类都有函数,但我只想重写接口类。目前,这段代码会产生编译错误,因为父类()中的getMessage是。

  • 7.2. 接口类型 接口类型具体描述了一系列方法的集合,一个实现了这些方法的具体类型是这个接口类型的实例。 io.Writer类型是用的最广泛的接口之一,因为它提供了所有的类型写入bytes的抽象,包括文件类型,内存缓冲区,网络链接,HTTP客户端,压缩工具,哈希等等。io包中定义了很多其它有用的接口类型。Reader可以代表任意可以读取bytes的类型,Closer可以是任意可以关闭的值,例如一

  • 问题内容: 我正在学习如何使用JavaScript进行OOP。它具有接口概念(例如Java的接口)吗? 这样我就可以创建一个侦听器… 问题答案: 没有“此类必须具有这些功能”的概念(也就是说,本身没有接口),因为: JavaScript继承基于对象,而不是类。除非您意识到:这不是什么大不了的事情 JavaScript是一种 非常 动态的类型化语言-您可以使用适当的方法创建对象,这将使其符合接口,

  • 我想通过google play services lib更改GoogleAdMobAdsSdk,但是当我删除GoogleAdMobAdsSdk时,我出现了一个错误:AdListener类型不能是GameActivity的超接口;超接口必须是接口。 你能帮帮我吗! PS:您可以在这里找到一部分代码:迁移到新的google play服务库 提前感谢!