Java 接口和抽象类差别

原文:http://blog.csdn.net/sunboard/article/details/3831823

1.概述

一个软件设计的好坏,我想非常大程度上取决于它的总体架构,而这个总体架构事实上就是你对整个宏观商业业务的抽象框架,当代表业务逻辑的高层抽象层结构 合理时,你底层的详细实现须要考虑的就不过一些算法和一些详细的业务实现了。当你须要再开发还有一个相近的项目时,你曾经的抽象层说不定还能够再次利用 。面对对象的设计,复用的重点事实上应该是抽象层的复用,而不是详细某一个代码块的复用

说到了抽象,我就不能不提到曾让我头痛的Java接口和Java抽象类了,这也是本文我想说的重点。

既然面向对象设计的重点在于抽象,那Java接口和Java抽象类就有它存在的必定性了。

Java接口(interface)和Java抽象类(abstract class)代表的就是抽象类型,就是我们须要提出的抽象层的详细表现。OOP面向对象的编程,假设要提高程序的复用率,添加程序 的可维护性,可扩展性,就必须是面向接口的编程,面向抽象的编程,正确地使用接口、抽象类这些实用的抽象类型作为你结构层次上的顶层。

Java接口和Java抽象类有太多相似的地方,又有太多特别的地方,到底在什么地方,才是它们的最佳位置呢?把它们比較一下,你就能够发现了。

  1. Java接口和Java抽象类最大的一个差别,就在于Java抽象类能够提供某些方法的部分实现,而Java接口不能够(就是interface中仅仅能定义方法,而不能有方法的实现,而在abstract class中则能够既有方法的详细实现,又有没有详细实现的抽象方法),这大概就是Java抽象类唯一的长处吧,但这个长处很实用。假设向一个抽象类里增加一个新的详细方法时,那么它全部的子类都一下子都得到了这个新方法,而Java接口做不到这一点,假设向一个Java接口里增加一个
    新方法,全部实现这个接口的类就无法成功通过编译了,由于你必须让每个类都再实现这种方法才行,这显然是Java接口的缺点
    这个在我的另外一篇博客mapreduce 新旧API 差别中有提到类似的问题,在新的mapreduce api中更倾向于使用抽象类,而不是接口,由于这更easy扩展。原因就是上面划线部分所说的。
  2. 一个抽象类的实现仅仅能由这个抽象类的子类给出,也就是说,这个实现处在抽象类所定义出的继承的等级结构中,而由于Java语言的单继承性,所以抽象类作为类型定义工具的效能大打折扣。在这一点上,Java接口的优势就出来了,不论什么一个实现了一个Java接口所规定的方法的类都能够具有这个接口的类型,而一个类能够实现随意多个Java接口,从而这个类就有了多种类型。(使用抽象类,那么继承这个抽象类的子类类型就比較单一,由于子类仅仅能单继承抽象类;而子类能够同一时候实现多个接口,由于类型就比較多。接口和抽象类都能够定义对象,可是仅仅能用他们的详细实现类来进行实例化。)
  3. 从第2点不难看出,Java接口是定义混合类型的理想工具,混合类表明一个类不仅仅具有某个主类型的行为,并且具有其它的次要行为。
  4. 结合1、2点中抽象类和Java接口的各自优势,具精典的设计模式就出来了:声明类型的工作仍然由Java接口承担,可是同一时候给出一个Java 抽象类,且实现了这个接口,而其它同属于这个抽象类型的详细类能够选择实现这个Java接口,也能够选择继承这个抽象类,也就是说在层次结构中,Java 接口在最上面,然后紧跟着抽象类,这下两个的最大长处都能发挥到极至了。这个模式就是“缺省适配模式”。在Java语言API中用了这样的模式,并且全都遵循一定的命名规范:Abstract
    +接口名。(A extends AbstractB implements interfaceC,那么A即能够选择实现(@Override)接口interfaceC中的方法,也能够选择不实现;A即能够选择实现(@Override)抽象类AbstractB中的方法,也能够选择不实现)

Java接口和Java抽象类的存在就是为了用于详细类的实现和继承的,假设你准备写一个详细类去继承还有一个详细类的话,那你的设计就有非常大问题了。Java抽象类就是为了继承而存在的,它的抽象方法就是为了强制子类必须去实现的。

使用Java接口和抽象Java类进行变量的类型声明、參数是类型声明、方法的返还类型说明,以及数据类型的转换等。而不要用详细Java类进行变量的类型声明、參数是类型声明、方法的返还类型说明,以及数据类型的转换等。

2.实例

以下给出一个详细的接口Action,代码例如以下所看到的:

