博客
关于我
Java 面向对象编程的四个基本原则(封装、继承、多态和抽象),并给出一个简单的例子说明如何在 Java 中应用这些原则?
阅读量:807 次
发布时间:2023-01-27

本文共 4745 字,大约阅读时间需要 15 分钟。

面向对象编程(OOP)是Java编程中的核心概念,它通过对象的划分实现代码的模块化和可维护性。四大基本原则——封装、继承、多态和抽象——是OOP的基石,每个原则都为开发者构建更高效的代码提供了有效的手段。

封装是开发者在对象化编程中首先学习的概念。它指通过将数据和行为捆绑在一起,保护对象的内部实现细节。对 Java 开发者来说,最直观的封装方式是通过字段声明为 private,并通过 setter 和 getter 方法进行访问。例如,银行账户类 BankAccount 中的 balance 字段被声明为 private,外部只能通过 getBalance() 方法获取,这样既保留了控制权,又确保了代码的安全性。

Justice Bank account 类的一个很好的示例是这样的:

public class BankAccount {    private double balance;    public BankAccount(double initialBalance) {        if (initialBalance > 0.0) {            balance = initialBalance;        } else {            throw new IllegalArgumentException("Initial balance must be greater than zero.");        }    }    public double getBalance() {        return balance;    }    public void deposit(double amount) {        if (amount > 0.0) {            balance += amount;        } else {            throw new IllegalArgumentException("Deposit amount must be positive.");        }    }    public void withdraw(double amount) {        if (amount > 0.0 && amount <= balance) {            balance -= amount;        } else {            throw new IllegalArgumentException("Withdrawal amount must be positive and less than or equal to the balance.");        }    }}

通过将 balance 属性私有化并提供公有方法,实现了对账户内部状态的控制。这种封装方法不仅保持代码的安全性,还允许我们在必要时添加各种校验逻辑。

继承则是在OOP中进一步强化代码复用性的一个重要概念。它允许一个子类继承父类的属性和方法,从而避免重复编写代码。比如,SavingsAccount 类可以继承 BankAccount 的大部分功能,并添加互利计算的方法。这种继承方式使得代码结构层次分明,易于扩展和维护。

对于继承的示例,我们可以创建一个扩展 BankAccount 的 SavingsAccount 类:

public class SavingsAccount extends BankAccount {    private double interestRate;    public SavingsAccount(double initialBalance, double interestRate) {        super(initialBalance);        this.interestRate = interestRate;    }    public void addInterest() {        double interest = getBalance() * interestRate;        deposit(interest);    }}

通过这种继承方式,我们不仅复用了父类的方法,还确保了子类的唯一性和功能特异性。

多态的概念与继承结合使用时特别有用。它允许一个对象以多种形式表现出不同的行为。例如,在 BankAccount 类中定义一个 abstract 方法 calculateInterest(),然后由具体的子类如 SavingsAccount 实现。这使得我们能够在不关心具体实现的情况下,统一处理所有类型的账户。

对于多态的实现,可以考虑如下代码:

public abstract class BankAccount {    private double balance;    public BankAccount(double initialBalance) {        if (initialBalance > 0.0) {            balance = initialBalance;        } else {            throw new IllegalArgumentException("Initial balance must be greater than zero.");        }    }    public double getBalance() {        return balance;    }    public void deposit(double amount) {        if (amount > 0.0) {            balance += amount;        } else {            throw new IllegalArgumentException("Deposit amount must be positive.");        }    }    public void withdraw(double amount) {        if (amount > 0.0 && amount <= balance) {            balance -= amount;        } else {            throw new IllegalArgumentException("Withdrawal amount must be positive and less than or equal to the balance.");        }    }    public abstract double calculateInterest();}

然后,SavingsAccount 类可以实现这个方法:

public class SavingsAccount extends BankAccount {    private double interestRate;    public SavingsAccount(double initialBalance, double interestRate) {        super(initialBalance);        this.interestRate = interestRate;    }    @Override    public double calculateInterest() {        return getBalance() * interestRate;    }}

这样,在同一个方法中,可以支持多种类型的账户,这就是多态的力量所在。

抽象类或接口是实现多态和抽象概念的重要手段。通过定义一组通用行为,我们可以让不同类型的对象遵循相同的接口。例如,Account 接口定义了基本的存取行为,而 BankAccount 和 SavingsAccount 类都实现这个接口。这样一来,我们可以在不关心具体实现的情况下,写出通用的代码。

一个最好的方法是创建一个Account 接口:

public interface Account {    void deposit(double amount);    void withdraw(double amount);    double getBalance();}

然后,具体的 BankAccount 类实现它:

public class BankAccount implements Account {    private double balance;    public BankAccount(double initialBalance) {        if (initialBalance > 0.0) {            balance = initialBalance;        } else {            throw new IllegalArgumentException("Initial balance must be greater than zero.");        }    }    public void deposit(double amount) {        if (amount > 0.0) {            balance += amount;        } else {            throw new IllegalArgumentException("Deposit amount must be positive.");        }    }    public void withdraw(double amount) {        if (amount > 0.0 && amount <= balance) {            balance -= amount;        } else {            throw new IllegalArgumentException("Withdrawal amount must be positive and less than or equal to the balance.");        }    }    public double getBalance() {        return balance;    }}

通过这种方式,所有账户类型都遵循相同的接口,从而可以在一个通用的方法中处理它们的行为。

Developers 的最佳实践可以总结为:

  • 封装:尽量将字段设为 private,并通过 getter 和 setter 方法提供必要的访问点,并在 setter 中添加必要的验证逻辑。
  • 继承:仅用于共享行为和状态的类之间,避免过度继承导致代码混乱。
  • 多态:利用抽象类或接口定义通用行为,并在子类中定制实现。
  • 抽象:使用抽象类或接口来定义通用行为规范,确保代码的扩展性。
  • 在实际开发中,需注意避免过度封装、过度继承,避免接口过于庞大,和避免为了抽象而抽象。

    转载地址:http://tfryk.baihongyu.com/

    你可能感兴趣的文章
    mysql-5.6.17-win32免安装版配置
    查看>>
    mysql-5.7.18安装
    查看>>
    MySQL-8.0.16 的安装与配置
    查看>>
    MySQL-Buffer的应用
    查看>>
    mysql-cluster 安装篇(1)---简介
    查看>>
    mysql-connector-java.jar乱码,最新版mysql-connector-java-8.0.15.jar,如何愉快的进行JDBC操作...
    查看>>
    mysql-connector-java各种版本下载地址
    查看>>
    mysql-EXPLAIN
    查看>>
    MySQL-Explain的详解
    查看>>
    mysql-group_concat
    查看>>
    MySQL-redo日志
    查看>>
    MySQL-【1】配置
    查看>>
    MySQL-【4】基本操作
    查看>>
    Mysql-丢失更新
    查看>>
    Mysql-事务阻塞
    查看>>
    Mysql-存储引擎
    查看>>
    mysql-开启慢查询&所有操作记录日志
    查看>>
    MySQL-数据目录
    查看>>
    MySQL-数据页的结构
    查看>>
    MySQL-架构篇
    查看>>