JAVA抽象类和接口

近来对抽象类跟接口搞不太清楚,在网上查了些资料,汇总如下,有什么不对的地方还请大家指正


比较

抽象层次从高到底:接口->抽象类->具体实现类

行为的抽象,是规则,接口, (是特殊的个性) 
事物的抽象,是共性,是抽象类(是一般的共性)


抽象类理解:抽象类往往用来表征我们在对问题领域进行分析、 设计中得出的抽象概念,是对一系列看上去不同,但是本质上相同的具体概念的抽象,我们不能把它们实例化(拿不出一个具体的东西)所以称之为抽象。比如:我们要描述“水果”,它就是一个抽象,它有质量、体积等一些共性(水果有质量),但又缺乏特性(苹果、橘子都是水果,它们有自己的特性),我们拿不出唯一一种能代表水果的东西(因为苹果、橘子都不能代表水果),可用抽象类来描述它,所以抽象类是不能够实例化的。当我们用某个类来具体描述“苹果”时,这个类就可以继承描述“水果”的抽象类,我们都知道“苹果”是一种“水果”。


1.接口中定义了一些方法,但是没有实现。
2.在接口的具体实现类中,如果有共同的实现<部分>,可用一个抽象类来实现这些共同的部分;个性化的实现交给具体实现类<子类>完成。
3.抽象类提供了公共方法的实现,抽象类提高代码复用能力

 

1、abstract class 和 interface有什么异同?

答:

1)抽象类可以有实现(包括构造函数),而接口不可以有任何实现,重要的是抽象类可以包括抽象方法,这是普通类所不能的。抽象方法只能声明于抽象类中,且不包含任何实现,派生类必须覆盖它们。接口中所有方法都必须是未实现的。

2)抽象类中还以有成员变量(包含静态成员变量)、属性、常量和静态方法,并且他们可以是非公共的;而接口中不能有成员变量、常量、静态方法,只能有公共的属性。

3)抽象类可以从另一个类或者一个/ 多个接口派生;而接口不能从另一个类派生却可以实现另一个或多个接口。

4)一个.net 类只能从一个基类中派生即使这个基类是抽象类;然而一个.net 类可以实现多个接口。(但是如果从一个抽象类派生或者从一个/ 多个接口实现,则必须实现抽象类中抽象方法或接口中所有的方法)

相同点:

1)不能实例化;

2)包含未实现的方法声明;

3)派生类必须实现未实现的方法,抽象类是抽象方法,接口则是所有成员(不仅是方法包括其他成员);

抽象类和接口的使用:

1)如果预计要创建组件的多个版本,则创建抽象类。抽象类提供简单的方法来控制组件版本。

2)如果创建的功能将在大范围的全异对象间使用,则使用接口。如果要设计小而简练的功能块,则使用接口。

3)如果要设计大的功能单元,则使用抽象类.如果要在组件的所有实现间提供通用的已实现功能,则使用抽象类。   

4)抽象类主要用于关系密切的对象;而接口适合为不相关的类提供通用功能。


使用场景

   1 优先定义接口 
   2 如果有多个接口实现有公用的部分,则使用抽象类(代码复用),然后继承它。

   包含抽象方法的类即为抽象类,当一个抽象类中所有的方法都是抽象时,我们就可以定义成接口。  
在设计类时,如果有些方法我们能确定,而有些方法不能确定,这时候我们就可以把该类声明成抽象类。抽象类的应用场景非常多,例如模板方法模式就是抽象类的一个应用,   JDK中的inputStream和outputStream也是抽象类的一个应用,这两个类定义了如何读写数据的方法,而没有定义从哪里去读,具体从哪里读由具体的实现子类确定。  
我们在定义相互调用规则时,可以使用接口。面向接口进行编程的明显好处,就是能极大降低软件系统的相互耦合性,接口的定义者按照接口进行调用,而实现者去实现接口。 
   在JDK中存在许多针对于接口的编程,例如用于比较对象的Comparable接口就是一个典型案例,我们在自定义对象时,如果实现了该接口,那么我们把对象保存到treeset集合中时,treeset将针对接口调用对象的compareTo方法。

看下面学生的例子:

abstract class AbstractStudent {

	abstract void study();

	void sleep() {
		System.out.println("sleep");
	}

	void smoke() {
		System.out.println("抽烟");
	}

}

//所有的Student被创建都会抽烟,是不是很搞笑? 

class Student extends AbstractStudent{ 
	
	tudent Demo stu = new Student(); 
 
	... 

}

上面这个学生抽象类中有三个方法,学习,睡觉,抽烟。我们知道任何一个学生都要学习,都要睡觉,但是不是每个学生都要抽烟呢?这显然是不合理的。难道说创建一个学生对象,就一定要强加给他抽烟的方法?就像一个学生来了,就一定要他会抽烟?女生也不放过?哈哈!这显然是很荒唐的事情。

于是我们做如下调整:

abstract class AbstractStudent {

	abstract void study();

	void sleep() {
		System.out.println("sleep");
	}

}

interface Smoking{ 

	void smoke(); 

} 
 
//普通的学生,继承AbstractStudent,有学习、睡觉的方法,不抽烟 
class Student extends AbstractStudent{ 

} 

//抽烟的学生,除了继承AbstractStudent中的方法,还会抽烟  
class SmokeStudent extends AbstractStudent implements Smokeing{ 

}

这样,就把抽烟的同学和不抽烟的同学分离开了。

总结:抽象类中通常放的是类种事物(对象)共有的属性和方法,于是它的子类继承它的时候就自然有了其所有属性和方法,当有些方法是某种子类特有的时,就应该将这个方法分离出来,以附加的形式(implements)添加进去。


相关引用:

http://blog.sina.com.cn/s/blog_62dae6060100lsg1.html    (抽象层次)

http://www.cnblogs.com/m3Lee/archive/2013/06/05/3119148.html   (门的例子)

http://blog.csdn.net/boyxiaolong/article/details/7841773

http://www.tarena.com.cn/student/452.jhtml  (学生的例子)

http://wenku.baidu.com/view/0612ed1fff00bed5b9f31dcb.html   (abstract class 和 interface有什么异同?)

http://my.oschina.net/lchl/blog/11635   (面向接口编程)


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值