package org.springframework.webflow.execution;
public interface Action {
	public Event execute(RequestContext context) throws Exception;
}

在这个接口中,定义了一个没有详细实现的方法,方法名叫做execute(),返回类型是Event。如前面第一条所述,接口中的方法都是没有实现的。这些方法的详细实现是在实现(implements)这个接口的类中给出的。

再来看一个实现Action接口的抽象类AbstractAction,代码例如以下。

package org.springframework.webflow.action;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.BeanInitializationException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.ClassUtils;
import org.springframework.webflow.core.collection.AttributeMap;
import org.springframework.webflow.execution.Action;
import org.springframework.webflow.execution.Event;
import org.springframework.webflow.execution.RequestContext;

public abstract class AbstractAction implements Action, InitializingBean {

	protected final Log logger = LogFactory.getLog(getClass());

	public EventFactorySupport getEventFactorySupport() {
		return new EventFactorySupport();
	}

	public void afterPropertiesSet() throws Exception {
		try {
			initAction();
		} catch (Exception ex) {
			throw new BeanInitializationException("Initialization of this Action failed: " + ex.getMessage(), ex);
		}
	}

	protected void initAction() throws Exception {
	}

	protected Event success() {
		return getEventFactorySupport().success(this);
	}

	protected Event success(Object result) {
		return getEventFactorySupport().success(this, result);
	}

	protected Event error() {
		return getEventFactorySupport().error(this);
	}

	protected Event error(Exception e) {
		return getEventFactorySupport().error(this, e);
	}

	protected Event yes() {
		return getEventFactorySupport().yes(this);
	}

	protected Event no() {
		return getEventFactorySupport().no(this);
	}

	protected Event result(boolean booleanResult) {
		return getEventFactorySupport().event(this, booleanResult);
	}

	protected Event result(String eventId) {
		return getEventFactorySupport().event(this, eventId);
	}

	protected Event result(String eventId, AttributeMap resultAttributes) {
		return getEventFactorySupport().event(this, eventId, resultAttributes);
	}

	protected Event result(String eventId, String resultAttributeName, Object resultAttributeValue) {
		return getEventFactorySupport().event(this, eventId, resultAttributeName, resultAttributeValue);
	}

	public final Event execute(RequestContext context) throws Exception {
		Event result = doPreExecute(context);
		if (result == null) {
			result = doExecute(context);
			doPostExecute(context);
		} else {
			if (logger.isInfoEnabled()) {
				logger.info("Action execution disallowed; pre-execution result is ‘" + result.getId() + "‘");
			}
		}
		return result;
	}

	protected String getActionNameForLogging() {
		return ClassUtils.getShortName(getClass());
	}

	protected Event doPreExecute(RequestContext context) throws Exception {
		return null;
	}

	//抽象方法
	protected abstract Event doExecute(RequestContext context) throws Exception;

	protected void doPostExecute(RequestContext context) throws Exception {
	}
}

在抽象类AbstractAction中,既有详细实现的方法,又有没有详细实现的抽象方法

	//抽象方法
	protected abstract Event doExecute(RequestContext context) throws Exception;

须要注意的是在抽象类中,假设方法没有详细实现(就是方法后面没有{}),那么必须加上abstract来声明这种方法,而接口中不须要使用abstract来声明(抽象类之所以被称为抽象类,就是由于它包括有抽象方法。含有抽象方法的类叫做抽象类)

时间: 2024-10-19 06:31:55

Java 接口和抽象类差别的相关文章

Java接口和抽象类有什么区别,哪些时候用接口,哪些时候用抽象类?

