简书 賈小強
转载请注明原创出处,谢谢!
抽象类和接口这是大多数Java APIs的基础元素。在这篇文章中,我将尝试触及两个最重要的概念。
本文是理解Java中的抽象的延续。我建议您首先阅读抽象的概念,因为它是抽象类和接口背后的主要力量。
本文中的内容:
- 理解抽象类
- 理解接口
- 识别明显的差异
- 探索抽象类vs接口的用法
理解抽象类
简单地说,抽象类是用abstract关键字声明的类。它可能包含或不包含任何抽象方法。JVM将抽象类标识为不完全的类,没有定义它完整的行为。声明类抽象导致一件事:您不能创建这个类的实例,就是这样。
那么,为什么还要费心创建一个根本就不能实例化的类呢?答案是在解决一些关键设计问题上时使用。稍后我们将在这篇文章中讨论这个部分。
让我们来看看抽象类的一个非常基本的形式:
abstract class TestAbstractClass
{
public abstract void abstractMethod();
public void normalMethod()
{
//method body
}
}
在这里,我们的TestAbstractClass有两个方法,一个是抽象的,第二个是正常的方法。在类中使用抽象方法将迫使您将类本身声明为抽象。
抽象方法,是一种没有实现的方法。抽象方法以不完整性的形式添加到类中,因此编译器希望声明整个类为抽象。
在应用程序中使用抽象类的唯一方法是继承这个类。它的子类如果不能再次声明抽象,那么可以实例化。子类继承超类的行为,子类可以实现抽象方法。
理解接口
接口是大多数Java APIs的另一个基本构建元素。比如集合、I/O或SWT,你可以到处看到它们
接口定义了实现类需要遵守的契约。这些契约本质上是未实现的方法。Java已经有一个针对未实现的方法的关键词即abstract。Java已经提供的任何类都可以实现任何接口,所有接口中声明的方法只能是public。
让我们看看接口的基本形式:
public interface TestInterface
{
void implementMe();
}
针对上面的接口,任何实现类需要实现implementMe ()方法。只有一种情况例外,当您实现一个接口时不需要实现接口的方法,即声明实现类本身抽象。例如,
public abstract class TestMain implements TestInterface
{
//No need to override implement Me
}
否则,你必须在你的类中实现implementMe ()方法。
public abstract class TestMain implements TestInterface
{
//No need to override implement Me
}
识别明显的差异
让我们记下抽象类和接口之间的差异,以便快速查阅:
- 接口所有方法都具有public和abstract。您不能通过试图减少方法的可访问性来覆盖此行为。您甚至不能声明静态(static)方法。只有public和abstract。
另一方面,抽象类在声明方法时是灵活的。您还可以定义protected的抽象方法。此外,还可以定义静态方法,前提是它们不是抽象的。允许使用非抽象静态方法。 - 接口不能有完全定义的方法。根据定义,接口仅用于提供契约。
抽象类可以有非抽象的方法,没有任何限制。您可以使用任何非抽象方法的关键字,就像在其他类中一样。 - 任何抽象类可以用extends关键字继承抽象类,用implements关键字实现接口。
一个类只能继承一个类,但可以实现任意数量的接口。Java用此特性模拟多继承。 - 接口是完全抽象的,不能被实例化;Java抽象类也不能实例化,但可以被调用,如果main()存在。
抽象类与接口的使用探索
始终记住,在接口或抽象类之间进行选择并不是非此即彼的情况,在没有适当分析的情况下选择一个都会产生相同的结果。在了解了手头的问题后,必须明智地作出选择。让我们试着把一分析一些情况:
抽象类让您定义了一些行为,使它们成为应用程序框架内的优秀候选者。
让我们以HttpServlet作为一个例子。如果你正在使用servlet技术开放Web应用程序,那么它是一个主要的必须继承的类。正如我们所知道的,每个servlet都有一个明确的生命周期阶段,即初始化、服务和销毁。如果我们创建的每一个servlet,我们必须反复编写关于初始化和销毁的相同的代码,这将非常痛苦。
JDK设计师使HttpServlet为抽象类解决这个问题。它已经为servlet初始化和销毁它编写了所有基本代码。您只需重写编写应用程序处理相关代码的某些方法,即可。有道理,对吗?!!
你能在接口上面添加特性吗?不,即使你能,对大多数无辜程序员来说,设计也会像地狱一样。
现在,让我们看看接口的用法。一个接口只提供契约,它让实现类负责来提每一个方法。
接口最适合于只定义具有种特性的情况,并且希望强制所有实现都实现这些特性。
我希望以集合框架中的Map为例。它只提供规则,Map在使用时应该如何表现。它应该存储键值对,值应该用键访问等。
这些规则在接口中以抽象方法的形式定义。
所有的实现类(如HashMap,HashTable,TreeMap或WeakHashMap)以不同的形式实现了所有的方法,从而它们表现出了不同的特征。
另外,接口可以用于确定分离的责任。例如HashMap实现了Map ,Serializable,和Cloneable接口。每个单独的接口定义了责任,实现类选择性的实现想要实现的功能,接口只提供了小一个范围了的功能。
最后,再举一种用法,实际上就多线程的例子,如 new Thread(Runnable task),Thread类要求传入一个实现Runnable接口的对象,然后Thread类对象会调用接口上实现的方法
希望你更多的理解了Java接口和抽象类。我会不断更新这个页面,所以继续访问。
Happy learning !!