Java抽象類與接口超詳細圖文解析
前言
在Java面向?qū)ο缶幊讨?,抽象類和接口是兩個非常重要的概念,它們?yōu)榇a的抽象化、模塊化和可擴展性提供了強大的支持。無論是開發(fā)大型企業(yè)級應(yīng)用,還是小型程序,掌握抽象類和接口的使用都至關(guān)重要。本文將通過詳細的理論講解、豐富的代碼示例、直觀的圖片以及對比表格,幫助你深入理解Java抽象類和接口的本質(zhì)與應(yīng)用。
一、抽象類
1.什么是抽象類
在面對對象的概念中,所以對象都是通過類來描述的,但并不是所有的類都是用來描述對象的,如果一個類中沒有包含足夠的信息來描述一個具體的對象,這樣的類就是抽象類
Dog類和Cat類都屬于Animal類,但Dog()和Cat()方法沒有實際的行為,可以將他們設(shè)計成
抽象方法
,包含抽象方法的類就是抽象類
。
2.抽象類語法
在Java中,被abstract
修飾的類稱抽象類,抽象類中,被abstract
修飾的方法稱為抽象方法,抽象方法不用給出具體的實現(xiàn)體。
public abstract class Animal { abstract public void eat();//抽象方法:被abstract修飾,沒有方法體 public double show(){ //自己增加的方法 return show1; } protected double show1;//參數(shù) }
3.抽象類特征
3.1 抽象類不能實例化對象
public abstract class Animal { Animal animal = new Animal(); }
3.2 抽象方法不能是private的
public abstract class Animal { abstract private void eat();//抽象方法:被abstract修飾,沒有方法體 }
3.3 抽象方法不能被final和static修飾,因為抽象方法要被子類重寫
abstract final void eat(); abstract public static void eat();
3.4 抽象類必須被繼承,并且繼承后子類要重寫父類的抽象方法,除非子類也是抽象類,用abstract修飾
public abstract class Cat extends Animal { @Override public void eat(){ } }
public abstract class Cat extends Animal { @Override public abstract void eat(); }
3.5 抽象類中不?定包含抽象?法,但是有抽象?法的類?定是抽象類
3.6 抽象類中可以有構(gòu)造?法,供?類創(chuàng)建對象時,初始化?類的成員變量
4.抽象類的作用
抽象類本身不能被實例化,只能創(chuàng)建子類,并且重寫抽象方法,這就起到檢驗的作用
二、接口
1.什么是接口?
字面意思:我們生活中的水龍頭,插座,充電線都是有接口的,才能插上。
接口
就是公共的行為規(guī)范標(biāo)準(zhǔn),在實現(xiàn)時,只要符合規(guī)范標(biāo)準(zhǔn),就能通用
2.語法規(guī)則
接口的定義和類基本相同,將class
換成interface
關(guān)鍵字
public interface IShape { public static final int SIZE = 100;//接口變量默認(rèn)public static final public abstract void test();//接口方法默認(rèn)public abstract }
【注意】
- 接口命名一般以大寫字母
I
開頭;- 接口不能被實例化;
3.接口的使用
類與接口之間是implements的關(guān)系
public class 類名 implenments 接口名{ //... }
這里建立一個IUSB接口和Mouse類
public interface IUSB { void openDevice(); void closeDevice(); }
public class Mouse implements IUSB{ @Override public void openDevice() { System.out.println("打開鼠標(biāo)"); } @Override public void closeDevice() { System.out.println("關(guān)閉鼠標(biāo)"); } }
4.接口特性
4.1 接口是一種引用類型,但是不能直接new接口的對象
public class TestUSB { public static void main(String[] args) { USB usb = new USB(); } }
4.2 接口中的方法會被默認(rèn)為public abstract,其他修飾符會報錯
public interface USB { private void openDevice();//private使用錯誤 void closeDevice(); }
4.3 接口中的方法不能在接口中實現(xiàn),只能通過接口的類來實現(xiàn)
public interface USB { //void openDevice(); void closeDevice(){ System.out.println("關(guān)閉USB設(shè)備"); } }
4.4 重寫接口方法時,不能使用默認(rèn)的訪問權(quán)限
public class Mouse implements USB{ @Override public void openDevice() { System.out.println("打開鼠標(biāo)"); } }
4.5 接口中可以有變量,但他會被默認(rèn)為public static final 變量
public interface USB { int susu = 250;//默認(rèn)被final public static修飾 void openDevice(); void closeDevice(); }
4.6 接口中不能有靜態(tài)代碼塊和構(gòu)造方法
public interface USB { public USB(){ } { } int susu = 250;//默認(rèn)被final public static修飾 void openDevice(); void closeDevice(); }
5.實現(xiàn)多個接口
一個類可以實現(xiàn)多個接口,這就是繼承所做不到的
- 這里創(chuàng)建一個
Dog類
,可以讓他實現(xiàn)多個接口
,如IRunning,ISwimming,IFlying。每個接口的抽象方法都有重寫,否則必須設(shè)置為抽象類AIT + InS
快捷鍵重寫
public class Dog extends Animal implements IRunning,ISwimming{ @Override public void run() { } @Override public void swim() { } }
狗:既能跑,又能游;
【注意】
有了接口之后,我們就不用注意具體類型,只需要關(guān)注這個類是否具備某種類型
6.接口間的繼承
在Java中,類和類之間是單繼承的,但一個類可以實現(xiàn)多個接口,接口與接口之間可以多繼承
這段代碼就繼承了兩個接口:游和跑
public class Dog extends Animal implements ISwimming,IRunning{ @Override public void run() { } @Override public void swim() { } }
7.接口使用實例
對象之間大小比較:
public class Student { public String name; public int score; public Student (String name,int score){ this.name=name; this.score=score; } @Override public String toString() { return super.toString(); } }
public class Test { public static void main(String[] args) { Student s1 = new Student("小華",20); Student s2 = new Student("小張",10); System.out.println(s1>s2); } }
這樣進行比較會報錯,因為沒有指定根據(jù)分?jǐn)?shù)還是什么來比較,這樣不太靈活,我們可以使用接口,如下:
使用Comparable接口
public class Student implements Comparable<Student>{ public String name; public int age; public Student (String name,int age){ this.name=name; this.age=age; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + '}'; } @Override public int compareTo(Student o) { if(this.age>o.age) return 1; else if(this.age == o.age) return 0; else return -1; } }
public class Test { public static void main(String[] args) { Student s1 = new Student("小華",20); Student s2 = new Student("小張",12); //System.out.println(s1>s2); if(s1.compareTo(s2)>0){ System.out.println("s1>s2"); } } }
使用Comparator接口
import java.util.Comparator; public class AgeComparator implements Comparator<Student> { @Override public int compare(Student o1, Student o2) { return o1.age-o2.age; } }
public class Test { public static void main(String[] args) { Student s1 = new Student("小華",20); Student s2 = new Student("小張",12); AgeComparator ageComparator=new AgeComparator(); int ret = ageComparator.compare(s1,s2); if(ret>0){ System.out.println("s1>s2"); }
如果是根據(jù)名字來比較的,就要看對應(yīng)字母的大小
8.Clonable接口和深拷貝
8.1 Clonable接口
Java 中內(nèi)置了?些很有?的接?,Clonable
就是其中之?.Object 類
中存在?個clone?法
,調(diào)?這個?法可以創(chuàng)建?個對象的"拷?".但是要想合法調(diào)?clone
?法,必須要先實現(xiàn)Clonable接?,否則就會拋出CloneNotSupportedException
異常.
public class Person implements Cloneable{ public String name; public int age; public Person (String name,int age){ this.name=name; this.age=age; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + '}'; } @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } }
public class Test1 { public static void main(String[] args) throws CloneNotSupportedException{ Person person1 = new Person("小華子",20); Person person2 = (Person) person1.clone();//強制類型轉(zhuǎn)換 System.out.println(person2); } }
受查異常/編譯時異常
解決方法:
8.2 淺拷貝
class Money implements Cloneable{ public double money = 9.9;
@Override protected Object clone() throws CloneNotSupportedException { return super.clone();
lic class Test1 { public static void main(String[] args) throws CloneNotSupportedException{ Person person1 = new Person("小華子",20); Person person2 = (Person) person1.clone(); System.out.println(person1.m.money); System.out.println(person2.m.money); System.out.println("=============="); person2.m.money = 19.9; System.out.println(person1.m.money); System.out.println(person2.m.money); }
通過clone,我們只是拷?了Person對象。但是Person對象中的Money對象,并沒有拷?。通過person2這個引?修改了m的值后,person1這個引?訪問m的時候,值也發(fā)?了改變。這?就是發(fā)?了淺拷?。
8.3 深拷貝
class Money implements Cloneable{ public double money = 9.9; @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } } public class Person implements Cloneable{ public String name; public int age; public Money m = new Money(); public Person (String name,int age){ this.name=name; this.age=age; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + '}'; } @Override protected Object clone() throws CloneNotSupportedException { //return super.clone(); Person tmp = (Person) super.clone(); tmp.m = (Money) this.m.clone(); return tmp; } }
public class Test1 { public static void main(String[] args) throws CloneNotSupportedException{ Person person1 = new Person("小華子",20); Person person2 = (Person) person1.clone(); System.out.println(person1.m.money); System.out.println(person2.m.money); System.out.println("=============="); person2.m.money = 19.9; System.out.println(person1.m.money); System.out.println(person2.m.money); }
核心代碼:
9.抽象類和接口的區(qū)別
抽象類中可以包含普通?法和普通字段,這樣的普通?法和字段可以被?類直接使?(不必重寫),
?接?中不能包含普通?法,?類必須重寫所有的抽象?法.
No | 區(qū)別 | 抽象類(abstract) | 接口(interface) |
---|---|---|---|
1 | 結(jié)構(gòu)組成 | 普通類+抽象方法 | 抽象方法+全局常量 |
2 | 權(quán)限 | 各種權(quán)限 | public |
3 | 子類使用 | 使用extends 關(guān)鍵字繼承抽象類 | 使用implements 關(guān)鍵字實現(xiàn)接口 |
4 | 關(guān)系 | 一個抽象類可以實現(xiàn)若干接口 | 接口不能繼承抽象類,可extends 繼承多個父接口 |
5 | 子類限制 | 一個子類只能繼承一個抽象類 | 一個子類可以實現(xiàn)多個接口 |
總結(jié)
在 Java 里,抽象類與接口是實現(xiàn)抽象編程的關(guān)鍵工具。抽象類融合普通類與抽象方法,可定義部分實現(xiàn)邏輯,權(quán)限靈活;接口由抽象方法和全局常量構(gòu)成,成員權(quán)限默認(rèn) public 。子類繼承抽象類用 extends ,實現(xiàn)接口用 implements 。關(guān)系上,抽象類能實現(xiàn)多個接口,接口可多繼承。繼承限制方面,子類單繼承抽象類,卻可多實現(xiàn)接口 。二者各有適用場景,抽象類適合提煉共性、留存部分實現(xiàn);接口利于規(guī)范行為、實現(xiàn)多態(tài)解耦。合理運用它們,能讓代碼架構(gòu)更清晰、可擴展與可維護,助力構(gòu)建靈活且健壯的 Java 程序 。
到此這篇關(guān)于Java抽象類與接口的文章就介紹到這了,更多相關(guān)Java抽象類與接口內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java Collections.shuffle()方法案例詳解
這篇文章主要介紹了Java Collections.shuffle()方法案例詳解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下2021-08-08三分鐘教你如何在IDEA中快速創(chuàng)建工程的方法
這篇文章主要介紹了三分鐘教你如何在IDEA中快速創(chuàng)建工程的方法,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-04-04MySQL text類型對應(yīng)mybatis jdbcType類型方式
這篇文章主要介紹了MySQL text類型對應(yīng)mybatis jdbcType類型方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-07-07