Java中多態(tài)與接口示例詳解
一、多態(tài)
1.1多態(tài)的概念
多態(tài)是面向?qū)ο蟮娜筇匦灾唬诵氖?**"一個(gè)接口,多種實(shí)現(xiàn)"**。具體表現(xiàn)為:父類 / 接口的引用可以指向子類 / 實(shí)現(xiàn)類的對(duì)象,調(diào)用方法時(shí)會(huì)執(zhí)行實(shí)際對(duì)象的重寫方法。
1.2多態(tài)的前提:
- 存在繼承 / 實(shí)現(xiàn)關(guān)系
- 方法重寫(@Override)
- 父類 / 接口引用指向子類 / 實(shí)現(xiàn)類對(duì)象
1.3多態(tài)的實(shí)現(xiàn)方式
方法重寫(Override)子類繼承父類并重寫父類方法,通過父類引用調(diào)用子類對(duì)象時(shí),實(shí)際執(zhí)行的是子類的方法。
// 1. 父類:只定義一個(gè)通用方法
class Animal {
void shout() { // 通用行為:叫
System.out.println("動(dòng)物叫");
}
}
// 2. 子類1:狗(重寫父類的叫方法)
class Dog extends Animal {
@Override
void shout() {
System.out.println("汪汪汪");
}
}
// 3. 子類2:貓(重寫父類的叫方法)
class Cat extends Animal {
@Override
void shout() {
System.out.println("喵喵喵");
}
}
// 測(cè)試:多態(tài)的核心體現(xiàn)
public class SimplePolymorphism {
public static void main(String[] args) {
// 核心:父類引用 指向 子類對(duì)象
Animal a1 = new Dog(); // 狗裝到Animal類型的“盒子”里
Animal a2 = new Cat(); // 貓裝到Animal類型的“盒子”里
// 調(diào)用同一個(gè)方法,執(zhí)行不同邏輯(多態(tài))
a1.shout(); // 輸出:汪汪汪
a2.shout(); // 輸出:喵喵喵
}
}代碼解釋:
- 先定義一個(gè)
Animal(動(dòng)物)父類,有個(gè)shout()(叫)方法; Dog(狗)和Cat(貓)繼承Animal,各自重寫shout()方法,實(shí)現(xiàn)自己的 “叫聲”;- 測(cè)試時(shí),用
Animal類型的變量(父類引用)分別指向Dog和Cat對(duì)象; - 調(diào)用
shout()方法時(shí),變量是Animal類型,但實(shí)際執(zhí)行的是子類(狗 / 貓)的方法 —— 這就是多態(tài):同一個(gè)方法,不同對(duì)象執(zhí)行不同邏輯。
1.4向上和向下轉(zhuǎn)型
- 向上轉(zhuǎn)型:把子類對(duì)象 “裝” 到父類類型的變量里(自動(dòng)完成,不用手動(dòng)操作),這是多態(tài)的基礎(chǔ);
- 向下轉(zhuǎn)型:把已經(jīng)向上轉(zhuǎn)型的父類變量,“還原” 回子類類型(必須手動(dòng)強(qiáng)轉(zhuǎn),且有風(fēng)險(xiǎn))
// 父類
class Animal {
void shout() {
System.out.println("動(dòng)物叫");
}
}
// 子類
class Dog extends Animal {
@Override
void shout() {
System.out.println("汪汪汪");
}
// 子類獨(dú)有方法
void wagTail() {
System.out.println("搖尾巴");
}
}
public class CastTest {
public static void main(String[] args) {
// 向上轉(zhuǎn)型:子類對(duì)象 → 父類引用(自動(dòng)完成,不用寫額外代碼)
Animal a = new Dog();
// 能調(diào)用父類定義的方法(執(zhí)行子類重寫的邏輯)
a.shout(); // 輸出:汪汪汪
// 不能調(diào)用子類獨(dú)有的方法(父類引用“看不到”子類獨(dú)有方法)
// a.wagTail(); // 編譯報(bào)錯(cuò)!
}
}向上轉(zhuǎn)型只能引用父類有的方法 如果沒有,編譯則會(huì)報(bào)錯(cuò)
多態(tài)就是基于向上轉(zhuǎn)型實(shí)現(xiàn)的。
public class CastTest {
public static void main(String[] args) {
// 第一步:先向上轉(zhuǎn)型
Animal a = new Dog();
// 第二步:向下轉(zhuǎn)型(強(qiáng)制轉(zhuǎn)換,必須加 (子類類型))
Dog d = (Dog) a;
// 轉(zhuǎn)型后:既能調(diào)用重寫的方法,也能調(diào)用子類獨(dú)有方法
d.shout(); // 輸出:汪汪汪
d.wagTail(); // 輸出:搖尾巴
// ? 錯(cuò)誤示范:父類對(duì)象不能轉(zhuǎn)成子類(會(huì)拋運(yùn)行時(shí)異常)
// Animal a2 = new Animal();
// Dog d2 = (Dog) a2; // 運(yùn)行時(shí)拋出 ClassCastException
}
}- 必須手動(dòng)強(qiáng)轉(zhuǎn):要寫
(Dog) a,告訴編譯器 “我確認(rèn)這個(gè)父類引用指向的是 Dog 對(duì)象”; - 前提條件:只有當(dāng)父類引用實(shí)際指向的是該子類對(duì)象時(shí),向下轉(zhuǎn)型才安全(比如
a實(shí)際是Dog,才能轉(zhuǎn)成Dog);
二、接口
2.1接口的定義
接口(Interface)是純抽象的 “行為契約 / 規(guī)范” —— 只規(guī)定 “要做什么”(定義方法名),不規(guī)定 “怎么做”(無方法體),由實(shí)現(xiàn)類(implements)去完成具體邏輯。
- 類比:就像 “遙控器接口”,只定義 “開機(jī)、換臺(tái)” 按鈕,電視、空調(diào)各自實(shí)現(xiàn)自己的開機(jī) / 換臺(tái)邏輯。
- 核心價(jià)值:統(tǒng)一行為標(biāo)準(zhǔn)、解耦代碼、彌補(bǔ) Java 單繼承的不足。
2.2接口的實(shí)現(xiàn)
接口使用 interface 關(guān)鍵字聲明,默認(rèn)所有方法為 public abstract(隱式修飾符),屬性為 public static final。
interface MyInterface {
void method1(); // 隱式為 public abstract
String CONSTANT = "VALUE"; // 隱式為 public static final
}類通過 implements 關(guān)鍵字實(shí)現(xiàn)接口,必須重寫接口中所有抽象方法(除非是抽象類)
class MyClass implements MyInterface {
@Override
public void method1() {
System.out.println("Implemented method");
}
}2.2.2多接口實(shí)現(xiàn)
一個(gè)類可同時(shí)實(shí)現(xiàn)多個(gè)接口,需重寫所有接口的抽象方法。
interface InterfaceA { void methodA(); }
interface InterfaceB { void methodB(); }
class MyClass implements InterfaceA, InterfaceB {
@Override
public void methodA() { /* 實(shí)現(xiàn) */ }
@Override
public void methodB() { /* 實(shí)現(xiàn) */ }
}2.2.3接口繼承
接口可通過 extends 繼承其他接口,支持多繼承。子接口會(huì)合并父接口的方法。
interface ParentA { void methodA(); }
interface ParentB { void methodB(); }
interface Child extends ParentA, ParentB { void methodC(); }
class MyClass implements Child {
@Override
public void methodA() { /* 實(shí)現(xiàn) */ }
@Override
public void methodB() { /* 實(shí)現(xiàn) */ }
@Override
public void methodC() { /* 實(shí)現(xiàn) */ }
}2.3接口+類基本用法
// 1. 定義接口:只規(guī)定行為,不實(shí)現(xiàn)
interface Runable {
// 抽象方法:只定義“跑”,無邏輯
void run();
// 默認(rèn)方法:有通用邏輯,可選重寫
default void warmUp() {
System.out.println("熱身:活動(dòng)關(guān)節(jié)");
}
// 靜態(tài)方法:接口專屬,只能通過接口名調(diào)用
static void rule() {
System.out.println("跑步規(guī)則:不要違規(guī)");
}
// 常量:默認(rèn)public static final
int SPEED_LIMIT = 10; // 限速10
}
// 2. 實(shí)現(xiàn)類1:學(xué)生跑步(實(shí)現(xiàn)接口)
class Student implements Runable {
@Override
public void run() { // 必須實(shí)現(xiàn)抽象方法
System.out.println("學(xué)生慢跑,速度≤" + SPEED_LIMIT);
}
// 可選重寫默認(rèn)方法
@Override
public void warmUp() {
System.out.println("學(xué)生熱身:拉伸腿");
}
}
// 3. 實(shí)現(xiàn)類2:運(yùn)動(dòng)員跑步(實(shí)現(xiàn)接口)
class Athlete implements Runable {
@Override
public void run() {
System.out.println("運(yùn)動(dòng)員沖刺,速度≤" + SPEED_LIMIT);
}
// 不重寫默認(rèn)方法,直接用接口的warmUp
}
// 測(cè)試
public class InterfaceDemo {
public static void main(String[] args) {
// 接口引用指向?qū)崿F(xiàn)類(多態(tài))
Runable s = new Student();
Runable a = new Athlete();
s.run(); // 輸出:學(xué)生慢跑,速度≤10
s.warmUp(); // 輸出:學(xué)生熱身:拉伸腿
a.run(); // 輸出:運(yùn)動(dòng)員沖刺,速度≤10
a.warmUp(); // 輸出:熱身:活動(dòng)關(guān)節(jié)
Runable.rule(); // 靜態(tài)方法:接口名.方法名調(diào)用
}
}三、總結(jié)
- 接口是多態(tài)的 “規(guī)范載體”,定義統(tǒng)一行為;多態(tài)是接口的 “落地方式”,實(shí)現(xiàn)靈活適配;
- 多態(tài)核心:統(tǒng)一引用、不同實(shí)現(xiàn);接口核心:只定規(guī)則、多實(shí)現(xiàn)、解耦;
- 實(shí)戰(zhàn)中 “接口 + 多態(tài)” 是 Java 面向?qū)ο缶幊痰暮诵慕M合,能讓代碼更靈活、易擴(kuò)展、易維護(hù)。
到此這篇關(guān)于Java中多態(tài)與接口的文章就介紹到這了,更多相關(guān)Java多態(tài)與接口內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
通過java字節(jié)碼分析學(xué)習(xí)對(duì)象初始化順序
今天用了jmock對(duì)進(jìn)行單元測(cè)試編碼,發(fā)現(xiàn)一個(gè)比較奇怪的語法,static使用方法,見下面例子2013-11-11
Spring Boot 聲明式調(diào)用 Feign 從入門到精通實(shí)例詳解
這篇文章給大家介紹Spring Boot聲明式調(diào)用Feign從入門到精通實(shí)例詳解,本文全面介紹了Feign的使用和配置,涵蓋基礎(chǔ)和高級(jí)特性,以及在復(fù)雜場(chǎng)景中的應(yīng)用,感興趣的朋友跟隨小編一起看看吧2026-04-04
SpringBoot中@ComponentScan注解過濾排除不加載某個(gè)類的3種方法
這篇文章主要給大家介紹了關(guān)于SpringBoot中@ComponentScan注解過濾排除不加載某個(gè)類的3種方法,文中通過實(shí)例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用SpringBoot具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2023-07-07
java開發(fā)建造者模式驗(yàn)證實(shí)例詳解
這篇文章主要為大家介紹了java開發(fā)中建造者模式的驗(yàn)證實(shí)例詳解,文中附含詳細(xì)示例代碼,有需要的朋友可以借鑒參考下,希望能夠有所幫助2021-10-10
MAC算法之消息摘要算法HmacMD5的實(shí)現(xiàn)
這篇文章主要介紹了MAC算法之消息摘要算法HmacMD5的實(shí)現(xiàn)的相關(guān)資料,這里提供實(shí)例,幫助大家學(xué)習(xí)理解這部分知識(shí),需要的朋友可以參考下2017-08-08
springboot發(fā)送request請(qǐng)求的方式小結(jié)
在Java中,發(fā)送HTTP請(qǐng)求是常見需求,hutool工具包和RestTemplate類是實(shí)現(xiàn)此功能的兩種主流方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-09-09

