05:封装、抽象、继承、多态分别可以解决哪些编程问题?
import java.math.BigDecimal;
/**
* Author : CHR_崔贺然
* Time : 2019 11.18
* Description : 极客时间专栏:设计模式之美 05,封装继承多态
* 封装:其中一个核心的概念就是访问权限控制Java中用public和private进行访问权限控制。
* 抽象:封装主要讲如何隐藏信息、保护数据,抽象是讲如何隐藏方法的具体实现,让调用者只需关系方法提供了哪些功能
* 并不需要知道这些功能如何实现。
* 通常使用编程语言提供的接口类(Java中的interface关键字语法)或者抽象类(Java中的abstract关键字语法)实现抽象
* 以后管接口叫接口类,接口这个词太泛化,可以指好多概念比如API等,所以用接口类特指编程中的接口语法
*/
// 利用OOP的设计思想来介绍虚拟钱包的设计实现
public class Wallet {
// 四个成员变量
private String id;
private long createTime;
private BigDecimal balance;
private long balanceLastModifiedTime;
// 构造器:构造函数
public Wallet() {
this.id = IdGenerator.getInstance().generate(); // id为唯一编号
this.createTime = System.currentTimeMillis(); // 钱包创建的时间
this.balance = BigDecimal.ZERO; // 钱包中的余额
this.balanceLastModifiedTime = System.currentTimeMillis(); // 上一次钱包变更的时间
}
// 从业务角度来说id createTime在创建钱包时就确定好了,之后不应该再改动
// 所以没有暴露id createTime属性的任何修改方法,比如set方法
// 这两个参数对于类的调用者来说应该是透明的,所以在Wallet类构造喊出内部将其初始化好而不是传参འི外部赋值
public String getId() {
return this.id;
}
public long getCreateTime() {
return this.createTime;
}
public BigDecimal getBalance() {
return this.balance;
}
public long getBalanceLastModifiedTime() {
return this.balanceLastModifiedTime;
}
public void increaseBalance(BigDecimal increasedAmount) {
if (increasedAmount.compareTo(BigDecimal.ZERO) < 0) {
throw new InvalidAmountException("...");
}
if (decreasedAmount.compareTo(this.balance) > 0) {
throw new InsufficientAmountException("...");
}
this.balance.subtract(decreaseAmount); // 当钱包减少了钱
this.balanceLastModifiedTime = System.currentTimeMillis(); // 更前最近一次扣钱的时间
}
}
/**
* Author : CHR_崔贺然
* Time : 2019 11.18
* Description : 抽象在Java中通过接口实现,在调用存储功能的时候只需要了解IPictureStorage这个接口暴露的方法即可
不需要去查看里面的具体实现,其实并不是说一定要为实现类PictureStorage抽象出IPictureStorage接口
很多设计原则都体现了抽象的思想,比如基于接口而非实现编程、开闭原则(对扩展开放、对修改关闭)、代码解耦等。
在定义方法中不要暴露太多细节,比如getAliyunPictureUrl()就不是一个具有抽象思维的命名,耦合性太重
解耦、抽象的目的就是为了只改一行代码,低耦合
*/
import javafx.scene.image.Image;
// 定义一组接口(接口类)
public interface IPictureStorage {
void savePicture(Picture picture);
Image getPicture(String pictureId);
void deletePicture(String pictureId);
void modifyMetaInfo(String picture, PictureMetaInfo metaInfo);
}
public class PictureStorage implements IPictureStorage {
@Override
public void savePicture(Picture picture) {
System.out.println("1");
}
@Override
public Image getPicture(String pictureId) {
System.out.println("2");
}
@Override
public void deletePicture(String pictureId) {
System.out.println("3");
}
@Override
public void modifyMetaInfo(String pictureId, PictureMetaInfo metaInfo) {
System.out.println("4");
}
}
// java不支持多继承
// 多用组合,少用继承,继承的过多,代码结构过于复杂
// 多态就是继承(接口实现)之后,重写方法。基于一组接口各自对其扩充功能实现多种状态。
// 动态语言是有duck-type
/**
* Author : CHR_崔贺然
* Time : 2019 11.18
* Description : 多态Demo,多继承和多态的区别,一个是在定义时就定好了,一个是在要执行时才确定,通过参数传进去
* 多继承会存在菱形继承的问题,所以java不支持多继承,用接口实现多态
*/
// 用于多态实现的接口
public interface Iterator {
String hashNext();
String next();
String remove();
}
// LinkList实现接口
public class LinkedList implements Iterator {
private LinkedListNode head;
// 重写hashNext()方法
public String hashNext() {
System.out.println("LinkListHashNext");
}
// 重写next()方法
public String next() {
System.out.println("LinkListNext");
}
// 重写remove()方法
public String remove() {
System.out.println("LinkListRemove");
}
}
// 实现Array接口,这就是多态
public class Array implements Iterable {
private String[] data;
public String hashNext() {
System.out.println("ArrayHashNext");
}
public String next() {
System.out.println("ArrayNext");
}
public String remove() {
System.out.println("ArrayRemove");
}
}
/**
* Demo
* 如果不同多态就不能将不同的集合类型传递给相同的函数,其实也是一种工厂方法的解耦表现
*/
public class Demo {
private static void print(Iterator iterator) {
while (iterator.hashNext()) {
System.out.println(iterator.next());
}
}
public static void main(String[] args) {
Iterator arr = new Array();
print(arr);
Iterator link = new LinkedList();
print(link);
}
}
'''
Author : CHR_崔贺然
Time : 2019.11.18
Description : duct-type实现多态
'''
class Iter:
def next(self):
pass
class Array:
def next(self):
print("Array next")
class LinkList:
def next(self):
print("LinkList next")
def do(obj):
res = obj.next()
def main():
arr = Array()
link = LinkList()
do(arr)
do(link)
if __name__ == "__main__":
main()