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

    你可能感兴趣的文章
    &和&&的区别
    查看>>
    (215:断言失败)函数‘;DFT‘中的type==CV_32FC1||type==CV_32FC2||type==CV_64FC1||type==CV_64FC2;
    查看>>
    (AS3)BitmapData.draw比BitmapData.copyPixel能做得更多
    查看>>
    (discord.py) 有没有办法让 on_message 事件查看嵌入式消息而不是普通消息?
    查看>>
    064:vue+openlayers根据坐标来显示点、线段、圆形、多边形
    查看>>
    (ios实战)单个ViewControl适配不同ios版本xib文件实现
    查看>>
    (Leetcode-字符串-2) 字符串运算
    查看>>
    (type interface {}) to type string
    查看>>
    (zhuan) Evolution Strategies as a Scalable Alternative to Reinforcement Learning
    查看>>
    (五)java多线程之Lock类
    查看>>
    (十一) 构建dubbo分布式平台-dubbo简介
    查看>>
    (十一)JAVA springboot ssm b2b2c多用户商城系统 - SSO单点登录之OAuth2.0登录流程(2)
    查看>>
    asp.net MVC 强类型视图表单Ajax提交的注意事项
    查看>>
    Asp.Net MVC 必备插件MVC Route Visualizer(Visual Studio 2012 版)
    查看>>
    Bailey Button Botas Ugg Baratas Corto Botas 5803 Casta?a Holgura Outlet GUANGXI SEDA ESTANCIA CALLB
    查看>>
    canvas设置文字阴影
    查看>>
    Centos 5.2+mysql-5.0.51a+httpd-2.2.8+PHP5.2.5(运行脚本)
    查看>>
    Centos 5.3 ADSL拨号组建中小型企业网络
    查看>>
    Centos 5.8 安装后不能使用ifconfig
    查看>>
    Centos 6 & 7 LVM 逻辑盘卷管理
    查看>>