在Java中声明一个抽象类
在Java中,通过将abstract关键字添加到类声明中来声明类是抽象的。这是一个Java抽象类的例子:
public abstract class MyAbstractClass {}
这就是在Java中声明一个抽象类的全部内容。现在你不能创建实例 MyAbstractClass因此,以下Java代码不再有效:
MyAbstractClass myClassInstance =new MyAbstractClass(); //无效
如果你试图编译上面的代码,那么Java编译器会产生一个错误,说你不能实例化, MyAbstractClass因为它是一个抽象类。
抽象类可以有抽象方法。您通过abstract在方法声明前添加关键字来声明方法摘要。这是一个Java抽象方法的例子:
public abstract class MyAbstractClass {public abstract void abstractMethod();}
抽象方法没有实现。它只是一个方法签名。就像Java interface中的方法一样 .
如果一个类有一个抽象方法,那么整个类必须被声明为抽象的。并非抽象类中的所有方法都必须是抽象方法。抽象类可以有抽象和非抽象方法的混合。
抽象类的子类必须实现(覆盖)其抽象超类的所有抽象方法。超类的非抽象方法只是继承而已。如果需要,它们也可以被覆盖。
这是抽象类的一个示例子类MyAbstractClass:
public class MySubClass extends MyAbstractClass {public void abstractMethod() {System.out.println(“My method implementation”);}}
注意如何从其抽象超类 MySubClass实现抽象方法。 abstractMethod()MyAbstractClass
唯一一次抽象类的子类没有被迫实现其超类的所有抽象方法的唯一时间是如果子类也是一个抽象类。
抽象类的目的
抽象类的目的是作为基类,它可以被子类扩展来创建一个完整的实现。例如,假设某个过程需要3个步骤:
行动之前的步骤。
那个行动。
行动之后的步骤。
如果动作前后的步骤始终相同,则可以使用此Java代码在抽象超类中实现三步过程:
public abstract class MyAbstractProcess {public void process() {stepBefore();action();stepAfter();}public void stepBefore() {//implementation directly in abstract superclass}public abstract void action(); // implemented by subclassespublic void stepAfter() {//implementation directly in abstract superclass}}
注意该action()方法是抽象的。MyAbstractProcess 现在,子类可以扩展MyAbstractProcess并重写该action()方法。
当process()该子类的方法被调用,全过程被执行时,包括stepBefore()和stepAfter()抽象超和的action() 子类的方法。
当然,这MyAbstractProcess不一定是抽象类来作为基类。该action()方法也不是抽象的。你可以使用一个普通的 class.但是,通过使抽象的方法实现以及类的实现,您可以清楚地向这个类的用户发出信号,表明不应该按照原样使用这个类。相反,它应该用作子类的基类,并且抽象方法应该在子类中实现。
上述示例没有该action()方法的默认实现。在某些情况下,你的超类可能实际上有一个子类应该覆盖的方法的默认实现。在这种情况下,您不能使该方法变为抽象。尽管不包含抽象方法,但仍然可以使超类尽管是抽象的。
这是一个更具体的例子,它打开一个URL,处理它并在之后关闭与URL的连接。
public abstract class URLProcessorBase {public void process(URL url) throws IOException {URLConnection urlConnection = url.openConnection();InputStream input = urlConnection.getInputStream();try{processURLData(input);} finally {input.close();}}protected abstract void processURLData(InputStream input)throws IOException;}
注意这processURLData()是一个抽象方法,这URLProcessorBase是一个抽象类。URLProcessorBase必须实现该processURLData() 方法的子类是因为它是一种抽象方法。
URLProcessorBase抽象类的 子类可以处理从URL下载的数据,而不用担心打开和关闭与URL的网络连接。这是由URLProcessorBase.子类只需要担心处理InputStream传递给 processURLData()方法的数据。这使得更容易实现从URL处理数据的类。
这是一个示例子类:
public class URLProcessorImpl extends URLProcessorBase {@Overrideprotected void processURLData(InputStream input) throws IOException {int data = input.read();while(data != -1){System.out.println((char) data);data = input.read();}}}
注意这个子类是如何实现这个processURLData()方法的,除此之外别无他法。其余的代码是从URLProcessorBasesuper继承的。
这里是一个如何使用这个URLProcessorImpl类的例子:
URLProcessorImpl urlProcessor = new URLProcessorImpl();urlProcessor.process(new URL(“#”));
该process()方法被调用,它在URLProcessorBase 超类中实现。这个方法反过来调用processURLData()这个URLProcessorImpl类。
抽象类和模板方法设计模式
我用这个URLProcessorBase类向你展示的例子实际上是Template Method设计模式的一个例子。Template Method设计模式提供了一些进程的部分实现,当扩展Template Method基类时,子类可以完成。
更多潍坊培训学校相关资讯,请扫描下方二维码