复用

    技术2025-09-20  40

    1.里氏替换原则

    里氏代换原则是面向对象设计的基本原则之一。 里氏代换原则中说,任何基类可以出现的地方,子类一定可以出现。LSP 是继承复用的基石,只有当派生类可以替换掉基类,且软件单位的功能不受到影响时,基类才能真正被复用,而派生类也能够在基类的基础上增加新的行为。

    类型替换:

    ①子类型只能增加而不能删除方法

    ②子类型需要实现抽象类中所有未实现的方法

    ③子类型中重写的方法,它的返回值必须是相等类型或是协变类型。

    ④子类型中重写的方法,它的返回值必须是相等类型或是逆变类型(java不支持)。

    ⑤子类型中重写的方法不能抛出额外的异常(必须是被重写方法抛出的异常及其子类)。

    方法重写:

    ①更强的不变量(规则限制)

    ②更弱的前置条件

    ③更强的后置条件

    2.协变、逆变

    协变:子类型代替父类型出现,更具体

    比如数组中相应子类型的数组引用可以传给父类型

    比如泛型中的通配符<?> <? extends xxx>

    逆变:父类型代替子类型出现,更抽象

    3.委托

    一个对象请求另一个对象的功能

    与继承相比,主要发生在对象层面,可以选择性的使用方法,比继承更自由。

    ①将其传入一个具体方法的参数,用完就解除关系。

    ②将其写入构造函数的参数中,并设立一个字段与委托对象建立联系。

    ③直接将其固定在一个字段中。

    ④将其写入一个字段中,并可通过set()方法更改。

    4.黑盒框架、白盒框架

    白盒框架:通过继承框架类,重写框架方法使用框架

    允许扩展每一个非私有方法 需要理解父类的实现 一次只进行一次扩展 通常被认为是开发者框架 黑盒框架:通过委派、组合、调用方法,使用框架类,内部不可见。

    允许在接口中对public方法扩展 只需要理解接口 通常提供更多的模块 通常被认为是终端用户框架,平台

    5.常用接口、功能类总结

    Iterator、Iterable iterator是一个接口

    package java.util; public interface Iterator<AnyType> { boolean hasNext(); AnyType next(); void remove(); //上次next执行结果的元素 }

    iterable是一个泛型接口

    package java.lang; public interface Iterable<AnyType> { Iterator<AnyType> iterator(); }

    删除元素的三种方式

    1.普通for循环 2.迭代器删除

    Iterator<String> it = list.iterator(); while(it.hasNext()) {   if("b".equals(it.next())) {     //list.remove("b"); //不能用集合的删除方法,因为迭代过程中如果集合修改会出现并发修改异常     it.remove();   } } for(Iterator<String> it2 = list.iterator(); it2.hasNext();) {   if("b".equals(it2.next())) {     //list.remove("b"); //不能用集合的删除方法,因为迭代过程中如果集合修改会出现并发修改异常     it2.remove();   } }

    3.另一种for循环

    for (String string : list) { if("b".equals(string)){ list.remove("b"); } }

    Observer、Observable Observer:接口、观察者

    package java.util; public interface Observer { void update(Observable o, Object arg); }

    Observable:类、被观察者

    package java.util; public class Observable { private boolean changed = false;  //是否改变状态 private Vector obs;    //Vector利用同步方法来线程安全,线程安全在多线程情况下不会造成数据混乱 public Observable() { obs = new Vector(); } public synchronized void addObserver(Observer o) { if (o == null) throw new NullPointerException(); if (!obs.contains(o)) { obs.addElement(o); } } public synchronized void deleteObserver(Observer o) { obs.removeElement(o); } public void notifyObservers() { notifyObservers(null); } public void notifyObservers(Object arg) { Object[] arrLocal; synchronized (this) { if (!changed)    //状态值未改变时返回,不通知 return; arrLocal = obs.toArray();  //将Vector转换成数组 clearChanged();    //重置状态 } for (int i = arrLocal.length-1; i>=0; i--) ((Observer)arrLocal[i]).update(this, arg); } public synchronized void deleteObservers() { obs.removeAllElements(); } protected synchronized void setChanged() { changed = true; } protected synchronized void clearChanged() { changed = false; } public synchronized boolean hasChanged() { return changed; } public synchronized int countObservers() { return obs.size(); } }

    Comparable、Comparator Comparable是排序接口。若一个类实现了Comparable接口,就意味着该类支持排序。实现了Comparable接口的类的对象的列表或数组可以通过Collections.sort或Arrays.sort进行自动排序。

    此外,实现此接口的对象可以用作有序映射中的键或有序集合中的集合,无需指定比较器。该接口定义如下:

    package java.lang; import java.util.*; public interface Comparable<T> { public int compareTo(T o); }

    Comparator是比较接口,我们如果需要控制某个类的次序,而该类本身不支持排序(即没有实现Comparable接口),那么我们就可以建立一个“该类的比较器”来进行排序,这个“比较器”只需要实现Comparator接口即可。也就是说,我们可以通过实现Comparator来新建一个比较器,然后通过这个比较器对类进行排序。该接口定义如下:

    package java.util; public interface Comparator<T> { int compare(T o1, T o2); boolean equals(Object obj); }

    注意:1、若一个类要实现Comparator接口:它一定要实现compare(T o1, T o2) 函数,但可以不实现 equals(Object obj) 函数。

    2、int compare(T o1, T o2) 是“比较o1和o2的大小”。返回“负数”,意味着“o1比o2小”;返回“零”,意味着“o1等于o2”;返回“正数”,意味着“o1大于o2”。

    排序 数组排序:Array.sort(int[] a)

    List item

    集合排序:

    1.Collections.sort(List list) 2.Collections.sort(List list,Comparator c)

    Processed: 0.012, SQL: 9