Heim > Java > Hauptteil

何时使用抽象,何时使用接口?

PHPz
Freigeben: 2024-02-22 12:25:19
nach vorne
642 人浏览过

php小编子墨带您探索Java中抽象类和接口的使用时机。在Java编程中,选择何时使用抽象类,何时使用接口是一项重要决策。本文将为您解答这个常见的问题,帮助您更好地理解在不同情况下如何选择合适的抽象类或接口。

问题内容

我隐约明白抽象和接口之间的区别,但我根本无法理解的是,什么时候使用抽象,什么时候使用接口。我需要哪些变量来选择接口抽象,反之亦然?网上大部分答案都是为了展示差异,但即使我理解它们。不知道什么时候比较合适。

解决方法

一般古老的原则是:坚持使用接口,直到你被迫编写抽象类。

java 中的 interface 是一种不可实例化类型,它定义了其他类型可以选择遵守的公共接口。

  • 接口可以声明公共方法,这些方法必须由其实现者定义。所有此类方法都隐式为 abstract,因此您不需要使用单词 abstract
  • 在旧版本的 java 中,接口不能有默认实现,因此每个方法都是 abstract。现在情况已不再是这样,接口现在可以具有在 implementing 类中使用的默认实现,除非被替换。
  • 在最新版本的 java 中,接口可以声明 private 辅助方法。这些可以帮助实现默认实现。
  • 接口永远不能有构造函数或实例变量。
  • 一个类可以 implement 多个接口。

abstract 类 只是一个无法实例化的类。抽象类不需要定义任何 abstract 方法,尽管您通常会想要这样做。

  • 抽象类可以声明具有任何可见性的方法:publicprivateprotected 和 package-private。
  • 抽象类可以实现方法或将它们保留为 abstract。抽象类中的方法不是隐式 abstract,并且必须如此标记。
  • 抽象类可以有构造函数,extending 类必须使用 super 在其自己的构造函数中调用构造函数。抽象类可以具有任何可见性的实例变量,它们的工作方式就像任何父类中的实例变量一样。
  • 一个类只能 extend 一个类,可以是 abstract 类,也可以是具体类。类的 abstractness 不会改变它允许拥有的超类的数量。

abstract classes 应该是例外而不是常态。如果您需要维护某些内部状态,同时还让子类定义您自己的行为,则应该使用抽象类。一个很好的例子来自 java swing gui 库:AbstractButtonabstractbutton 是行为模糊地类似于窗口中按钮的事物的抽象父代,包括按钮、切换按钮和菜单中的项目。任何人都可以子类化 abstractbutton 并实现其成员来定义类似按钮的显示。但是 abstractbutton 还必须维护大量内部状态(其中大部分来自 jcomponent),以便与窗口以及整个 swing api 进行通信。

如果要为类型集合定义公共接口,请使用 interface。如果您想为其中一些方法提供默认实现并且使用 2014 年之后发布的 java 版本,请使用接口。如果您需要默认实现但仍停留在 2000 年代,请使用抽象类。无论 java 版本如何,如果您需要私有状态(例如实例变量)或自定义初始化(例如构造函数),请使用抽象类。

接口:

假设您有一个界面,例如:

interface animal {
  string makenoise();
}
Nach dem Login kopieren

以及几个实现 animal 的类:

class cat implements animal {
    string makenoise() {
        return "meow";
    }
}

class dog implements animal {
    string makenoise() {
        return "woof";
    }
}
Nach dem Login kopieren

现在您可以使用接口作为返回类型,因此方法可以返回 catdog

string makeanimalmakenoise(int animalid) {
    animal animal = pretendanimalservice.getdogorcat(animalid);

    animal.makenoise();
}
Nach dem Login kopieren

抽象类:

假设您有一个抽象类:

abstract class animal {
    public string makenoise() {
        return "whistle";
    }

    abstract public string getname();
}
Nach dem Login kopieren

现在,任何扩展它的类都需要实现 getname 方法:

class Cat extends Animal {
    String getName() {
        return "Pussy";
    }
}

class Dog extends Animal {
    String getName() {
        return "Fido";
    }
}
Nach dem Login kopieren

上述两个类都实现了所需的 getname 方法,但它们也可以访问父类 makenoise 方法,如果需要,也可以覆盖该方法。

注意其他差异也很重要,它们是:

  • 您只能扩展一个抽象类,但可以实现多个 接口。
  • 当不同类型应具有相同的方法签名时,应使用接口;而当实现共享共同行为时,应使用抽象类。
  • 它们并不相互排斥。
  • 接口只能有公共方法,而抽象类可以有公共方法和受保护方法。

以上是何时使用抽象,何时使用接口?的详细内容。更多信息请关注PHP中文网其他相关文章!

Quelle:stackoverflow.com
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!