面向对象的设计思想
封装
- 封装的是数据和基于数据的操作 – 构成不可分割的实体
- 隐藏内部细节,只**暴露对外的接口(方法)**使其与外部发生联系
优点
- 减少耦合:各个模块相互独立
- 提升代码重用性
- 降低程序风险:整个系统不可用,但是单个模块是可用的
- 易于维护和性能分析
典型例子:Java Bean (POJO)
继承
对象之间的is-A
的关系。
继承需要遵循里氏替换原则:子类对象可以完全替换父类
多态
- 编译时多态:方法的重载
- 运行时多态:类型只有在真正运行的时候才会最终确认
- 条件:
- 继承:声明类与被声明类之间有继承关系
- 覆写:子类中实现了对父类方法的覆写
- 向上转型:由一个父类去声明其对应的子类
- 条件:
Instrument a = new Wind();
类图关系
- 泛化关系:描述继承。extends关键字
- 实现关系:实现接口。implements 关键字
- 聚合关系:整体由部分构成。没了整体,部分还是存在的
- 组合关系:整体和部分强依赖,整体不存在部分也就不存在
- 关联关系:表示不同类对象之间有关联,这是一种静态关系,与运行过程的状态无关,在最开始就可以确定
- 依赖关系:运行过程中起作用的
- A是B的局部变量
- A是B的方法参数
- A会影响B内部的变化
设计原则 – S.O.L.I.D
- 单一责任原则 The Single Responsibility Principle
- 修改一个类的原因只能有一个(解耦)
- 一个类只负责一件事。当这个类承担的事情较多,需要对类进行分解
- 开放封闭原则 The Open Closed Principle
- 类应该对扩展开放,对修改封闭
- 要求类在扩展功能的时候不修改原来的代码(典例 – 装饰者模式)
- 里氏替换原则 The Liskov Substitution Principle
- 子类应该可以完全替换父类
- 否则会增加继承体系的复杂度
- 接口分离原则 The Interface Segregation Principle
- 不应该强迫类依赖于它们不用的方法
- 多个专用接口比一个单一的总接口好(总接口的一些方法类不一定要使用)
- 依赖倒置原则 The Dependency Inversion Principle
-
高层模块不应该依赖于低层模块,二者都应该依赖于抽象。
- 否则低层的更改就会影响到高层的功能,迫使高层改动
-
抽象不应依赖于细节,细节要依赖于抽象(最难理解)
-
依赖于抽象的含义
- 任何变量都不应该持有一个指向具体类的指针或者引用;
不能在类的内部出现 private ArrayList arr = new ArrayList<>();这种直接赋引用
而是private List arr; 这样的抽象实现
- 任何类都不应该从具体类派生;(需要通过抽象类或接口派生)
- 任何方法都不应该覆写它的任何基类中的已经实现的方法。(只覆写抽象方法,不然想要调用父类方法的时候会出错)
-
可以看下面这个实例
public class DIPtest
{
public static void main(String[] args)
{
Customer wang=new Customer();
System.out.println("顾客购买以下商品:");
wang.shopping(new ShaoguanShop());
wang.shopping(new WuyuanShop());
}
}
//商店
interface Shop
{
public String sell(); //卖
}
//韶关网店
class ShaoguanShop implements Shop
{
public String sell()
{
return "韶关土特产:香菇、木耳……";
}
}
//婺源网店
class WuyuanShop implements Shop
{
public String sell()
{
return "婺源土特产:绿茶、酒糟鱼……";
}
}
//顾客
class Customer
{
// 顾客类依赖的是Shop这个抽象 -- 不关注具体是哪个Shop
public void shopping(Shop shop)
{
//购物
System.out.println(shop.sell());
}
}