」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > Java 中的封裝與抽象:終極指南

Java 中的封裝與抽象:終極指南

發佈於2024-11-08
瀏覽:570

Encapsulation vs. Abstraction in Java: The Ultimate Guide

学习 Java 或任何面向对象编程 (OOP) 语言时,两个基本概念很突出:封装抽象。这些概念是 OOP 的关键支柱,可提高代码的可重用性、安全性和可维护性。尽管它们经常一起使用,但它们具有不同的目的。

在这篇文章中,我们将深入探讨封装和抽象之间的差异,并通过清晰的定义、示例和代码片段来帮助您了解它们在 Java 编程中的作用。让我们来分解一下吧!

什么是封装?

封装是将数据(变量)和对数据进行操作的方法捆绑到单个单元(通常是类)中的过程。它向外界隐藏对象的内部状态,只允许通过公共方法进行受控访问。

封装的主要特点:

  1. 数据隐藏:内部对象数据对其他类隐藏。
  2. 访问控制:只有允许的(公共)方法才能操作隐藏数据。
  3. 提高安全性:防止外部代码直接修改内部数据。
  4. 维护方便:如果内部实现发生变化,只需要更新方法,不需要更新外部类。

Java封装的例子:

// Encapsulation in action

public class Employee {
    // Private variables (data hiding)
    private String name;
    private int age;

    // Getter and setter methods (controlled access)
    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;
    }
}

// Using the encapsulated class
public class Main {
    public static void main(String[] args) {
        Employee emp = new Employee();
        emp.setName("John Doe");
        emp.setAge(30);

        System.out.println("Employee Name: "   emp.getName());
        System.out.println("Employee Age: "   emp.getAge());
    }
}

在此示例中,Employee 类通过将其声明为私有来隐藏其字段(姓名和年龄)。像 Main 这样的外部类只能通过 getter 和 setter 方法访问这些字段,这些方法控制和验证输入/输出。


什么是抽象?

抽象是指隐藏对象复杂的实现细节并仅暴露基本特征的概念。这简化了与对象的交互并使代码更加用户友好。

抽象的主要特征:

  1. 隐藏复杂性:用户只看到自己需要的,底层代码被隐藏。
  2. 关注“内容”而不是“如何”:仅向用户提供必要的详细信息,同时隐藏实现。
  3. 帮助管理复杂性:通过提供简化的接口,有助于处理复杂的系统。
  4. 通过接口和抽象类强制执行:这些构造提供了蓝图而不暴露实现。

Java 中的抽象示例:

// Abstract class showcasing abstraction
abstract class Animal {
    // Abstract method (no implementation)
    public abstract void sound();

    // Concrete method
    public void sleep() {
        System.out.println("Sleeping...");
    }
}

// Subclass providing implementation for abstract method
class Dog extends Animal {
    public void sound() {
        System.out.println("Barks");
    }
}

public class Main {
    public static void main(String[] args) {
        Animal dog = new Dog();
        dog.sound();  // Calls the implementation of the Dog class
        dog.sleep();  // Calls the common method in the Animal class
    }
}

这里,抽象类Animal包含一个抽象方法sound(),该方法必须由其子类实现。 Dog 类提供了自己的 sound() 实现。这样,用户不需要担心 sound() 方法内部如何工作——他们只需调用它即可。


封装与抽象:主要区别

现在我们已经了解了定义和示例,让我们重点介绍 Java 中封装和抽象之间的主要区别:

特征 封装 抽象
目的 数据隐藏和保护内部状态 通过隐藏复杂细节来简化代码
重点 使用 getter/setter 控制对数据的访问 提供基本功能并隐藏实现
执行 使用带有私有字段的类实现 使用抽象类和接口实现
OOP 中的角色 提高安全性并保持对数据的控制 简化与复杂系统的交互
例子 私有变量和公共方法 抽象方法和接口

Java 的实际用例

何时使用封装:

  • 当您需要保护数据时:例如,在银行系统中不应直接修改账户余额。
  • 当您想要控制数据的访问方式时:确保只有允许的方法才能修改或检索数据,从而添加一层安全性。

何时使用抽象:

  • 在大型系统上工作时:在各种类和模块交互的大型项目中,抽象可以通过提供简化的接口来帮助管理复杂性。
  • 开发API时:仅向用户公开必要的细节,同时隐藏实际的实现。

