1.字段上移
俩个子类拥有相同的字段,将该字段移至超类
2.函数上移
函数在各个子类中作用相同,移至超类
3.构造函数本体上移
在超类中新建一个构造函数,并在子类构造函数中调用它
public class Manager extends Employee{
private String name;
private String id;
private String grade;
public Manager(String name, String id, String grade) {
//this.name = name;
//this.id = id;
super(name,id);
this.grade = grade;
}
}
public abstract class Employee {
private String name;
private String id;
protected Employee(String name, String id) {
this.name = name;
this.id = id;
}
}
4.函数下移
超类中的某个函数只与部分函数有关,将这个函数移至相关的子类中去
5.字段下移
超类中的某个字段只被部分子类使用,将这个字段移到那些子类
6.提炼子类
类中的某些特性只被某些实例使用,新建一个子类,将这些特性移到子类中
做法:
为源类建立一个新的子类
为新子类提供构造函数,让子类构造函数接收与超类构造函数相同的参数,通过super调用超类的构造函数
找出调用超类构造函数的所有地点,如果它们需要的是新建的子类,令它们改而调用新构造函数
将源类的特性移到子类去
public class JobItem {
private int unitPrice;
private int quantity;
protected Employee employee;
private boolean isLabor;
// protected JobItem(int unitPrice, int quantity, Employee employee, boolean isLabor) {
// this.unitPrice = unitPrice;
// this.quantity = quantity;
// this.employee = employee;
// this.isLabor = isLabor;
// }
protected JobItem(int unitPrice, int quantity, boolean isLabor) {
this.unitPrice = unitPrice;
this.quantity = quantity;
this.isLabor = isLabor;
}
// public JobItem(int unitPrice, int quantity) {
// this(unitPrice, quantity, null, false);
// }
public int getTotalPrice(){
return getUnitPrice()*this.quantity;
}
// public int getUnitPrice() {
// return this.isLabor?this.employee.getRate():this.unitPrice;
// }
public int getUnitPrice() {
return this.unitPrice;
}
public int getQuantity() {
return quantity;
}
public Employee getEmployee() {
return employee;
}
// public boolean isLabor() {
// return isLabor;
// }
protected boolean isLabor() {
return false;
}
}
public class LaborItem extends JobItem{
private Employee employee;
// public LaborItem(int unitPrice, int quantity, Employee employee, boolean isLabor) {
// super(unitPrice, quantity, employee, isLabor);
//
// }
// public LaborItem(int quantity, Employee employee) {
// super(0, quantity, employee, true);
// }
public LaborItem(int quantity, Employee employee) {
super(0, quantity, true);
this.employee = employee;
}
public Employee getEmployee(){
return this.employee;
}
public boolean isLabor() {
return true;
}
public int getUnitPrice() {
return this.employee.getRate();
}
}
public class Employee {
private int rate;
public int getRate(){
return this.rate;
}
}
7.提炼超类
俩个类有相似特性,为这俩个类建立一个超类,将相同特性移至超类
//员工部门都有名称,都有年度成本
public abstract class Party {
//特性移至超类
protected String name;
//构造器上移
protected Party(String name){
this.name = name;
}
//函数移至超类
public String getName() {
return name;
}
//声明抽象函数
abstract public int getAnnulCast();
}
public class Employee extends Party{
private String name;
private int annulCast;
private String id;
public Employee(String name, int annulCast, String id) {
//this.name = name;
super(name);
this.annulCast = annulCast;
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAnnulCast() {
return annulCast;
}
public void setAnnulCast(int annulCast) {
this.annulCast = annulCast;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
public class Department extends Party{
private String name;
private Vector staff = new Vector();
public Department(String name) {
//this.name = name;
super(name);
}
//public int getTotalAnnualCost(){
//改名
public int getAnnulCast(){
Enumeration e = getStaff();
int result = 0;
while(e.hasMoreElements()){
Employee each = (Employee) e.nextElement();
result+=each.getAnnulCast();
}
return result;
}
public int getHeadCount(){
return this.staff.size();
}
public Enumeration getStaff(){
return this.staff.elements();
}
public void addStaff(Employee employee){
this.staff.addElement(employee);
}
public String getName() {
return name;
}
}
8.提炼接口
若干客户使用类接口中的同一个子集,或者俩个类的接口有部分相同,将相同的子集提炼到一个独立接口中
9.折叠继承关系
超类子类间无太大区别,整合
10.塑造模板函数
一些子类,其中相应的某些函数以相同顺序执行类似的操作,但各个操作的细节上有所不同,将这些操作分别放入独立的函数中,并保持它们都有相同的签名,将原函数上移至超类
做法:
在各个子类中分解目标函数,使分解后的各个函数要不完全相同,要不完全不同
将各子类中完全相同的函数上移至超类
完全不同的函数将这些函数签名改为相同的
将所有原函数卓一移至超类,将那些代表各种不同操作的函数定义为抽象函数
11.以委托取代继承
某个子类只使用超类接口的一部分,或根本不需要继承而来的数据,在子类中新建一个字段,用以保存超类,调整子类函数,令它改而委托超类,去掉俩者间的继承关系
做法:
在子类中新建一个字段,使其引用超类的一个实例,并将它初始化为this
修改子类中的所有函数,让他们不再使用超类,转而使用上述那个受委字段
针对客户端使用的每一个超类函数,为他添加一个委托函数
//public class MyStack extends Vector{
public class MyStack{
//新建字段
//private Vector vector = this;
private Vector vector = new Vector();
public void push(Object element){
//修改,使用委托
// insertElementAt(element, 0);
vector.insertElementAt(element, 0);
}
public Object pop(){
// Object result =firstElement();
// removeElementAt(0);
Object result =vector.firstElement();
vector.removeElementAt(0);
return result;
}
public int size(){
return vector.size();
}
public boolean isEmpty(){
return vector.isEmpty();
}
}
12.以继承取代委托
在俩个类之间使用委托关系,为整个接口编写许多极简单的委托函数,让委托类继承受托类
做法:
让委托端成为受托端的一个子类
将受托字段设为该字段所处对象本身
去掉简化的委托函数
将所有其他涉及委托关系的代码改为调用对象本身
public class Persion {
String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getLastName(){
return this.name.substring(this.name.lastIndexOf(' ')+1);
}
}
//public class Employee {
public class Employee extends Persion{
//Persion persion = new Persion();
public Persion getPersion() {
//return persion;
return getPersion();
}
public void setPersion(Persion persion) {
//this.persion = persion;
setPersion(persion);
}
@Override
public String toString() {
//return "Emp:"+ this.persion.getLastName();
return "Emp:"+ getLastName();
}
}