一弃秆、抽象類
1丧诺、抽象方法
抽象方法只有聲明入桂,而沒有具體的實(shí)現(xiàn)。也就是說沒有{}驳阎。
抽象方法的聲明格式為:abstract void 方法名();
2抗愁、抽象類
包含一個(gè)抽象方法的類就是抽象類 使用abstract類就是抽象類
3、特點(diǎn)
1.抽象類與抽象方法必須使用abstract修飾
2.抽象類不允許創(chuàng)建對象
3.抽象類總可以有抽象方法也可以沒有抽象方法.如果抽象類中有帶主體方法子類繼承也可以直直接用
4.抽象類的子類使用
??? a.繼承抽象類,重寫抽象方法
??? b.抽象類的子類也可是抽象類
4.格式
public?abstract?class?People {?//關(guān)鍵詞abstract呵晚,聲明該類為抽象類
?????? public?int?age;
?????? public?void?Num() {
?????? }
?????? public?abstract?Name();?//聲明該方法為抽象方法
}
注意:
abstract不能與final并列修飾同一個(gè)類
abstract 不能與private蜘腌、static、final或native并列修飾同一個(gè)方法饵隙。
5.使用
在下面這個(gè)例子中撮珠,把打印機(jī)類封裝成抽象類,把print定義成抽象類金矛,當(dāng)HPPrinter和CannonPrinter要繼承printer類的時(shí)候芯急,必須重寫print函數(shù)。這樣寫的好處是驶俊,每個(gè)打印機(jī)都有自己打印方式志于,此舉可以防止子類沒有寫明打印方式。
public?abstract?void?Printer() {
?????? public?void?open() {
??????????? system.out.print("打印機(jī)開啟");
??????? }
??????? public?void close() {
??????????? system.out.print("打印機(jī)關(guān)閉");
??????? }
??????? abstract?void?print();?//把print方法定義為抽象方法
? }
public?HPPrinter?extends?Printer {
???????? void?print(){?//必須重寫抽象方法print()??
??????????????? system.out.print("惠普打印機(jī)開始打印");
????????? };
}
public?CanonPrinter?extends?Printer {
???? void?print(){?//必須重寫抽象方法print()
????????????? system.out.print("佳能打印機(jī)開始打印");
????? };
}
接口
接口可以理解為一種特殊的類废睦,里面全部是由全局常量和公共的抽象方法組成
1.格式
public interface?interface 接口名稱{
? ? ? 全局常量
? ? ? 抽象方法
}
2.特點(diǎn)
1.使用關(guān)鍵字interface
2.接口的實(shí)現(xiàn)也必須通過子類,使用關(guān)鍵字implements养泡,而且接口是可以多實(shí)現(xiàn)的
class?A?implements?Inter1,Inter2{?//Inter1和Inter2是接口???
?? ...
}
3.一個(gè)類可以同時(shí)繼承抽象類和接口
class?A?extends?Abs?implements?Inter1,Inter2{?//Abs是一個(gè)抽象類???
??? ...
}
4.一個(gè)接口不能繼承普通的類嗜湃,但可以通過extends關(guān)鍵字繼承多個(gè)接口,實(shí)現(xiàn)接口的多繼承
interface?Inter?extends?Inter1,Inter2{?//Inter澜掩、Inter1购披、Inter2都為接口??
? ?? ...
}
5.接口中可以含有 變量和方法。但是要注意肩榕,接口中的變量會被隱式地指定為public static final變量(并且只能是public static final變量刚陡,用private修飾會報(bào)編譯錯(cuò)誤)惩妇,而方法會被隱式地指定為public abstract方法且只能是public abstract方法(用其他關(guān)鍵字,比如private筐乳、protected歌殃、static、 final等修飾會報(bào)編譯錯(cuò)誤)
6.無構(gòu)造方法
抽象類和接口的區(qū)別
一蝙云、語義層次
public?abstract?class?People {?//關(guān)鍵詞abstract氓皱,聲明該類為抽象類
????? void?Num();
????? abstract?void?Name(); //聲明該方法為抽象方法
}
Interface Person {
?????? void?Num();
?????? void?Name();
}
一、抽象類方式中勃刨,抽象類可以擁有任意范圍的成員數(shù)據(jù)波材,同時(shí)也可以擁有自己的非抽象方法,但是接口方式中身隐,它僅能夠有靜態(tài)廷区、不能修改的成員數(shù)據(jù)(但是我們一般是不會在接口中使用成員數(shù)據(jù)),同時(shí)它所有的方法都必須是抽象的贾铝。
二隙轻、在某種程度上來說,接口是抽象類的特殊化忌傻。
三大脉、對子類而言,它只能繼承一個(gè)抽象類(這是java為了數(shù)據(jù)安全而考慮的)水孩,但是卻可以實(shí)現(xiàn)多個(gè)接口镰矿。
二、設(shè)計(jì)層次
1俘种、 抽象層次不同
抽象類是對類抽象秤标,而接口是對行為的抽象。抽象類是對整個(gè)類整體進(jìn)行抽象宙刘,包括屬性苍姜、行為,但是接口卻是對類局部(行為)進(jìn)行抽象悬包。
2衙猪、 跨域不同
抽象類所跨域的是具有相似特點(diǎn)的類,而接口卻可以跨域不同的類布近。我們知道抽象類是從子類中發(fā)現(xiàn)公共部分垫释,然后泛化成抽象類,子類繼承該父類即可撑瞧,但是接口不同棵譬。實(shí)現(xiàn)它的子類可以不存在任何關(guān)系,共同之處预伺。例如貓订咸、狗可以抽象成一個(gè)動物類抽象類曼尊,具備叫的方法。鳥脏嚷、飛機(jī)可以實(shí)現(xiàn)飛Fly接口骆撇,具備飛的行為,這里我們總不能將鳥然眼、飛機(jī)共用一個(gè)父類吧艾船!所以說抽象類所體現(xiàn)的是一種繼承關(guān)系,要想使得繼承關(guān)系合理高每,父類和派生類之間必須存在"is-a" 關(guān)系屿岂,即父類和派生類在概念本質(zhì)上應(yīng)該是相同的。對于接口則不然鲸匿,并不要求接口的實(shí)現(xiàn)者和接口定義在概念本質(zhì)上是一致的爷怀, 僅僅是實(shí)現(xiàn)了接口定義的契約而已。
3带欢、 設(shè)計(jì)層次不同
對于抽象類而言运授,它是自下而上來設(shè)計(jì)的,我們要先知道子類才能抽象出父類乔煞,而接口則不同吁朦,它根本就不需要知道子類的存在,只需要定義一個(gè)規(guī)則即可渡贾,至于什么子類逗宜、什么時(shí)候怎么實(shí)現(xiàn)它一概不知。比如我們只有一個(gè)貓類在這里空骚,如果你這是就抽象成一個(gè)動物類纺讲,是不是設(shè)計(jì)有點(diǎn)兒過度?我們起碼要有兩個(gè)動物類囤屹,貓熬甚、狗在這里,我們在抽象他們的共同點(diǎn)形成動物抽象類吧肋坚!所以說抽象類往往都是通過重構(gòu)而來的乡括!但是接口就不同,比如說飛智厌,我們根本就不知道會有什么東西來實(shí)現(xiàn)這個(gè)飛接口粟判,怎么實(shí)現(xiàn)也不得而知,我們要做的就是事前定義好飛的行為接口峦剔。所以說抽象類是自底向上抽象而來的,接口是自頂向下設(shè)計(jì)出來的角钩。
實(shí)例:
現(xiàn)在有個(gè)鳥類吝沫,鳥的屬性有種類呻澜,顏色,重量等惨险,鳥的行為有吃羹幸,飛。但是有的鳥類只會奔跑不會飛(鴕鳥)辫愉。這時(shí)如果我們在一個(gè)Birds類中去定義飛和奔跑的行為栅受,分別讓只會飛的鳥和只會奔跑的鳥都去繼承這個(gè)類,好像有些不太妥當(dāng)恭朗。我們可以這樣解決:定義一個(gè)抽象類屏镊,屬性包括種類、顏色痰腮、重量而芥,行為包括吃。在定義一個(gè)Fly接口膀值,包含一個(gè)方法fly()棍丐。在定義一個(gè)Run接口,包含一個(gè)run()方法沧踏。如果只是會飛的鳥我們就繼承Birds類歌逢,實(shí)現(xiàn)Fly接口。如果只是會奔跑的鳥我們就實(shí)現(xiàn)Birds類翘狱,實(shí)現(xiàn)Run接口秘案。如果繼承Birds類,實(shí)現(xiàn)了Fly和Run接口盒蟆,那就是又會飛又會奔跑的鳥踏烙。實(shí)現(xiàn)代碼如下:
定義鳥的抽象類其中用3個(gè)成員變量一個(gè)eat的抽象方法,一個(gè)print方法
public?abstract?class?Birds?{?
???????? private?String?type;?
???????? private?String?color;?
???????? private?double?weight;????????? public?Birds(String?type,?String?color,?double?weight){?
??????????????? this.setType(type);?
?????????????? this.setColor(color);?
?????????????? this.setWeight(weight);?
? ? ? ? ?? }????????? public?abstract?void?eat();
???????? public?void?print(){?
????????????? System.out.println("種類:"+this.getType());?
????????????? System.out.println("顏色:"+this.getColor());?
????????????? System.out.println("重量:"+this.getWeight());?
? ? ? ? }?????? public?String?getType()?{?
???????? ? ? return?type;?
?? ? ? }
? ? ? public?void?setType(String?type)?{?
????? ?? ?? this.type?=?type;
? ? ?? }?
????? public?String?getColor()?{?
????????? return?color;?
?????? }?
?????? public?void?setColor(String?color)?{?
????????? this.color?=?color;?
? ? ?? }?
???? public?double?getWeight()?{?
??????? return?weight;?
???? }?
??? public?void?setWeight(double?weight)?{?
??????? this.weight?=?weight;?
??? }?
}
定義飛的接口
public?interface?Fly?{?
??? void?fly();?
}?
定義跑的接口
public?interface?Run?{?
??? void?run();?
}?
/**
*?蜂鳥 繼承抽象類,實(shí)現(xiàn)Fly的接口
*/?
public?class?HummingBird?extends?Birds?implements?Fly?{
???? public?HummingBird(String?type,?String?color,?double?weight){?
???????? super(type,?color,?weight);?
???? }??? @Override?
??? public?void?fly()?{
??????? //實(shí)現(xiàn)飛接口中的方法
??????? System.out.println("我是"+this.getType()+",我會fly。");?
??? }??? @Override?
?? public?void?eat()?{
?? //實(shí)現(xiàn)抽象類中的抽象方法
? ? System.out.print("我是"+this.getType()+",我吃花蜜历等。");?
?? }?
}?
/**
*?鴕鳥
*/??public?class?OstrichBirds?extends?Birds?implements?Run?{
?????? public?OstrichBirds(String?type,?String?color,?double?weight)?{?
?????????? super(type,?color,?weight);?
? ? ? ? }????? @Override
?????? public?void?run()?{?
?????? System.out.println("我是"+this.getType()+",我會奔跑讨惩。");?
?????? }? ???????? @Override?
?????? public?void?eat()?{?
?????? System.out.println("我是"+this.getType()+",我吃草。");?
????? }?
}?
public?class?Test?{?
???? public?static?void?main(String?[]?args){?
????????? //蜂鳥?
???????? Birds?hummingBirds?=new?HummingBird("蜂鳥",?"彩虹色",?2.3);?
? ? ? ?? hummingBirds.print();?
???????? hummingBirds.eat();?
???????? Fly?f?=?(Fly)?hummingBirds;?
???????? f.fly();???????? //鴕鳥?
??????? OstrichBirds?ostrichBirds?=new?OstrichBirds("鴕鳥",?"灰色",?200.2);?
??????? ostrichBirds.print();?
??????? ostrichBirds.eat();?
??????? ostrichBirds.run();???????? System.out.println("是否會飛=>"+(hummingBirds?instanceof?Fly));?
??????? }
}?