抽象類更多的情況下是作為一個模闆使用,而接口更多的情況下是作為一個标準出現。
一個子類如果實作了一個接口,則肯定要覆寫接口中的全部方法,那是否有一種方式,可以讓子類有選擇的去實作接口中的方法,而不是全都實作呢?
interface A{
public void printA() ;
public void printB() ;
public void printC() ;
public void printD() ;
public void printE() ;
}
以上的接口的子類能否有選擇性的進行所需要方法的覆寫呢?
abstract class AAdapter implements A{
// 方法全部實作
// 但是此類是中間過渡類,不能直接使用,是以此時應該把此類定義成抽象類。
public void printA() {}
public void printB() {}
public void printC() {}
public void printD() {}
public void printE() {}
};
class AAA extends AA{
public void printA() {
System.out.println("dafa");
}
<b>思考:</b>
張三去酒會參加活動,碰見了一個美國女孩,想跟她說“HELLO,MAKE FRIEND”,第二次又參加了一個舞會,又碰見了一個中國的女孩,想跟她說“你好,我想跟你交朋友”。
· 碰見美國人說英語
· 碰見中國人說中文
· 接口的第二個作用就是表示一種能力。
interface SayChina{
public void sayChina() ;
interface SayEnglish{
public void sayEnglish() ;
class Person implements SayChina,SayEnglish{
public void sayChina(){
System.out.println("你好,交朋友吧!") ;
public void sayEnglish(){
System.out.println("HELLO,MAKE FRIEND!") ;
現在孫鍵欠了我500000000元錢,此時,王甯是一個老實人,孫鍵欺負他,不還,之後王甯沒有辦法了,找到了王偉(專門的讨債公司),準備好了繩索、刀子、槍支,從孫鍵手裡把銀子要了回來,之後銷毀了一切的證據。但是王甯隻管拿回了自己的錢。
可以按照以下的形式組織代碼:
interface Subject{
public void giveMoney() ;
class RealSubject implements Subject{
public void giveMoney(){
System.out.println("把錢拿回。。。") ;
class ProxySubject implements Subject{
private Subject sub = null ;
public ProxySubject(Subject sub){
this.sub = sub ;
public void before(){
System.out.println("要準備繩索、刀子、槍支。。。") ;
this.before() ;
this.sub.giveMoney() ;
this.after() ;
public void after(){
System.out.println("銷毀一切的罪證。。。") ;
public class Demo06{
public static void main(String args[]){
Subject sub = new ProxySubject(new RealSubject()) ;
sub.giveMoney() ;
問題的引出:現在使用一個接口,同時定義出子類,通過子類為接口進行執行個體化:
interface Fruit{
public void eat() ;
class Apple implements Fruit{
public void eat(){
System.out.println("吃蘋果。。。") ;
public class Demo07{
Fruit f = new Apple() ;
f.eat() ;
以上代碼存在問題?
· main方法實際上相當于是一個用戶端程式
· 如果現在需要換一個子類了,那麼就要修改用戶端。
· 好的程式:某一處的更改不影響調用處
造成以上問題的根源:
· 子類直接在用戶端使用,耦合度太深了。
在對象執行個體化的中間加入一個過渡端,所謂的解耦合最大的特點就是永遠有一個過渡端。
那麼現在加入一個過渡端:
class Cherry implements Fruit{
System.out.println("吃櫻桃。。。") ;
<b>class Factory{</b>
<b> public static Fruit getInstance(String str){</b>
<b> Fruit f = null ;</b>
<b> if("apple".equals(str)){</b>
<b> f = new Apple() ;</b>
<b> }</b>
<b> if("cherry".equals(str)){</b>
<b> f = new Cherry() ;</b>
<b> return f ;</b>
<b> }</b>
<b>};</b>
public class Demo08{
Fruit f = Factory.getInstance(args[0]) ;
if(f!=null)
f.eat() ;
此時,發現程式的用戶端沒有任何的改變,而直接可以選擇各種所要的子類。那麼通過工廠取得全部的接口執行個體,那麼以後修改的時候就可以隻修改工廠了。
<b>差別點</b>
<b>抽象類</b>
<b>接口</b>
<b>定義</b><b></b>
abstract class 抽象類名稱{}
interface 接口名稱{}
<b>概念</b><b></b>
包含一個抽象方法的類就是抽象類,除此之外還包含常量、變量、普通方法、構造方法
隻包含全局常量和抽象方法的類稱為接口
<b>使用</b><b></b>
需要通過子類繼承
class 子類 extends 父類
需要通過子類實作
class 子類 implements 接口
<b>關系</b><b></b>
一個抽象類可以實作多個接口,一個接口不能繼承一個抽象類
<b>作用</b><b></b>
提供了一個模闆
提供了一個标準,或者說表示了一種能力
<b>設計模式</b><b></b>
模闆設計模式
工廠設計模式、代理設計模式
擴充卡設計模式
<b>限制</b><b></b>
抽象類有單繼承局限
無此局限
<b>應用</b><b></b>
如果抽象類與接口同時都可以使用,優先使用接口
<b>特殊點</b><b></b>
一個抽象類可以包含一個接口或一個抽象類
一個接口中也可以包含抽象類或接口
<b>特殊點:</b>
1、 一個抽象類中能否包含一個接口?可以
abstract class A{
public abstract void printA() ;
interface B{
public void printB() ;
class DA extends A{
public void printA(){}
class DB implements B{
public void printB(){}
};
2、 一個接口中能否包含一個抽象類?可以
abstract class B{
public abstract void printB() ;
class DA implements A{
class DB extends B{
觀察以下的題目,寫出輸出結果:
public A(){
this.print() ;
public abstract void print() ;
class B extends A{
private int i = 10 ;
public B(int i){
this.i = i ;
public void print(){
System.out.println(this.i) ;
public class Demo11{
public static void main(String artgs[]){
new B(100) ;
答案是0
子類對象執行個體化之前,肯定要先去調用父類中的無參構造方法,為父類中的屬性初始化,但是父類中的方法未調用完之前,子類的内容并沒有初始化,如果沒有初始化,則會安排預設值,預設值就是“0”。
本文轉自 李興華 51CTO部落格,原文連結:http://blog.51cto.com/lixinghua/96923,如需轉載請自行聯系原作者