面向對象編程 (OOP):深入理解繼承、多態和抽象

1. 簡介

????????面向對象編程 (OOP) 是一種強大的編程范式,它通過將程序組織成對象的集合來簡化軟件設計和開發。與傳統的程序設計方法相比,OOP 提供了一種更自然、更易于理解和維護的方式來構建復雜的軟件系統。OOP 的核心概念包括:對象、類、繼承、多態、封裝。本文將深入探討這些概念,重點講解繼承、多態、抽象類和接口,以及它們在 Java 中的應用。

2. 棧空間和堆空間

????????在深入了解 OOP 之前,我們需要先了解 Java 中的內存管理機制,尤其是棧空間和堆空間。

2.1 棧空間 (Stack)

  • 定義和作用:?棧空間用于存儲局部變量、方法參數和函數調用信息。 它是 Java 程序運行時最基本的內存區域之一。
  • LIFO 原理:?棧空間遵循先進后出 (LIFO) 的原則,就像一個疊放盤子的架子,最后放進去的盤子最先被拿出來。
  • 存儲數據類型:?棧空間主要存儲以下數據類型:
    • 局部變量: 定義在方法內部的變量,例如?int age = 25;
    • 方法參數: 傳遞給方法的變量,例如?void calculateSum(int a, int b) { ... }?中的?a?和?b
    • 函數調用信息: 包括方法調用時的局部變量地址、返回地址等。
  • 特點:
    • 棧空間大小通常較小,而且速度較快。
    • 棧空間的分配和回收由 Java 虛擬機 (JVM) 自動管理,程序員不需要手動進行操作。

2.2 堆空間 (Heap)

  • 定義和作用:?堆空間用于存儲對象和數組。它是 Java 程序中用于動態內存分配的主要區域。
  • 特點:
    • 堆空間的空間大小通常比棧空間大得多。
    • 堆空間的分配和回收由垃圾回收器 (Garbage Collector) 自動管理,程序員一般不需要手動進行操作。
    • 堆空間通常比棧空間速度慢。

2.3 棧空間和堆空間的交互

當創建一個對象時,會發生以下步驟:

  1. 棧空間:?分配一個引用變量,該變量指向堆空間中對象的地址。例如:Car myCar = new Car();?中的?myCar
  2. 堆空間:?為新創建的對象分配一塊內存塊,其中包含對象的屬性和方法。
  3. 連接:?引用變量指向堆空間中分配的內存塊,這樣就可以通過引用變量訪問對象。
// 1. 棧空間:
// 創建一個 Car 類對象,并分配了一個引用變量 myCar。
Car myCar = new Car(); // 2. 堆空間:
// 將新創建的 Car 對象的屬性和方法存儲在堆空間中。
// 這里假設 Car 有兩個屬性:color 和 model。
// myCar 的值指向堆空間中對象的地址。
// 此時 myCar 就是一個指向堆空間對象的引用。
//         堆空間
// +-----+-----+---------+     // 
// | color| model|  ...   |     //
// +-----+-----+---------+
//       ^
//       |
//       myCar(棧空間)

3. 面向對象編程的基礎

3.1 對象和類

  • 對象:?現實世界中事物的抽象表示。在編程中,對象是數據(屬性)和操作數據的方法(行為)的封裝。例如,一個 "汽車" 對象可以包含屬性(例如顏色、品牌、型號、速度)和方法(例如啟動、加速、剎車)。
  • 類:?創建對象的模板或藍圖。它定義了對象的屬性和方法。例如,"汽車" 類可以定義所有汽車共有的屬性和方法,然后通過這個類創建多個不同的汽車對象。

用 Java 代碼表示:

class Car {String color;String brand;String model;int speed;void start() {System.out.println("汽車啟動");}void accelerate() {System.out.println("汽車加速");}void brake() {System.out.println("汽車剎車");}
}public class Main {public static void main(String[] args) {Car myCar = new Car();myCar.color = "紅色";myCar.brand = "寶馬";myCar.model = "3系";myCar.start();myCar.accelerate();}
}

