一文总结:抽象类(abstract)与接口(interface)的特点和代码展示
文章目錄
- 1. 什么是抽象類?
- 2. 抽象類與抽象方法的特點(diǎn)
- 3. 抽象類的應(yīng)用
- 4. 什么是接口?
- 5.接口的特點(diǎn)
- 6.接口面試題
- 7.抽象類與接口的對(duì)比
本篇文章已同步到:https://www.bithachi.cn/posts/77de2e90.html
1. 什么是抽象類?
隨著繼承層次中一個(gè)個(gè)新子類的定義,類變得越來(lái)越具體,而父類則更一般,更通用。類的設(shè)計(jì)應(yīng)該保證父類和子類能夠共享特征。有時(shí)將一個(gè)父類設(shè)計(jì)得非常抽象,以至于它沒(méi)有具體的實(shí)例,這樣的類叫做抽象類。
抽象類的出現(xiàn)使面向?qū)ο蟾右?guī)范,比如人是一個(gè)抽象的概念,沒(méi)有具體的對(duì)象,我們應(yīng)該將其抽象成一個(gè)類,它無(wú)法生成對(duì)象實(shí)例,卻擁有一些人通用的屬性和方法。有些方法人類都是一樣的行為,比如說(shuō)都是用嘴吃飯,用耳朵聽(tīng)聲音等;但有些則不是,比如工作,不同的崗位人們有不同的工作行為,那么這些行為的具體實(shí)現(xiàn)在子類完成,Person父類只負(fù)責(zé)定義。
2. 抽象類與抽象方法的特點(diǎn)
- 用abstract關(guān)鍵字來(lái)修飾一個(gè)類,這個(gè)類叫做抽象類。
- 抽象類可以有構(gòu)造器,可以使用this關(guān)鍵字,子類可以使用super關(guān)鍵字
- 用abstract來(lái)修飾一個(gè)方法,該方法叫做抽象方法。抽象方法只能聲明,具體實(shí)現(xiàn)應(yīng)該交給子類完成
抽象方法:只有方法的聲明,沒(méi)有方法的實(shí)現(xiàn)。以分號(hào)結(jié)束:
比如:public abstract void talk(); - 抽象類中不一定包含抽象方法,但是含有抽象方法的類必須被聲明為抽象類。
- 抽象類不能被實(shí)例化。抽象類是用來(lái)被繼承的,抽象類的子類必須定義父類的抽象方法,并提供方法體。若沒(méi)有定義全部的抽象方法,仍為抽象類。
- 不能用abstract修飾變量、代碼塊、構(gòu)造器;
- 不能用abstract修飾私有(private)方法、靜態(tài)(static)方法、final的方法、final的類
- 抽象類可以引用非抽象類的子類對(duì)象,并調(diào)用子類實(shí)現(xiàn)抽象類定義的方法和抽象類本身不是抽象的方法。
運(yùn)行結(jié)果:
可以有代碼塊 B類中定義的m1方法 B類中重寫的的m2方法 A類中定義的m2方法 A類中的屬性a=303. 抽象類的應(yīng)用
抽象類的應(yīng)用與多態(tài)應(yīng)用相關(guān)聯(lián)。
抽象類體現(xiàn)的是一種模板模式的設(shè)計(jì),抽象類作為多個(gè)子類的通用模板,子類在抽象類的基礎(chǔ)上進(jìn)行擴(kuò)展、改造,但子類總體上會(huì)保留抽象類的行為方式。
抽象類解決的問(wèn)題:
模板方法設(shè)計(jì)模式是編程中經(jīng)常用得到的模式。各個(gè)框架、類庫(kù)中都有他的影子,比如常見(jiàn)的有:
4. 什么是接口?
- 接口(英文:Interface),在JAVA編程語(yǔ)言中是一個(gè)抽象類型,是抽象方法的集合,接口通常以interface來(lái)聲明。
- 有時(shí)必須從幾個(gè)類中派生出一個(gè)子類,繼承它們所有的屬性和方法。但是,Java不支持多重繼承。有了接口,就可以得到多重繼承的效果。
- 有時(shí)必須從幾個(gè)類中抽取出一些共同的行為特征,而它們之間又沒(méi)有is-a的關(guān)系,僅僅是具有相同的行為特征而已。
- 接口就是規(guī)范,定義的是一組規(guī)則,體現(xiàn)了現(xiàn)實(shí)世界中“如果你是/要…則必須能…”的思想。繼承是一個(gè)"是不是"的關(guān)系,而接口實(shí)現(xiàn)則是 "能不能"的關(guān)系。
5.接口的特點(diǎn)
- 接口(interface)是抽象方法和全局常量值定義的集合(jdk8之前)。jdk8之后可以定義static和default的方法和方法體
- 接口的特點(diǎn):
- 用interface來(lái)定義。
- 接口中沒(méi)有構(gòu)造器。
- 接口不能用于實(shí)例化對(duì)象。
- 接口中不能擁有代碼塊
- 接口中的所有成員變量都默認(rèn)是由public static final修飾的。
- 接口中的所有抽象方法都默認(rèn)是由public abstract修飾的。
- 一個(gè)類可以實(shí)現(xiàn)多個(gè)接口,接口也可以繼承(extends)其它一個(gè)或多個(gè)接口。
- 定義Java類的語(yǔ)法格式:先寫extends,后寫implements
class SubClass extends SuperClass implements InterfaceA{ } - 實(shí)現(xiàn)接口的類中必須提供接口中所有方法的具體實(shí)現(xiàn)內(nèi)容,方可實(shí)例化。否則,仍為抽象類。
- 接口的主要用途就是被實(shí)現(xiàn)類實(shí)現(xiàn)。(面向接口編程)
- 與繼承關(guān)系類似,接口與實(shí)現(xiàn)類之間存在多態(tài)性
- 接口和類是并列關(guān)系,或者可以理解為一種特殊的類。從本質(zhì)上講,接口是一種特殊的抽象類,這種抽象類中只包含常量和方法的定義(JDK7.0及之前),而沒(méi)有變量和方法的實(shí)現(xiàn)。
接口的定義舉例:
JDK8中關(guān)于接口的改進(jìn):
-
Java 8中,你可以為接口添加靜態(tài)方法和默認(rèn)方法。從技術(shù)角度來(lái)說(shuō),這是完全合法的,只是它看起來(lái)違反了接口作為一個(gè)抽象定義的理念。
-
靜態(tài)方法:使用 static 關(guān)鍵字修飾。可以通過(guò)接口直接調(diào)用靜態(tài)方法,并執(zhí)行其方法體。我們經(jīng)常在相互一起使用的類中使用靜態(tài)方法??梢栽跇?biāo)準(zhǔn)庫(kù)中找到像Collection/Collections或者Path/Paths這樣成對(duì)的接口和類。
-
默認(rèn)方法:默認(rèn)方法使用 default 關(guān)鍵字修飾。可以通過(guò)實(shí)現(xiàn)類對(duì)象來(lái)調(diào)用。我們?cè)谝延械慕涌谥刑峁┬路椒ǖ耐瑫r(shí),還保持了與舊版本代碼的兼容性。比如:java 8 API中對(duì)Collection、List、Comparator等接口提供了豐富的默認(rèn)方法。
- 若一個(gè)接口中定義了一個(gè)默認(rèn)方法,而另外一個(gè)接口中也定義了一個(gè)同名同參數(shù)的方法(不管此方法是否是默認(rèn)方法),在實(shí)現(xiàn)類同時(shí)實(shí)現(xiàn)了這兩個(gè)接口時(shí),會(huì)出現(xiàn): ·接口沖突·。
解決辦法:實(shí)現(xiàn)類必須覆蓋接口中同名同參數(shù)的方法,來(lái)解決沖突。 - 若一個(gè)接口中定義了一個(gè)默認(rèn)方法,實(shí)現(xiàn)其接口的類的父類中也定義了一個(gè)同名同參數(shù)的非抽象方法,則不會(huì)出現(xiàn)沖突問(wèn)題。因?yàn)榇藭r(shí)遵守: 類優(yōu)先原則。接口中具有相同名稱和參數(shù)的默認(rèn)方法會(huì)被忽略。
-
接口中靜態(tài)方法和默認(rèn)方法必須給出方法體,不能只定義
根據(jù)接口的特點(diǎn),綜合舉例:
/************ 一個(gè)類可以實(shí)現(xiàn)多個(gè)無(wú)關(guān)的接口 ************/interface Runner {int a=10;public void run();//jdk8之前只能聲明非static和defult的方法static void fun2() {//jdk8之后可以定義static和defult的方法,不能聲明,必須給出方法體System.out.println("interface Runner static fun2");}default void fun3(){System.out.println(this.a);//可以使用this,但是不能更改其值,因?yàn)槟J(rèn)缺省public static finalSystem.out.println("interface Runner default fun3");} }interface Swimmer {public double swim();default void fun3(){System.out.println("interface Swimmer default fun3");}default void skip(){System.out.println("interface Swimmer default skip");} }class Creator{public void eat() {System.out.println("eat");}public void skip(){System.out.println("class Creator skip");} }class Man extends Creator implements Runner ,Swimmer{public void run() {System.out.println("run");}public double swim() {System.out.println("swim");return 1.1d;}public void fun3(){System.out.println("class Man fun3");//類覆蓋兩個(gè)接口中默認(rèn)的方法fun3()Runner.super.fun3();//調(diào)用原接口中默認(rèn)的方法Swimmer.super.fun3();} }class Test{public static void main(String args[]){Test t = new Test();Man m = new Man();t.m1(m);//接口多態(tài)引用,與繼承關(guān)系類似,接口與實(shí)現(xiàn)類之間存在多態(tài)性t.m2(m);t.m3(m);System.out.println("-----------");Runner.fun2();System.out.println("-----------");System.out.println(Runner.a);System.out.println("-----------");m.fun3();System.out.println("-----------");m.skip();}public void m1(Runner f) {//接口多態(tài)引用f.run();}public void m2(Swimmer s) {//接口多態(tài)引用s.swim();}public void m3(Creator a) {//接口多態(tài)引用a.eat();} }運(yùn)行結(jié)果:
run swim eat ----------- interface Runner static fun2 ----------- 10 ----------- class Man fun3 10 interface Runner default fun3 interface Swimmer default fun3 ----------- class Creator skip6.接口面試題
題一:
interface A {int x = 0; }class B {int x = 1; }class C extends B implements A {public void pX() {System.out.println(x);//ErrorSystem.out.println(super.x);//1System.out.println(A.x);//0}public static void main(String[] args) {new C().pX();} }7.抽象類與接口的對(duì)比
總結(jié)
以上是生活随笔為你收集整理的一文总结:抽象类(abstract)与接口(interface)的特点和代码展示的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 一篇文章全方位了解:static ma
- 下一篇: 一篇搞定异常: Exception