这是一篇专栏学习总结。主要从特性的定义及意义两方面解读。
封装
- 什么是封装
封装是对信息的隐藏和保护,类通过暴露有限的访问接口,授权外部访问内部的信息或数据。 - 怎样实现封装
通过访问权限控制,private只允许类内部访问,public提供外部访问接口 - 封装的意义
如果对类中的属性方法的访问不做限制,那任何代码都可以访问、修改类的属性,虽然看起来很灵活方便,但是同时也意味着不可控,属性可以被任何方式修改,且修改的代码散落在项目中的各个角落,势必就影响代码的可读性、可维护性。通过封装只暴露必要的接口,有利于调用者正确操作属性,提高类的易用性。 - 示例
/**
*
* @desc
* 钱包Wallet类包含id唯一ID,createTime创建时间,updateTime上次更新时间,balance余额。
* 从业务的角度考虑,只提供了六个public方法提供外部访问,id,createTime在创建钱包的时候就决定了,
* 之后应该是不允许被修改的,所以只暴露get方法
* 而且这两个值的初始化操作对调用者应该也是透明的,在构造方法中直接初始化,而不是通过外部赋值。
* 对于钱包的balance,应该只能增或减,不能被重新设置,
* 且伴随着updateTime属性的修改,所以balance和updateTime都只暴露了get方法,
* 通过increaseBalance和decreaseBalance封装balance和updateTime的修改,
* 这样既不暴露内部细节,同时保证了数据的一致性。
*/
public class Wallet {
private String id;
private long createTime;
private long updateTime;
private BigDecimal balance;
public Wallet() {
this.id = IdGenerator.getInstance().generate();
this.createTime = System.currentTimeMillis();
this.updateTime = System.currentTimeMillis();
this.balance = BigDecimal.ZERO;
}
public String getId() {
return this.id;
}
public long getCreateTime() {
return this.createTime;
}
public BigDecimal getBalance() {
return this.balance;
}
public long getUpdateTime() {
return this.updateTime;
}
public void increaseBalance(BigDecimal increaseAmount) {
//参数检查
this.balance.add(increaseAmount);
this.updateTime = System.currentTimeMillis();
}
public void decreaseBalance(BigDecimal decreaseAmount) {
//参数检查
this.balance.subtract(decreaseAmount);
this.updateTime = System.currentTimeMillis();
}
}
抽象
- 什么是抽象
抽象是对方法具体实现的隐藏,调用者只需关注方法提供了哪些功能,而不用关注方法如何实现这些功能。 - 怎样实现抽象
Java通过interface和abstract语法机制实现抽象。其实函数也可以说是一种抽象,函数隐藏了具体实现逻辑,调用者使用函数的时候,不用关注函数内部的实现逻辑。 - 抽象的意义
抽象是处理复杂性系统的有效手段,作为一个非常宽泛的设计思想,在代码设计中,起到非常重要的指导作用,基于接口而非实现编程、开闭原则等设计原则及设计模式都体现了抽象的设计思想。大到代码设计,小到类方法命名,抽象思想都很重要,方法命名不暴露太多细节,可保证在某个时间点需要修改方法实现细节时而可以不修改命名。比如getPictureFromCeph()就不是一个具有抽象思维的方法命名,当某一天图片不存储在Ceph上,那这个方法命名也要随之修改。
继承
-
什么是继承
继承是用来表示类之间的is-a关系的一种特性,Java只支持单继承,为什么不支持多继承?
因为多继承会带来钻石问题(菱形继承)的副作用。假设B extends A,C extends A,且都重写了A中的一个方法F,同时D extends B,C,那么D会继承B和C的方法包括方法F,但这里的方法F到底是B的方法还是C的方法呢,这里就会产生歧义。考虑到这个问题,Java不支持多继承 -
怎样实现继承
java通过关键字extends实现继承 -
继承的意义
继承最大的一个好处就是代码复用,如果两个类有一些相同的类和方法,可以将相同的类和方法抽取到父类,让两个子类继承父类,实现代码复用,但是如果过度使用继承,继承的层次过深过复杂,便会影响代码的可读性及可维护性。为了了解一个类的完整功能,需要不断追溯其父类的功能,且修改父类直接影响所有子类。
多态
- 什么是多态
多态是指,子类可以替换父类,在代码运行过程中,实际调用子类的方法实现。 - 怎样实现多态
Java通过继承实现父子关系,同时通过override实现子类重写父类方法,配合一起便实现了多态特性。同时接口也可实现多态特性。 - 多态的意义
多态提高了代码的可扩展性和复用性。多态也是很多设计模式、设计原则的实现基础,比如里式替换原则、基于接口而非实现编程、策略模式、模板模式等。 - 示例
这里Array 和LinkedList 都实现了接口类Iterator,对于方法print(Iterator iterator) ,支持动态调用next()和hasNext()的实现,传递什么子类就会调用什么子类的实现逻辑。这里利用多态的特性,通过print函数可以实现遍历不同类型集合的数据,当要增加一种需要遍历功能的集合类型时,只要实现Iterator接口,实现自己的next(),hasNext()逻辑,不需要改动print方法,所以说多态提高了代码的可扩展性及复用性。
public interface Iterator {
String hasNext();
String next();
String remove();
}
public class Array implements Iterator {
private String[] data;
public String hasNext() { ... }
public String next() { ... }
public String remove() { ... }
}
public class LinkedList implements Iterator {
private LinkedListNode head;
public String hasNext() { ... }
public String next() { ... }
public String remove() { ... }
}
public class Demo {
private static void print(Iterator iterator) {
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
public static void main(String[] args) {
Iterator arrayIterator = new Array();
print(arrayIterator);
Iterator linkedListIterator = new LinkedList();
print(linkedListIterator);
}
}
本文深入探讨面向对象编程的四大核心特性:封装、抽象、继承和多态。封装确保数据安全,抽象简化复杂性,继承促进代码复用,多态增强代码灵活性。通过实例展示每个特性的重要性和应用。
7671

被折叠的 条评论
为什么被折叠?