3.2 封裝

  • 概念:?將對象的屬性和方法結合起來,并隱藏對象的內部實現細節,只暴露接口供外部訪問。
  • 目的:
    • 提高代碼安全性: 防止外部代碼直接修改對象的私有屬性。
    • 提升代碼可維護性: 修改對象的內部實現細節不會影響外部代碼的使用。
    • 增強代碼可重用性: 可以根據需要創建不同的對象,而無需關注其內部實現細節。

訪問修飾符:

修飾符描述訪問范圍
public任何地方都可以訪問整個程序
private只有類內部可以訪問類內部
protected繼承的類和同一個包內的類可以訪問繼承類和同一個包
default?(無修飾符)只有同一個包內的類可以訪問同一個包

用 Java 代碼示例:

class Person {private String name; // 私有屬性,只能在 Person 類內部訪問private int age; // 私有屬性,只能在 Person 類內部訪問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;}
}

4. 繼承

  • 概念:?繼承是 OOP 中一個重要的特性,它允許一個類繼承另一個類的屬性和方法。繼承建立了 “is-a” 關系,子類擁有父類的所有屬性和方法,并且可以添加自己的屬性和方法。
  • 目的:
    • 代碼復用: 避免重復編寫相同的功能代碼。
    • 可擴展性: 通過繼承,可以在父類的基礎上創建新的子類,實現新的功能。
    • 代碼組織: 將相關的功能組織到不同的層次結構中,使代碼更易于理解和維護。

4.1 繼承的概念

  • 父類 (基類或超類):?被繼承的類。
  • 子類 (派生類或擴展類):?繼承自另一個類的類。
class Animal {void eat() {System.out.println("動物在吃");}
}class Dog extends Animal { // Dog 繼承了 Animal 類void bark() {System.out.println("狗在叫");}
}

4.2 繼承的優勢

  • 代碼復用:?繼承允許子類復用父類的代碼,避免重復編寫相同的功能。例如,在?Dog?類中,eat?方法不需要重新編寫,可以直接繼承自父類?Animal
  • 可擴展性:?繼承使得添加新的功能變得更容易。例如,我們可以通過繼承?Animal?類,創建新的子類,比如?Cat?類,來添加貓的相關功能,例如?meow()?方法。
  • 代碼組織:?繼承可以幫助我們更好地組織代碼,將相關的類組織到不同的層次結構中。例如,我們可以創建一個?Pet?類作為父類,然后創建?DogCat?等子類,這樣可以使代碼更加清晰、易于維護。

4.3 繼承的類型

  • 單繼承:?在 Java 中,一個子類只能繼承一個父類。
  • 多繼承:?一個子類可以繼承多個父類。 Java 不支持真正的多繼承,但可以使用接口來實現類似功能。
  • 層次化繼承:?父類可以有子類,子類可以有孫類,形成層次結構。

4.4 繼承中的方法重寫 (Overriding)

  • 概念:?子類可以選擇重寫父類的方法,以便在子類中提供不同的實現。
  • 條件:?方法重寫必須滿足以下條件:
    • 方法名相同。
    • 參數列表相同。
    • 返回值類型相同(或者返回值類型是父類返回值類型的子類)。
    • 訪問修飾符的權限不能比父類更嚴格。
