html内容封装为一个对象_一个非常简单的例子说说面向对象的封装特性


045d610b72414d16ee6b9736d8acc546.png

长按图片关注公众号

我们从一个简单的示例了解下对象的封装

定义一个账户类

// FileName:Account.java
// 账户表
public class Account{
  private long accountId;  //账户id
  private long balance;   //账户余额
  private DateTime updateTime; //最后更新时间

  public long getAccountId(){
    return accountId;
  }
  public long getBalance(){
    return balance;
  }
  public DateTime getUpdateTime{
    return updateTime;
  }
  public void setAccountId(long accountId){
    this.accountId = accountId;
  }
  public void setBalance(long balance){
    this.balance = balance;
  }
  public void setUpdateTime(DateTime updateTime){
    this.updateTime = updateTime;
  }
}

我们很多程序员定义一个对象类,直接采用这种方式,将 set 跟 get 方法全部开放出来,或者直接加上 lombok 的@Data 注解,那么这个类从面向对象的角度存在什么问题呢?

面向对象的四大特性

  • 封装
  • 抽象
  • 继承
  • 多态

这段代码从封装的特性角度来说存在什么问题呢?

- 假设创建了某个账户对象,是否可以在创建之后改变这个账户 id 呢?

理论上不存在这种场景,换了一个账户 id 之后理论上就是另外一个账户对象了,那么在类中定义的 setAccountId 方法就不能开放出去

从另外的角度来说,账户 id 应该在创建账户对象的时候就存在了

故可以在创建的时候直接给账户 id 赋值

  public Account(long accountId){
    this.accountId = accountId
  }

- account 对象中,updateTime 属性是可以随便赋值的么?

从代码中我们可以发现,在这个 account 账户对象中,一旦对象创建之后可以更改的只有余额 balance 跟最后更新时间,而最后更新时间是伴随着对象的更改才会更新,不会存在单独更新最后更新时间的场景

那么 setUpdateTime 方法就不能开放出去了,从类中可知,我们可以在更新余额的时候可以更新 updateTime,因为只存在余额一个变化因素

  public void setBalance(long balance){
    this.balance=balance
    this.updateTime = new Date();
  }

这种方式避免了调用方人为的错误,比如只设置了余额但是未设置更新时间

- 日常生活中,我们比如银行账户,都是存钱,取钱,即有个扣减或增加余额的步骤,没有说我存钱是直接给账户余额设置多少的概念,所以我们可以将 setBalance 方法调整成如下

  //增加余额
  public void addBalance(long money){
    this.balance=balance + money;
    this.updateTime = new Date();
  }
  //扣减余额
  public void reduceBalance(long money){
    if (balance       抛出异常,余额不足
    }
    this.balance = this.balance - money;
    this.updateTime = new Date();
  }

这种方式,就严格控制了余额的限制条件,后续如果有其他条件判断,也可在这个类内部进行处理,修改较为容易

改造后的类定义如下

// FileName:Account.java
// 账户表
public class Account{
  private long accountId;  //账户id
  private long balance;   //账户余额
  private DateTime updateTime; //最后更新时间

  public Account(long accountId, long initBalance){
    this.accountId = accountId;
    this.balance = initBalance;
    this.updateTime = new Date();
  }

  public long getAccountId(){
    return accountId;
  }
  public long getBalance(){
    return balance;
  }
  public DateTime getUpdateTime{
    return updateTime;
  }

  public void addBalance(long money){
    this.balance=balance + money;
    this.updateTime = new Date();
  }
  public void reduceBalance(long money){
    if (balance       抛出异常,余额不足
    }
    this.balance = this.balance - money;
    this.updateTime = new Date();
  }
}

上述流程可知,我们对面向对象的封装特性大体有了一个整体的印象

封装是把过程和数据包围起来,对数据的访问只能通过已定义的方法。

面向对象计算始于这个基本概念,即现实世界可以被描绘成一系列完全自治、封装的对象,这些对象通过一个受保护的接口访问其他对象。一旦定义了一个对象的特性,则有必要决定这些特性的可见性,即哪些特性对外部世界是可见的,哪些特性用于表示内部状态。

在这个阶段定义对象的接口。通常,应禁止直接访问一个对象的实际表示,而应通过操作接口访问对象,这称为信息隐藏。

事实上,信息隐藏是用户对封装性的认识,封装则为信息隐藏提供支持。封装保证了模块具有较好的独立性,使得程序维护修改较为容易。对应用程序的修改仅限于类的内部,因而可以将应用程序修改带来的影响减少到最低限度

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值