封装和抽象相结合的好处

虽然封装和抽象服务于不同的目的,但它们一起工作以在 Java 中构建健壮、安全和可维护的代码。

  1. 安全性和灵活性:通过将两者结合起来,您可以确保数据受到保护(封装),同时仍然允许用户以简单的方式与其交互(抽象)。
  2. 代码可维护性:抽象隐藏了复杂性,使系统更易于管理,而封装提供了对数据的受控访问。
  3. 可重用性:这两个概念都促进代码重用——通过隔离数据进行封装,通过允许抽象方法的不同实现进行抽象。

结论:掌握 Java 中的封装和抽象

封装和抽象是面向对象编程中两个强大的概念,每个 Java 开发人员都应该掌握。虽然封装通过控制数据访问来帮助保护对象的内部状态,但抽象隐藏了系统的复杂性并仅提供必要的细节。

通过理解和应用两者,您可以构建经得起时间考验的安全、可维护和可扩展的应用程序。


本指南是否帮助您阐明 Java 中的封装和抽象?在下面的评论中分享您的想法或问题!


标签:

  • #Java
  • #OOP
  • #封装
  • #抽象
  • #Java编程

版本聲明 本文轉載於:https://dev.to/abhinowww/encapsulation-vs-abstraction-in-java-the-ultimate-guide-4ccf?1如有侵犯,請聯絡[email protected]刪除
最新教學 更多>
  • 解決Spring Security 4.1及以上版本CORS問題指南
    解決Spring Security 4.1及以上版本CORS問題指南
    彈簧安全性cors filter:故障排除常見問題 在將Spring Security集成到現有項目中時,您可能會遇到與CORS相關的錯誤,如果像“訪問Control-allo-allow-Origin”之類的標頭,則無法設置在響應中。為了解決此問題,您可以實現自定義過濾器,例如代碼段中的MyFi...
    程式設計 發佈於2025-05-03
  • 如何為PostgreSQL中的每個唯一標識符有效地檢索最後一行?
    如何為PostgreSQL中的每個唯一標識符有效地檢索最後一行?
    postgresql:為每個唯一標識符在postgresql中提取最後一行,您可能需要遇到與數據集合中每個不同標識的信息相關的信息。考慮以下數據:[ 1 2014-02-01 kjkj 在數據集中的每個唯一ID中檢索最後一行的信息,您可以在操作員上使用Postgres的有效效率: id dat...
    程式設計 發佈於2025-05-03
  • 如何在無序集合中為元組實現通用哈希功能?
    如何在無序集合中為元組實現通用哈希功能?
    在未訂購的集合中的元素要糾正此問題,一種方法是手動為特定元組類型定義哈希函數,例如: template template template 。 struct std :: hash { size_t operator()(std :: tuple const&tuple)const {...
    程式設計 發佈於2025-05-03
  • 如何簡化PHP中的JSON解析以獲取多維陣列?
    如何簡化PHP中的JSON解析以獲取多維陣列?
    php 試圖在PHP中解析JSON數據的JSON可能具有挑戰性,尤其是在處理多維數組時。 To simplify the process, it's recommended to parse the JSON as an array rather than an object.To do...
    程式設計 發佈於2025-05-03
  • Java開發者如何保護數據庫憑證免受反編譯?
    Java開發者如何保護數據庫憑證免受反編譯?
    在java 在單獨的配置文件保護數據庫憑證的最有效方法中存儲憑據是將它們存儲在單獨的配置文件中。該文件可以在運行時加載,從而使登錄數據從編譯的二進製文件中遠離。 使用prevereness class import java.util.prefs.preferences; 公共類示例{ 首選...
    程式設計 發佈於2025-05-03
  • 如何解決AppEngine中“無法猜測文件類型,使用application/octet-stream...”錯誤?
    如何解決AppEngine中“無法猜測文件類型,使用application/octet-stream...”錯誤?
    appEngine靜態文件mime type override ,靜態文件處理程序有時可以覆蓋正確的mime類型,在錯誤消息中導致錯誤消息:“無法猜測mimeType for for file for file for [File]。 application/application/octet...
    程式設計 發佈於2025-05-03
  • `console.log`顯示修改後對象值異常的原因
    `console.log`顯示修改後對象值異常的原因
    foo = [{id:1},{id:2},{id:3},{id:4},{id:id:5},],]; console.log('foo1',foo,foo.length); foo.splice(2,1); console.log('foo2', foo, foo....
    程式設計 發佈於2025-05-03
  • 圖片在Chrome中為何仍有邊框? `border: none;`無效解決方案
    圖片在Chrome中為何仍有邊框? `border: none;`無效解決方案
    在chrome 在使用Chrome and IE9中的圖像時遇到的一個頻繁的問題是圍繞圖像的持續薄薄邊框,儘管指定了圖像,儘管指定了;和“邊境:無;”在CSS中。要解決此問題,請考慮以下方法: Chrome具有忽略“ border:none; none;”的已知錯誤,風格。要解決此問題,請使用以下...
    程式設計 發佈於2025-05-03
  • 如何使用Java.net.urlConnection和Multipart/form-data編碼使用其他參數上傳文件?
    如何使用Java.net.urlConnection和Multipart/form-data編碼使用其他參數上傳文件?
    使用http request 上傳文件上傳到http server,同時也提交其他參數,java.net.net.urlconnection and Multipart/form-data Encoding是普遍的。 Here's a breakdown of the process:Mu...
    程式設計 發佈於2025-05-03
  • PHP陣列鍵值異常:了解07和08的好奇情況
    PHP陣列鍵值異常:了解07和08的好奇情況
    PHP數組鍵值問題,使用07&08 在給定數月的數組中,鍵值07和08呈現令人困惑的行為時,就會出現一個不尋常的問題。運行print_r($月份)返回意外結果:鍵“ 07”丟失,而鍵“ 08”分配給了9月的值。 此問題源於PHP對領先零的解釋。當一個數字帶有0(例如07或08)的前綴時,PHP...
    程式設計 發佈於2025-05-03
  • 在PHP中如何高效檢測空數組?
    在PHP中如何高效檢測空數組?
    在PHP 中檢查一個空數組可以通過各種方法在PHP中確定一個空數組。如果需要驗證任何數組元素的存在,則PHP的鬆散鍵入允許對數組本身進行直接評估:一種更嚴格的方法涉及使用count()函數: if(count(count($ playerList)=== 0){ //列表為空。 } 對...
    程式設計 發佈於2025-05-03
  • 如何有效地轉換PHP中的時區?
    如何有效地轉換PHP中的時區?
    在PHP 利用dateTime對象和functions DateTime對象及其相應的功能別名為時區轉換提供方便的方法。例如: //定義用戶的時區 date_default_timezone_set('歐洲/倫敦'); //創建DateTime對象 $ dateTime = ne...
    程式設計 發佈於2025-05-03
  • 如何避免Go語言切片時的內存洩漏?
    如何避免Go語言切片時的內存洩漏?
    ,a [j:] ...雖然通常有效,但如果使用指針,可能會導致內存洩漏。這是因為原始的備份陣列保持完整,這意味著新切片外部指針引用的任何對象仍然可能佔據內存。 copy(a [i:] 對於k,n:= len(a)-j i,len(a); k
    程式設計 發佈於2025-05-03
  • 在JavaScript中如何並發運行異步操作並正確處理錯誤?
    在JavaScript中如何並發運行異步操作並正確處理錯誤?
    同意操作execution 在執行asynchronous操作時,相關的代碼段落會遇到一個問題,當執行asynchronous操作:此實現在啟動下一個操作之前依次等待每個操作的完成。要啟用並發執行,需要進行修改的方法。 第一個解決方案試圖通過獲得每個操作的承諾來解決此問題,然後單獨等待它們: c...
    程式設計 發佈於2025-05-03
  • 如何有效地選擇熊貓數據框中的列?
    如何有效地選擇熊貓數據框中的列?
    在處理數據操作任務時,在Pandas DataFrames 中選擇列時,選擇特定列的必要條件是必要的。在Pandas中,選擇列的各種選項。 選項1:使用列名 如果已知列索引,請使用ILOC函數選擇它們。請注意,python索引基於零。 df1 = df.iloc [:,0:2]#使用索引0和1 ...
    程式設計 發佈於2025-05-03

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3