首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 面向對象四大支柱:繼承、多態、重載、重寫系統性闡述與 C++ 對比

     編輯:Java 相關知識

繼承

定義與分類

繼承是在現有類型基礎上,通過添加新方法或重新定義現有方法產生新類型。Java 中三種類型:

  • 類:class 定義、無抽象方法
  • 抽象類:abstract class、可含抽象方法
  • 接口:interface、默認 public abstract 方法

繼承規則矩陣

子類型 \ 父類型類抽象類接口
類extends(單繼承)extends(單繼承)implements(多實現)
抽象類extendsextendsimplements
接口✗✗extends(多繼承)

關鍵約束

  • 類/抽象類:最多繼承一個類或一個抽象類(二選一)
  • 接口實現數量無限制
  • 類實現接口必須實現所有方法,否須聲明為抽象類
  • 抽象類實現接口可部分/全部/不實現接口方法

組合復用替代方案

public class Sub {
    private Parent parent = new Parent();  // 或延遲初始化
    public void doSomething() {
        parent.method();  // 復用父類功能
    }
}

適用於「has-a」關係,避免繼承帶來的強耦合、脆弱基類問題。

多態

核心機制

  • 繼承是基礎:子類是父類類型
  • 重寫是手段:子類提供差異化實現
  • 向上轉型:父類引用指向子類對象
  • 動態綁定:運行期根據對象實際類型分發方法

綁定類型

類型別名時機適用方法
早期綁定靜態綁定編譯/鏈接期static、final、private、構造器
晚期綁定動態綁定運行期其他實例方法(虛方法)

經典案例:汽車銷售系統

interface Car {
    String getName();
    int getPrice();
}

class BMW implements Car {
    public String getName() { return "BMW"; }
    public int getPrice() { return 300000; }
}

class CheryQQ implements Car {
    public String getName() { return "CheryQQ"; }
    public int getPrice() { return 20000; }
}

class CarShop {
    private int total = 0;
    public void sellCar(Car car) {  // 多態參數
        System.out.println("車型: " + car.getName() + " 價格: " + car.getPrice());
        total += car.getPrice();
    }
    public int getTotal() { return total; }
}

// 新增車型零修改 CarShop
class Santana implements Car {
    public String getName() { return "Santana"; }
    public int getPrice() { return 80000; }
}

重載 vs 重寫

方法簽名定義

簽名 = 方法名 + 參數列表(數量、類型、順序)。不包含:返回類型、訪問修飾符、abstract/static/final 等修飾符。

對比表

特性重載重寫
位置同一類父子類
方法名相同相同
參數列表不同相同
返回類型可不同兼容(协变返回)
訪問權限無限制不能減弱
拋出異常無限制不能擴大
綁定時機編譯期運行期
多態相關無關核心基礎

構造器特殊性

  • 可重載:同類多構造器、參數不同
  • 不可重寫:子類無法定義同簽名構造器(構造器不繼承)
  • 子類構造器必須調用父類構造器(super())

C++ 對比視角:重載、覆蓋、隱藏、多態

函數隱藏

class Base { public: void fun() {} void fun(int i) {} };
class Derive : public Base { public: void fun(int i, int j) {} }; // 隱藏基類所有 fun 重載版本

Derive d;
d.fun(1,2);  // OK
d.fun();     // 編譯錯誤:基類 fun() 被隱藏
d.fun(1);    // 編譯錯誤:基類 fun(int) 被隱藏

解決:using Base::fun; 在派生類引入基類名字空間。

覆蓋

  • 基類虛函數 + 派生類同簽名實現
  • 基類指針/引用調用 → 動態綁定派生類版本
  • 虛函數表(vtable)機制實現

重載與多態的 C++ 區別

  • 重載:編譯期根據參數靜態綁定,僅在同一作用域有效
  • 多態:運行期根據對象類型動態綁定,依賴虛函數表
  • 虛函數可重載,但派生類新增重載版本不進入 vtable,基類指針不可調用

String 對象創建深度解析

字符串池機制

  • JVM 維護字符串常量池,存儲字面量字符串
  • String s = "abc":池中查找,有則返回引用,無則創建入池
  • new String("abc"):堆中創建新對象,值共享池中 char 數組

經典面試題

String str = new String("abc");  // 創建幾個對象?
// 答案:2 個
// 1. "abc" 字面量 → 常量池(若不存在)
// 2. new String(...) → 堆中新對象

拼接行為差異

表達式結果進池
"ab" + "cd""abcd"是(編譯期常量折疊)
String a = "ab"; a + "cd""abcd"否(運行期 new StringBuilder)
final String A = "ab"; final String B = "cd"; A + B"abcd"是(編譯期常量)
static final String A; static { A="ab"; } A + "cd""abcd"否(運行期賦值)

intern() 方法

String a = new String(new char[]{'a','b','c','d'});
String b = a.intern();  // 池中查找,有則返回池引用,無則創建入池並返回
// b != a(除非池中原本就有相同值)

總結

繼承、多態、重載、重寫構成 Java 面向對象核心。繼承建立類型層級,重寫實現行為多樣性,多態實現運行時動態分發,重載提供編譯期便利。理解 C++ 隱藏/覆蓋機制有助於深度掌握多態本質。String 池機制體現「享元模式」優化內存,掌握字面量 vs new、常量折疊、intern() 行為差異,是避免生產 Bug 的關鍵。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved