抽象類、接口與類是一個層次的概念,是java中極其重要的概念。
抽象類是從多個類中抽象出來的公共模板,提供子類均具有的功能。
接口是從多個類中抽象出來的規范,體現的是規范和實現分離的原則,同時也有效的解決了java單重繼承的缺陷
二、抽象類2.1、抽象類與普通類的區別/* * 抽象類 */public abstract class Person1 {}/* * 普通類 */public class Person {} /* * 抽象方法 */ public abstract void show(); //沒有方法體/* * 普通方法 */ public void show(){ System.out.2.3、完整對比2個類package com.pb.demo3;/* * 普通類 */public class Person { private String name; //名稱 private int age ; //年齡 /* * 普通方法 */ public void show(){ System.out.println("這是個普通方法"); } /* * 普通類中不能有抽象方法 */ //setter/getter方法 public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }package com.pb.demo3;/* * 抽象類 */public abstract class Person1 { private String name; //名稱 private int age ; //年齡 /* * 抽象方法 */ public abstract void show(); //沒有方法體 //抽象類中可以有普通方法 public void printSelf(){ System.out.println("這是個抽象類中的普通方法"); } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }2.4、如果抽象類被繼承- 如果子類不是抽象類,則必須重寫父類抽象類的全部抽象方法。(普通方法選擇重寫或者不寫)
package com.pb.demo3;/* * 學生類繼承Person1抽象類 */public class Student extends Person1 { //繼承時,會強制要求重寫父類的抽象方法 @Override public void show() { System.out.println("重寫父類的抽象方法"); }}2.5 、一些注意事項- abstract不能與final關鍵字一起使用
- private 關鍵字不能修飾抽象方法
- abstract修飾的抽象方法沒有方法體
2.6、圖像對比
三、接口3.1、接口定義接口使用interface關鍵字來定義
簡單的說,接口是一個不能實例化,且只能擁有抽象方法的類型
public interface 接口名稱{抽象方法}public interface Person {}package com.pb.demo4;public interface Person { /* * 定義2個抽象方法 */ public void run(); public void say();}3.2.為什么接口中的抽象方法不用使用abstract關鍵字?因為接口中只能有抽象方法,所以不必專門使用abstract關鍵字來修飾,當然也可以加上不過完全沒有必要
3.3、接口的抽象方法接口的抽象方法只能由public來修飾
四、使用抽象類和接口4.1、抽象類使用繼承來實現/* * 抽象類 */public abstract class Person { /* * 普通方法 */ public void run(){ System.out.println("抽象類的普通方法! 走一走"); } /* * 抽象方法 */ public abstract void say();}/* * 繼承抽象類 */public class Student extends Person{ @Override public void say() { System.out.println("實現父類的抽象方法!說一說"); }}public class Test { public static void main(String[] args) { //聲明子類對象 Student stu=new Student(); //調用子類重寫的方法 stu.say(); //調用父類的普通方法 stu.run(); }}結果:
實現父類的抽象方法!說一說抽象類的普通方法! 走一走
4.2、接口的使用使用implements來實現接口,解決java中單繼承的關系,接口可以是多個
package com.pb.demo4;public interface Person { /* * 定義2個抽象方法 */ public void run(); public void say();}package com.pb.demo4;/* * 實現接口Person */public class PersonImp implements Person { /* * 必須重寫接口的全部抽象方法 */ @Override public void run() { System.out.println("實現接口的走一走抽象方法"); } @Override public void say() { System.out.println("實現接口的說一說抽象方法"); }}package com.pb.demo4;public class Test { public static void main(String[] args) { //聲明對象 PersonImp p=new PersonImp(); //調用實現的方法 p.run(); p.say(); }}結果:
實現接口的走一走抽象方法實現接口的說一說抽象方法
4.3 、對比實現
五、抽象類和接口的簡單區別5.1、區別- 抽象類使用abstract聲明,接口使用interface聲明
- 抽象類可以有抽象方法也可以有普通方法,接口只能有抽象方法
- 實現方式不同:抽象類使用繼承extends來實現,接口使用implements來實現
5.2、相同點- 抽象類和接口都不能實例化
5.3、圖形對比
5.4、使用規則- 抽象類和接口都不能實例化
- 抽象類與接口分別被繼承與實現的場合,其子類必須實現其中的抽象方法
- 抽象類中的抽象方法訪問修飾符不能為private,接口中的抽象方法訪問修飾符必須為public

六、簡單實現抽象類package com.pb.demo5;/* * 鳥類抽象類 */public abstract class Bird { /* * 飛的普通方法 */ public void fly(){ System.out.println("彈射飛!"); } /* * 攻擊抽象方法 */ public abstract void attack(); }package com.pb.demo5;/* * 火箭鳥 */public class RocketBird extends Bird { /* * 重寫攻擊方法 */ @Override public void attack() { System.out.println("火箭鳥攻擊方式:加速沖撞!"); } }package com.pb.demo5;/* * 分裂鳥 */public class SplittBird extends Bird { /* * 重寫攻擊方法 */ @Override public void attack() { System.out.println("分裂鳥攻擊方式:分裂攻擊!"); } }package com.pb.demo5;public class Test { public static void main(String[] args) { /* * 多態的應用 */ //創建鳥類對象,實例化為分裂鳥對象 Bird splitbird=new SplittBird(); //創建鳥類對象,實例化為火箭鳥對象 Bird rocketbird=new RocketBird(); //分別調用鳥類的普通飛的方法 //分別調用子類重寫后的叫方法 //分別調用子類重寫后的攻擊方法 splitbird.fly(); splitbird.attack(); rocketbird.fly(); rocketbird.attack(); }}結果:
彈射飛!分裂鳥攻擊方式:分裂攻擊!彈射飛!火箭鳥攻擊方式:加速沖撞!
從上例子中可以看出:子類相同的方法,如:飛的方法 可以放在父類的抽象類中使用普通方法實現,實現代碼的重用,而不同的部分,使用抽象方法,子類來實現自己的方法,簡單來講:抽象類就是抽取公共的部分在抽象來中來實現
如:完全沒有相同的方法,但都有這此方法,該怎么實現呢?這時候就需要接口大神出場
七、簡單接口實現還是以上例為例,比如,連有叫的方法,但每種 鳥的叫聲都不一樣呢?有的會叫,有的不會叫,
package com.pb.demo5;/* * 叫的接口 */public interface Shout { /* * 叫的方法 */ public void shout();}package com.pb.demo5;public class AoShoutImpl implements Shout { @Override public void shout() { System.out.println("嗷嗷叫!"); }}package com.pb.demo5;public class ZhaShoutImpl implements Shout { @Override public void shout() { System.out.println("喳喳叫!"); }}package com.pb.demo5;public class NoCanShoutImpl implements Shout { @Override public void shout() { System.out.println("不會叫!"); }}package com.pb.demo5;/* * 鳥類抽象類 */public abstract class Bird { Shout shout; /* * 構造方法 */ public Bird(Shout shout) { super(); this.shout = shout; }/* * 叫的普通方法 */ public void shout(){ //調用自身叫的方法 shout.shout(); } /* * 飛的普通方法 */ public void fly(){ System.out.println("彈射飛!"); } /* * 抽象攻擊方法 */ public abstract void attack(); }package com.pb.demo5;/* * 炸彈鳥 */public class Bombbird extends Bird { public Bombbird(Shout shout) { super(shout); } @Override public void attack() { System.out.println("炸彈鳥攻擊方式:炸彈攻擊"); } @Override public void shout() { System.out.println("炸彈鳥:喳喳叫!"); }}package com.pb.demo5;/* * 胖子鳥 */public class Fatbird extends Bird { public Fatbird(Shout shout) { super(shout); } @Override public void attack() { System.out.println("胖子鳥攻擊方式:下蛋攻擊"); } @Override public void shout() { System.out.println("胖子鳥:不會叫!"); }}package com.pb.demo5;/* * 紅色鳥 */public class Redbird extends Bird { public Redbird(Shout shout) { super(shout); } @Override public void attack() { System.out.println("紅色鳥攻擊方式:普通攻擊"); } @Override public void shout() { System.out.println("紅色鳥:喳喳叫!"); }}package com.pb.demo5;import com.pb.demo5.Bird;/* * 火箭鳥 */public class RocketBird extends Bird { public RocketBird(Shout shout) { super(shout); } /* * 重寫攻擊方法 */ @Override public void attack() { System.out.println("火箭鳥攻擊方式:加速沖撞!"); } /* * 重寫叫的方法 */ @Override public void shout() { System.out.println("火箭鳥:嗷嗷叫!"); } }package com.pb.demo5;/* * 分裂鳥 */public class SplittBird extends Bird { public SplittBird(Shout shout) { super(shout); } /* * 重寫攻擊方法 */ @Override public void attack() { System.out.println("分裂鳥攻擊方式:分裂攻擊!"); } /* * 重寫叫的方法 */ @Override public void shout() { System.out.println("分裂鳥:嗷嗷叫!"); }}package com.pb.demo5;import com.pb.demo5.Bird;public class Test { public static void main(String[] args) { /* * 創建接口對象 */ Shout aoshout=new AoShoutImpl(); Shout zhashout=new ZhaShoutImpl(); Shout noshout=new NoCanShoutImpl(); /* * 多態的應用 */ //創建鳥類對象,實例化為分裂鳥對象 Bird splitbird=new SplittBird(aoshout); Bird rocketbird=new RocketBird(aoshout); Bird bomb=new Bombbird(zhashout); Bird redbird=new Redbird(zhashout); Bird fatbird=new Fatbird(noshout); splitbird.fly(); splitbird.attack(); splitbird.shout(); rocketbird.fly(); rocketbird.shout(); rocketbird.attack(); bomb.fly(); bomb.shout(); bomb.attack(); redbird.fly(); redbird.shout(); redbird.attack(); fatbird.fly(); fatbird.shout(); fatbird.attack(); }}結果:
彈射飛!分裂鳥攻擊方式:分裂攻擊!分裂鳥:嗷嗷叫!彈射飛!火箭鳥:嗷嗷叫!火箭鳥攻擊方式:加速沖撞!彈射飛!炸彈鳥:喳喳叫!炸彈鳥攻擊方式:炸彈攻擊彈射飛!紅色鳥:喳喳叫!紅色鳥攻擊方式:普通攻擊彈射飛!胖子鳥:不會叫!胖子鳥攻擊方式:下蛋攻擊
由上可以看出:抽象類方便代碼復用,接口方便代碼維護
新聞熱點
疑難解答