class Animal {void sound() {System.out.println("動物發出聲音");}
}class Dog extends Animal {@Overridevoid sound() {  // 重寫父類的 sound 方法System.out.println("狗叫");}
}

4.5 繼承中的構造函數

  • 子類構造函數:?子類構造函數必須調用父類構造函數,才能初始化父類繼承的屬性。
  • super()?方法:?在子類構造函數中,可以使用?super()?方法調用父類的構造函數。

4.6 繼承中的方法隱藏

  • 概念:?子類的方法與父類的某個方法具有相同的方法名,但參數列表不同,這種情況稱為方法隱藏。
  • 區別:?方法隱藏與方法重寫不同,方法隱藏不會改變方法的實現,而方法重寫會改變方法的實現。
class Animal {void sound() { // 父類方法System.out.println("Animal makes a sound");}
}class Dog extends Animal {void sound(int age) { // 子類方法,與父類方法同名,但參數不同System.out.println("Dog barks, age: " + age);}
}

4.7 繼承中?final?關鍵字

  • final?關鍵字:?用于修飾類、方法和變量,表示它們是最終的,不能被繼承或重寫。
    • final?類:?表示該類不能被繼承。
    • final?方法:?表示該方法不能被子類重寫。
    • final?變量:?表示該變量是一個常量,其值一旦被賦值就不能再改變。

5. 多態

  • 概念:?多態是指同一個操作在不同的對象上會產生不同的行為。
  • 目的:
    • 代碼靈活性和可擴展性: 可以通過父類引用指向子類對象,調用不同的實現方法。
    • 提高代碼可讀性: 可以使用更簡潔、更靈活的方式來編寫代碼。

5.1 多態的概念

  • 父類引用:?可以使用父類類型的變量來引用子類對象。
  • 方法調用:?當調用父類引用中的方法時,實際執行的是子類重寫后的方法。
class Animal { void sound() {System.out.println("動物發出聲音");}
}class Dog extends Animal {@Overridevoid sound() {System.out.println("狗叫");}
}public class Main {public static void main(String[] args) {Animal myDog = new Dog(); // 父類引用指向子類對象myDog.sound(); // 調用的是 Dog 類的 sound 方法}
}

5.2 多態的類型

  • 方法重載 (Overloading):?同一個類中,方法名相同,參數列表不同。 編譯器會根據參數類型和數量選擇合適的重載方法。
  • 方法重寫 (Overriding):?子類重寫父類的方法。 當父類引用指向子類對象時,調用的是子類重寫后的方法。

5.3 多態的優勢

  • 代碼靈活性和可擴展性:?多態可以使代碼更加靈活和易于擴展。
  • 代碼可讀性:?多態可以使代碼更加簡潔和易于理解。

5.4 多態的應用場景

????????多態在實際開發中有很多應用場景,例如:

  • 工廠模式:?通過工廠類創建不同類型的對象。
  • 策略模式:?定義一組算法,并將它們封裝為獨立的類,以便在運行時選擇合適的算法。

5.5 抽象類

  • 概念:?抽象類是用?abstract?關鍵字修飾的類,它不能被直接實例化,只能被子類繼承。抽象類可以包含抽象方法和普通方法。
  • 特點:
    • 抽象方法: 沒有方法體,以?abstract?關鍵字修飾。 子類必須重寫抽象方法才能實例化。
    • 不能被直接實例化: 只能通過子類來實例化。
abstract class Shape { // 抽象類abstract void draw(); // 抽象方法,沒有方法體void print() { // 普通方法System.out.println("這是一個形狀");}
}class Circle extends Shape {@Overridevoid draw() {System.out.println("畫一個圓形");}
}public class Main {public static void main(String[] args) {Shape circle = new Circle(); // 實例化子類 Circlecircle.draw(); // 調用子類重寫的 draw 方法circle.print(); // 調用父類的 print 方法}
}

5.6 接口

  • 概念:?接口是使用?interface?關鍵字聲明的,它是一種特殊的抽象類,其中只包含抽象方法和常量。接口不能被直接實例化,只能被類實現。
  • 特點:
    • 只能包含抽象方法和常量。
    • 可以被多個類實現。
    • 提高代碼的可擴展性和靈活性。
interface Drawable { // 接口void draw(); // 抽象方法
}class Circle implements Drawable { // 實現接口@Overridepublic void draw() {System.out.println("畫一個圓形"); }
}public class Main {public static void main(String[] args) {Drawable circle = new Circle(); // 實例化 Circle 對象circle.draw();}
}

6. 總結

概念描述優勢
對象現實世界中事物的抽象表示,包含屬性和方法提供了一種更自然、更易于理解和維護的編程方式
創建對象的模板,定義對象的屬性和方法定義了對象的結構和行為
封裝將對象的屬性和方法結合起來,隱藏實現細節提高代碼安全性、可維護性和可重用性
繼承允許子類繼承父類的屬性和方法代碼復用、可擴展性、代碼組織
多態同一個操作在不同的對象上會產生不同的行為代碼靈活性和可擴展性、提高代碼可讀性
抽象類用?abstract?修飾的類,不能被直接實例化,只能被子類繼承定義公共方法和屬性,并強制子類實現抽象方法
接口用?interface?關鍵字定義,包含抽象方法和常量,可以被多個類實現提高代碼的可擴展性和靈活性

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/20720.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/20720.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/20720.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Java進階學習筆記31——日期時間

Date: 代表的是日期和時間。 分配Date對象并初始化它以表示自標準基準時間(稱為紀元)以來的指定毫秒數,即1970年1月1日00:00:00。 有參構造器。 package cn.ensource.d3_time;import java.util.Date;public class Test1Date {pu…

linux C/C++靜態庫制作

概念:程序在編譯時會把庫文件的二進制代碼鏈接到目標程序中,這種方式稱為靜態鏈接。 如果多個程序中用到了同一靜態庫中的函數或類,就會存在多份拷貝。 特點: 靜態庫的鏈接是在編譯時期完成的,執行的時候代碼加載速度…

Java—異常處理

異常的結構圖 異常知識點 異常分類: 按照在程序編譯階段是否被檢查,異常分為編譯時異常(Checked Exception)和運行時異常(Unchecked Exception)。編譯時異常是指必須進行顯式處理的異常,例如IOE…

【Linux】寫一個日志類

文章目錄 1. 源代碼2. 函數功能概覽3. 代碼詳細解釋3.1 頭文件和宏定義3.2 Log類定義3.3 打印日志的方法3.4 操作符重載和析構函數3.5 可變參數函數的原理 4. 測試用例 1. 源代碼 下面代碼定義了一個 Log 類,用于記錄日志信息。這個類支持將日志信息輸出到屏幕、單…

Java擴展機制:SPI與Spring.factories詳解

一、SPI SPI全稱Service Provider Interface,是Java提供的一套用來被第三方實現或者擴展的API,它可以用來啟用框架擴展和替換組件。 整體機制圖如下: Java SPI 實際上是“基于接口的編程+策略模式+配置文件”組合實現的動態加載機制。 系統設計的各個抽象,往往有很多不…

戴爾科技:一盆冷水澆醒了AIPC

這年頭,只要沾上英偉達的公司,不論美股還是大A,都跟著雞犬升天幾輪過,但昨晚英偉達蒸發1064億美元, 跟著遭罪的也不少,有沒有一夜驚魂夢醒的感覺? 今天我們來說說——戴爾科技。 昨晚戴爾科技大跌5.18%&a…

5G無線標準演進綜述及新技術引入

摘 要 隨著經濟和社會的發展,5G業務越來越豐富多彩,1080P高清視頻、裸眼3D、網聯汽車、云手機等新業務、新終端對網絡的要求也越來越高;另一方面,5G標準持續演進,在MIMO、載波聚合、移動性管理、uRLLC、切片、定位等方…

你了解MySQL分區表嗎?知道哪些情況不適用分區表嗎?

一、分區表的使用 簡單來說,分區表就是把物理表結構相同的幾張表,通過一定算法,組成一張邏輯大表。這種算法叫“分區函數”,當前 MySQL 數據庫支持的分區函數類型有 RANGE、LIST、HASH、KEY、COLUMNS。 無論選擇哪種分區函數,都要指定相關列成為分區算法的輸入條件,這些列…

ESP32開發筆記

ESP32 學習筆記 MQTT5 共享訂閱 什么是共享訂閱? 在普通的訂閱中,每發布一條消息,所有匹配的訂閱端都會收到該消息的副本。然而,當某個訂閱端的消費速度無法跟上消息的生產速度時,我們無法將其中一部分消息分流到…

`nano` 文本編輯器快捷鍵使用

在 nano 文本編輯器中,可以幫助用戶高效編輯文本,下面是每個快捷鍵的詳細解釋: 常用快捷鍵 ^G: Help - 顯示幫助信息。這里的 ^ 代表 Ctrl 鍵,因此 ^G 就是 Ctrl G。^O: Write Out - 保存文件。^O 即 Ctrl O,用于將…

模仿庫實現priority_queue

1 priority_queue 1.1 概念 優先級隊列,一種大/小堆(默認為大堆) 1.2 大堆和小堆 一種完全二叉樹,大堆根節點一定比子字節大 小堆根節點一定比子字節小 向下調整 從根節點開始比較與子節點的大小不斷向下 向上調整 找到最后一個非葉子節點&#xf…

mac多媒體影音庫:Emby for Mac 中文版

Emby軟件是一款功能強大的媒體服務器軟件,旨在為用戶提供豐富的多媒體體驗。以下是關于Emby軟件的詳細介紹: 下載地址:https://www.macz.com/mac/7964.html?idOTI2NjQ5Jl8mMjcuMTg2LjE1LjE4Mg%3D%3D 主要功能 媒體管理:Emby允許用…

代碼隨想錄-Day25

216.組合總和III 找出所有相加之和為 n 的 k 個數的組合,且滿足下列條件: 只使用數字1到9 每個數字 最多使用一次 返回 所有可能的有效組合的列表 。該列表不能包含相同的組合兩次,組合可以以任何順序返回。 示例 1: 輸入: k 3, n 7 輸…

Python OCR 圖片轉文字進階:讀光OCR之行檢測模型+行識別模型

Python OCR 圖片轉文字進階:讀光OCR之行檢測模型行識別模型 介紹阿里云文字識別OCR(讀光OCR)前置條件模型1:行檢測模型模型1:行識別模型 代碼:main.py 介紹 什么是OCR? OCR是“Optical Charac…

Leetcode:字符串轉換整數 (atoi)

題目鏈接:8. 字符串轉換整數 (atoi) - 力扣(LeetCode) 普通版本(條件限制) class Solution { public:int myAtoi(string s) {int res 0;int i 0;int flag 1;//假設整數為正while(s[i] )//跳過空格{i;}if(s[i] …

德人合科技——@天銳綠盾 | -文檔透明加密系統

天銳綠盾文檔透明加密系統是一種先進的數據安全解決方案,旨在保護企業和組織的敏感信息,防止未經授權的訪問和泄漏。 PC地址: https://isite.baidu.com/site/wjz012xr/2eae091d-1b97-4276-90bc-6757c5dfedee 以下是該系統的一些關鍵特點和功…

[C++11/14新特性] tuple元組介紹

C11 標準新引入了一種類模板,命名為 tuple(中文可直譯為元組)。tuple 最大的特點是:實例化的對象可以存儲任意數量、任意類型的數據。tuple 的應用場景很廣泛,例如當需要存儲多個不同類型的元素時,可以使用…

3D目標檢測入門:探索OpenPCDet框架

前言 在自動駕駛和機器人視覺這兩個飛速發展的領域中,3D目標檢測技術扮演著核心角色。隨著深度學習技術的突破性進展,3D目標檢測算法的研究和應用正日益深入。OpenPCDet,這個由香港中文大學OpenMMLab實驗室精心打造的開源工具箱,…

加密算法簡述

目錄 1 加密算法的分類 2 對稱加密 3 非對稱加密 4 哈希算法 1 加密算法的分類 數據加密的基本過程是將原本的明文數據依照某種算法進行一定的處理,使之成為一段不可讀的密文,只有通過相應的密鑰與算法進行計算后才可顯示出原文。而這個過程中的算法…

【用Python畫畫】六一兒童節畫愛心

本文收錄于 《Python編程入門》專欄,從零基礎開始,分享一些Python編程基礎知識,歡迎關注,謝謝! 文章目錄 一、前言二、代碼示例三、知識點梳理四、總結 一、前言 本文介紹如何使用Python的海龜畫圖工具turtle&#xf…