Java中抽象类和接口之间的区别
抽象类和接口之间的区别是流行的采访问题之一。
抽象类和接口是Java编程语言的核心部分。
选择接口还是抽象类是每个架构师都面临的设计决策。
在上一篇文章中,我提供了有关Java接口和抽象类的尽可能详细的信息。
在本文中,我们将了解抽象类和接口之间的区别,以及何时应在抽象类上使用接口,反之亦然。
抽象类和接口之间的区别
" abstract"关键字用于创建抽象类,并且还可以与方法一起使用,而" interface"关键字用于创建接口,而不能与方法一起使用。
子类使用
extends
关键字扩展抽象类,除非子类也是抽象类,否则它们需要提供抽象类中所有已声明方法的实现,而子类则使用implements
关键字实现接口并应为所有接口提供实现接口中声明的方法。抽象类可以具有实现的方法,而接口则提供绝对的抽象,并且不能具有任何方法的实现。
请注意,从Java 8开始,我们可以在包含方法实现的接口中创建默认方法和静态方法。抽象类可以具有构造函数,但接口不能具有构造函数。
抽象类具有普通Java类的所有功能,但我们无法实例化它。
我们可以使用abstract
关键字使类抽象,但是接口是完全不同的类型,并且只能具有公共静态最终常量和方法声明。抽象类方法可以具有公共,私有,受保护,静态的访问修饰符,但接口方法是隐式公共和抽象的,我们不能将任何其他访问修饰符与接口方法一起使用。
子类只能扩展一个抽象类,但可以实现多个接口。
抽象类可以扩展其他类并实现接口,但是接口只能扩展其他接口。
如果抽象类具有main()方法,我们可以运行该类,但是由于它们没有main方法的实现,因此我们无法运行接口。
接口用于定义子类的协定,而抽象类也定义协定,但是它可以提供其他方法实现以供子类使用。
这就是接口和抽象类之间的区别,现在我们可以继续了解何时应该在抽象类上使用接口,反之亦然。
接口或者抽象类
在接口还是抽象类之间进行选择以为子类提供合同是一个设计决定,取决于许多因素。
让我们看看什么时候接口是最佳选择,什么时候可以使用抽象类。
Java不支持多个类级别的继承,因此每个类只能扩展一个超类。
但是一个类可以实现多个接口。
因此,大多数时候,接口是为类层次结构和协定提供基础的好选择。
另外,在接口方面进行编码也是用Java进行编码的最佳实践之一。如果协定中有很多方法,那么抽象类会更有用,因为我们可以为所有子类通用的某些方法提供默认实现。
另外,如果子类不需要实现特定的方法,则可以避免提供实现,但是在使用接口的情况下,子类将必须为所有方法提供实现,即使它没有用处并且实现只是空块。如果我们的基本合同一直在变化,那么接口会引起问题,因为在不更改所有实现类的情况下我们无法向接口声明其他方法,使用抽象类,我们可以提供默认实现,而仅更改实际使用的实现类使用新方法。
同时使用Abstract类和Interface
一起使用接口和抽象类是设计系统的最佳方法。
例如,在JDK中,java.util.List是一个包含很多方法的接口,因此有一个抽象类java.util.AbstractList,它为List接口的所有方法提供了基本实现。
子类可以扩展此类,并且仅实现必需的方法。
我们应该始终以接口作为基础,并定义每个子类都应实现的方法,然后,如果只有某些子类应实现某些方法,则可以扩展基本接口并使用这些方法创建新接口。
子类可以选择在基本接口还是子接口之间进行选择,以根据其要求来实现。
如果方法的数量增加很多,那么提供一个框架抽象类来实现子接口并为子类提供灵活性以在接口和抽象类之间进行选择就不是坏主意了。
Java 8接口更改
从Java 8开始,我们可以在接口中使用方法实现。
我们可以在接口中创建默认方法和静态方法,并为其提供实现。
这弥合了抽象类和接口之间的鸿沟,现在接口才是可行的方法,因为我们可以通过为新方法提供默认实现来进一步扩展接口。