做公司網(wǎng)站首頁(yè)seo網(wǎng)站診斷顧問
目錄
1.接口的概念
2.語(yǔ)法規(guī)則
?3.接口的使用
?4.接口的特性
總結(jié):
5.實(shí)現(xiàn)多個(gè)接口
6.接口間的繼承
1.接口的概念
接口就是公共的行為規(guī)范標(biāo)準(zhǔn),大家在實(shí)現(xiàn)時(shí),只要符合規(guī)范標(biāo)準(zhǔn),就可以通用。
在Java中,接口可以看成是:多個(gè)類的公共規(guī)范,是一種引用數(shù)據(jù)類型。
2.語(yǔ)法規(guī)則
接口的定義格式與定義類的格式基本相同,將class關(guān)鍵字換成 interface 關(guān)鍵字,就定義了一個(gè)接口。????????
public interface 接口名稱{
// 抽象方法
????????public abstract void method1(); // public abstract 是固定搭配,可以不寫
????????public void method2();
????????abstract void method3();
????????void method4();
// 注意:在接口中上述寫法都是抽象方法,跟推薦方式4,代碼更簡(jiǎn)潔
}
提示:
1. 創(chuàng)建接口時(shí), 接口的命名一般以大寫字母 I 開頭。
2. 接口的命名一般使用 "形容詞" 詞性的單詞。
3. 阿里編碼規(guī)范中約定, 接口中的方法和屬性不要加任何修飾符號(hào), 保持代碼的簡(jiǎn)潔性。
?3.接口的使用
接口不能直接使用,必須要有一個(gè)"實(shí)現(xiàn)類"來"實(shí)現(xiàn)"該接口,實(shí)現(xiàn)接口中的所有抽象方法。
public class 類名稱 implements 接口名稱{
// ...
}
?注意:子類和父類之間是extends 繼承關(guān)系,類與接口之間是 implements 實(shí)現(xiàn)關(guān)系。
?請(qǐng)實(shí)現(xiàn)筆記本電腦使用USB鼠標(biāo)、USB鍵盤的例子:
1. USB接口:包含打開設(shè)備、關(guān)閉設(shè)備功能
2. 筆記本類:包含開機(jī)功能、關(guān)機(jī)功能、使用USB設(shè)備功能
3. 鼠標(biāo)類:實(shí)現(xiàn)USB接口,并具備點(diǎn)擊功能
4. 鍵盤類:實(shí)現(xiàn)USB接口,并具備輸入功能
// USB接口
public interface USB {
????????void openDevice();
????????void closeDevice();
}
// 鼠標(biāo)類,實(shí)現(xiàn)USB接口
public class Mouse implements USB {
@Override
????????public void openDevice() {
????????????????System.out.println("打開鼠標(biāo)");
????????}@Override
????????public void closeDevice() {
????? ? ??????? System.out.println("關(guān)閉鼠標(biāo)");
????????}
????????public void click(){
????????????????System.out.println("鼠標(biāo)點(diǎn)擊");
????????}
}
// 鍵盤類,實(shí)現(xiàn)USB接口
public class KeyBoard implements USB {
@Override
????????public void openDevice() {
????????System.out.println("打開鍵盤");
????????}
@Override
????????public void closeDevice() {
????????????????System.out.println("關(guān)閉鍵盤");
????????}
????????public void inPut(){
????????????????System.out.println("鍵盤輸入");
????????}
}
// 筆記本類:使用USB設(shè)備
public class Computer {
????????public void powerOn(){
????????????????System.out.println("打開筆記本電腦");
????????}
????????public void powerOff(){
????????????????System.out.println("關(guān)閉筆記本電腦");
????????}
????????public void useDevice(USB usb){
????????????????usb.openDevice();
????????????????if(usb instanceof Mouse){
????????????????????????Mouse mouse = (Mouse)usb;
????????????????????????mouse.click();
????????????????}else if(usb instanceof KeyBoard){
????????????????????????KeyBoard keyBoard = (KeyBoard)usb;
????????????????????????keyBoard.inPut();
????????????????}
????????????????usb.closeDevice();
????????????????}}
// 測(cè)試類:
public class TestUSB {
????????public static void main(String[] args) {????????????????Computer computer = new Computer();
????????????????computer.powerOn();
// 使用鼠標(biāo)設(shè)備
????????????????computer.useDevice(new Mouse());
// 使用鍵盤設(shè)備
????????????????computer.useDevice(new KeyBoard());
????????????????computer.powerOff();
????????}
}????????
?4.接口的特性
1. 接口類型是一種引用類型,但是不能直接new接口的對(duì)象
public class TestUSB {
????????public static void main(String[] args) {
????????????????USB usb = new USB();
????????}
}
// Error:(10, 19) java: day20210915.USB是抽象的; 無(wú)法實(shí)例化
2. 接口中每一個(gè)方法都是public的抽象方法, 即接口中的方法會(huì)被隱式的指定為 public abstract(只能是public abstract,其他修飾符都會(huì)報(bào)錯(cuò)) 。
public interface USB {
// Error:(4, 18) java: 此處不允許使用修飾符private
????????private void openDevice();
????????void closeDevice();
}?
3. 接口中的方法是不能在接口中實(shí)現(xiàn)的,只能由實(shí)現(xiàn)接口的類來實(shí)現(xiàn)?
?public interface USB {
????????void openDevice();
// 編譯失敗:因?yàn)榻涌谥械姆绞侥J(rèn)為抽象方法
// Error:(5, 23) java: 接口抽象方法不能帶有主體
????????void closeDevice(){
????????????????System.out.println("關(guān)閉USB設(shè)備");
????????}
}
4. 重寫接口中方法時(shí),不能使用默認(rèn)的訪問權(quán)限
public interface USB {
????????void openDevice(); // 默認(rèn)是public的
????????void closeDevice(); // 默認(rèn)是public的
}
public class Mouse implements USB {
@Override
????????void openDevice() {
????????????????System.out.println("打開鼠標(biāo)");
????????}
// ...
}
// 編譯報(bào)錯(cuò),重寫USB中openDevice方法時(shí),不能使用默認(rèn)修飾符
// 正在嘗試分配更低的訪問權(quán)限; 以前為public
5. 接口中可以含有變量,但是接口中的變量會(huì)被隱式的指定為 public static final 變量
public interface USB {
????????double brand = 3.0; // 默認(rèn)被:final public static修飾
????????void openDevice();
????????void closeDevice();
}
public class TestUSB {
????????public static void main(String[] args) {
????????????????System.out.println(USB.brand); // 可以直接通過接口名訪問,說明是靜態(tài)的
// 編譯報(bào)錯(cuò):Error:(12, 12) java: 無(wú)法為最終變量brand分配值
????????????????USB.brand = 2.0; // 說明brand具有final屬性
????????}
}
6. 接口中不能有靜態(tài)代碼塊和構(gòu)造方法
public interface USB {
// 編譯失敗
????????public USB(){
????????}
{} // 編譯失敗
????????void openDevice();
????????????????void closeDevice();
????????}
7. 接口雖然不是類,但是接口編譯完成后字節(jié)碼文件的后綴格式也是.class。
8. 如果類沒有實(shí)現(xiàn)接口中的所有的抽象方法,則類必須設(shè)置為抽象類。
9. jdk8中:接口中還可以包含default方法。
總結(jié):
- 接口是一種引用數(shù)據(jù)類型。
- 接口是使用interface方法來修飾的。
- 接口當(dāng)中不能有被實(shí)現(xiàn)的方法,意味著只能有抽象方法。但是兩個(gè)方法除外:一個(gè)是static修飾的方法一個(gè)是被default修飾的方法。
- 接口當(dāng)中的抽象方法默認(rèn)都是public abstract修飾的!!
- 接口當(dāng)中的成員變量默認(rèn)都是public static final修飾的!!
- 接口不能進(jìn)行實(shí)例化。
- 類和接口之間的關(guān)系,可以使用implements來進(jìn)行關(guān)聯(lián)。
- 接口也是有對(duì)應(yīng)的字節(jié)碼文件的。
- 接口中不能有靜態(tài)代碼塊、實(shí)例代碼塊和構(gòu)造方法。
- 重寫接口中方法時(shí),不能使用默認(rèn)的訪問權(quán)限(要用public,重寫的大于被重寫的)。
5.實(shí)現(xiàn)多個(gè)接口
在Java中,類和類之間是單繼承的,一個(gè)類只能有一個(gè)父類,即Java中不支持多繼承,但是一個(gè)類可以實(shí)現(xiàn)多個(gè)接口。下面通過類來表示一組動(dòng)物。
class Animal {
????????protected String name;
????????public Animal(String name) {
????????????????this.name = name;
????????}
}
另外我們?cè)偬峁┮唤M接口, 分別表示 "會(huì)飛的", "會(huì)跑的", "會(huì)游泳的":
interface IFlying {
????????void fly();
}
interface IRunning {
????????void run();
}
interface ISwimming {
????????void swim();
}
接下來我們創(chuàng)建幾個(gè)具體的動(dòng)物:
貓, 是會(huì)跑的:
class Cat extends Animal implements IRunning {
????????public Cat(String name) {
????????????????super(name);
????????}
@Override
????????public void run() {
????????????????System.out.println(this.name + "正在用四條腿跑");
????????}
}
魚, 是會(huì)游的:
class Fish extends Animal implements ISwimming {
????????public Fish(String name) {
????????????????super(name);
????????}
@Override
????????public void swim() {
????????????????System.out.println(this.name + "正在用尾巴游泳");
????????}
}
青蛙, 既能跑, 又能游(兩棲動(dòng)物):
class Frog extends Animal implements IRunning, ISwimming {
????????public Frog(String name) {
????????????????super(name);
????????}
@Override
????????public void run() {
????????????????System.out.println(this.name + "正在往前跳");
????????}
@Override
????????public void swim() {
????????????????System.out.println(this.name + "正在蹬腿游泳");
????????}
}?
注意:一個(gè)類實(shí)現(xiàn)多個(gè)接口時(shí),每個(gè)接口中的抽象方法都要實(shí)現(xiàn),否則類必須設(shè)置為抽象類。?
?還有一種神奇的動(dòng)物, 水陸空三棲, 叫做 "鴨子":
?class Duck extends Animal implements IRunning, ISwimming, IFlying {
????????public Duck(String name) {
????????????????super(name);
????????}
@Override
????????public void fly() {
????????????????System.out.println(this.name + "正在用翅膀飛");
????????}
@Override
????????public void run() {
????????????????System.out.println(this.name + "正在用兩條腿跑");
????????}@Override
????????public void swim() {
????????????????System.out.println(this.name + "正在漂在水上");
????????}
}
上面的代碼展示了 Java 面向?qū)ο缶幊讨凶畛R姷挠梅? 一個(gè)類繼承一個(gè)父類, 同時(shí)實(shí)現(xiàn)多種接口。
繼承表達(dá)的含義是 is - a 語(yǔ)義, 而接口表達(dá)的含義是 具有 xxx 特性 。
貓是一種動(dòng)物, 具有會(huì)跑的特性。
青蛙也是一種動(dòng)物, 既能跑, 也能游泳。
鴨子也是一種動(dòng)物, 既能跑, 也能游, 還能飛。
這樣設(shè)計(jì)有什么好處呢? 時(shí)刻牢記多態(tài)的好處, 讓程序猿忘記類型. 有了接口之后, 類的使用者就不必關(guān)注具體類型,而只關(guān)注某個(gè)類是否具備某種能力,只要?jiǎng)?chuàng)建對(duì)象或修改參數(shù),就可以實(shí)現(xiàn)這些特性。
?
見下面例子:
?
6.接口間的繼承
?? 在Java中,類和類之間是單繼承的,一個(gè)類可以實(shí)現(xiàn)多個(gè)接口,接口與接口之間可以多繼承。即:用接口可以達(dá)到多繼承的目的。
接口可以繼承一個(gè)接口, 達(dá)到復(fù)用的效果. 使用 extends 關(guān)鍵字.
interface IRunning {
????????void run();
}
interface ISwimming {
????????void swim();
}
// 兩棲的動(dòng)物, 既能跑, 也能游
interface IAmphibious extends IRunning, ISwimming {
}
class Frog implements IAmphibious {
...
}?
通過接口繼承創(chuàng)建一個(gè)新的接口 IAmphibious 表示 "兩棲的". 此時(shí)實(shí)現(xiàn)接口創(chuàng)建的 Frog 類, 就繼續(xù)要實(shí)現(xiàn) run 方法, 也需要實(shí)現(xiàn) swim 方法(接口間的繼承相當(dāng)于把多個(gè)接口合并在一起)。????????
?
?