Java接口和抽象类有什么区别,哪些时候用接口,哪些时候用抽象类? 2013-01-05 17:16:09|  分类: JAVA |  标签:java  |举报|字号 订阅 下面比较一下两者的语法区别:1.抽象类可以有构造方法,接口中不能有构造方法.2.抽象类中可以有普通成员变量,接口中没有普通成员变量3.抽象类中可以包含非抽象的普通方法,接口中的所有方法必须都是抽象的,不能有非抽象的普通方法.4. 抽象类中的抽象方法的访问类型可以是public,protected和(默认类型,虽然eclips

初探设计:Java接口和抽象类何时用?怎么用?

今天犯了个错: “接口变动,伤筋动骨,除非你确定只有你一个人在用”.哪怕只是throw了一个新的Exception.哈哈,这是我犯的错误. 一.接口和抽象类 类,即一个对象. 先抽象类,就是抽象出类的基础部分,即抽象基类(抽象类).官方定义让人费解,但是记忆方法是也不错的 — 包含抽象方法的类叫做抽象类. 接口就是把抽象的深度更深,它就像用简短的非逻辑的一些规则表示类之间的关系.可以比作协议,比如通信使用的UDP/TCP协议等. 小结:类与接口是Java语言的基本抽象单元. 二.为什么有接口的两

浅谈Java接口和抽象类的区别

面向对象的设计,服用的重点其实应该是抽象层的复用,而不是具体某一个代码块的复用. 说到了抽象,就不得不提到Java接口和Java抽象类了,这也是我这里想要谈论的重点. Java接口和抽象类代表的就是抽象类型,就是我们需要提出的抽象层的具体表现.OOP面向对象编程,如果要提高程序的复用率,增加程序的可维护性,可扩展性,就必须是面向接口编程,面向抽象编程,正确地使用接口,抽象类这些有用的抽象类型作为你结构层次上的顶层. Java接口和Java抽象类有太多相似的地方,又有太多特别的地方,究竟在什么地方

Java 接口和抽象类小记

Java 接口和抽象类小记 @author ixenos 接口 1.接口没有构造函数,因为接口是不能被实例化的2.匿名对象如果使用接口的构造器也只是表示了一个协变的实现了接口的匿名对象3.接口里面的成员变量默认都是public static final类型的.必须被显示的初始化.4.接口里面的方法默认都是public abstract类型的.隐式声明.5.接口不能实现另一个接口,但可以继承多个接口.6.类如果实现了一个接口,那么必须实现接口里面的所有抽象方法 抽象类 1.若果在父类中(这里就是你

Java 接口和抽象类区别

1.概述 一个软件设计的好坏,我想很大程度上取决于它的整体架构,而这个整体架构其实就是你对整个宏观商业业务的抽象框架,当代表业务逻辑的高层抽象层结构 合理时,你底层的具体实现需要考虑的就仅仅是一些算法和一些具体的业务实现了.当你需要再开发另一个相近的项目时,你以前的抽象层说不定还可以再次利用 .面对对象的设计,复用的重点其实应该是抽象层的复用,而不是具体某一个代码块的复用. 说到了抽象,我就不能不提到曾让我头痛的Java接口和Java抽象类了,这也是本文我想说的重点. 既然面向对象设计的重点在于

java接口和抽象类

(一)接口和抽象类 作用: 1 利于设计和实现分工: 2 体现代码的层次性: (二)钩子方法或者叫模板方法方式 概念:23中设计模式中的一种,在代码执行的中间阶段,加入钩子,使得我们根据需要调用子类的不同方法,就行我们日常生活中的插座一样,如果你插上去的是电饭煲,那当然这个钩子就充当了煮饭的作用:如果你用来冲热水袋,你们它就充当了加热取暖的作用,我们在我们的某一个功能实现的过程中加入这样的钩子,那么这就是模板方法模式,它可以根据子类对这个方法(比如对于奔跑这个方法,不同子类不一样)来动态调用不同

浅谈JAVA接口和抽象类

一.什么是抽象方法.抽象类 抽象方法: 1.背景(为什么要有抽象方法):有一些方法,一出生就是用来让别人继承重写使用的,自己完全没有去实现的必要,只用定义就可以了,于是JAVA里就专门将这种方法称为抽象方法. 2.定义:用abstract修饰符来声明一种方法,而且这种方法只有声明,没有实现. 例如: public abstract test();//只做了声明,没有实现,连"{}"都不写. 抽象类: 1.背景:因为抽象方法是定义在类里面的,抽象方法是只有声明没有实现的方法,即是残缺不全

Java 接口和抽象类--缺省模式

一个软件设计的好坏,我想很大程度上取决于它的整体架构,而这个整体架构其实就是你对整个宏观商业业务的抽象框架,当代表业务逻辑的高层抽象层结构 合理时,你底层的具体实现需要考虑的就仅仅是一些算法和一些具体的业务实现了.当你需要再开发另一个相近的项目时,你以前的抽象层说不定还可以再次利用 .面对对象的设计,复用的重点其实应该是抽象层的复用,而不是具体某一个代码块的复用. 说到了抽象,我就不能不提到曾让我头痛的Java接口和Java抽象类了,这也是本文我想说的重点. 既然面向对象设计的重点在于抽象,那J

Effective Java - 接口还是抽象类

Java有两种机制可以为某个抽象提供多种实现——Interface和abstract class. Interface 和 abstract class, 除了比较明显的区别(也就是能否提供基本实现), 比较重要的区别是—— 接口的实现类可以处于类层次的任何一个位置,而抽象类的子类则受到这一限制. Existing classes can be easily retrofitted to implement a new interface. 即,如果一个类要实现某个接口,只需要加上impleme