一、
以人及其属性为例:
abstract class Person {
String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public abstract void desc();
}
class Chinese extends Person {
@Override
public void desc() {
// TODO Auto-generated method stub
System.out.println(name + "是中国人");
}
}
class American extends Person {
@Override
public void desc() {
// TODO Auto-generated method stub
System.out.println("是米国人");
}
}
class highChinese extends Chinese {
public void desc() {
super.desc();
System.out.println("是high人");
}
}
class richChinese extends Chinese {
public void desc() {
super.desc();
System.out.println("是rich人");
}
}
class highrichChinese extends Chinese {
public void desc() {
super.desc();
System.out.println("是high&rich人");
}
}
class HighAmerican extends American {
public void desc() {
super.desc();
System.out.println("是high人");
}
}
class RichAmerican extends American {
public void desc() {
super.desc();
System.out.println("是rich人");
}
}
class HighRichAmerican extends American {
public void desc() {
super.desc();
System.out.println("是high&rich人");
}
}
public class Main {
public static void main(String[] args) {
highChinese hc = new highChinese();
hc.setName("yaoming");
richChinese rc = new richChinese();
rc.setName("mayun");
HighRichAmerican hra = new HighRichAmerican();
hra.setName("tom");
hc.desc();
rc.desc();
hra.desc();
}
}
缺点:随着需求的变化,子类会急剧增多,充斥着重复代码,此时的关键是划清责任。
改进版本一(组合代替继承):
abstract class Person {
String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public abstract void desc();
}
class Chinese extends Person {
@Override
public void desc() {
// TODO Auto-generated method stub
System.out.println(name + "是中国人");
}
}
class American extends Person {
@Override
public void desc() {
// TODO Auto-generated method stub
System.out.println("是米国人");
}
}
class highChinese extends Chinese {
Chinese person;
public void desc() {
super.desc();
System.out.println("是high人");
}
public highChinese(Chinese person) {
this.person = person;
}
}
class richChinese extends Chinese {
Chinese person;
public void desc() {
super.desc();
System.out.println("是rich人");
}
public richChinese(Chinese person) {
this.person = person;
}
}
class highrichChinese extends Chinese {
Chinese person;
public void desc() {
super.desc();
System.out.println("是high&rich人");
}
public highrichChinese(Chinese person) {
this.person = person;
}
}
class HighAmerican extends American {
American person;
public void desc() {
super.desc();
System.out.println("是high人");
}
public HighAmerican(American person) {
this.person = person;
}
}
class RichAmerican extends American {
American person;
public void desc() {
super.desc();
System.out.println("是rich人");
}
public RichAmerican(American person) {
this.person = person;
}
}
class HighRichAmerican extends American {
American person;
public void desc() {
super.desc();
System.out.println("是high&rich人");
}
public HighRichAmerican(American person) {
this.person = person;
}
}
public class Main {
public static void main(String[] args) {
Chinese p = new Chinese();
p.setName("yaoming");
highChinese hc = new highChinese(p);
hc.desc();
p.setName("mayun");
richChinese rc = new richChinese(p);
rc.desc();
American q = new American();
q.setName("rom");
HighRichAmerican hra = new HighRichAmerican(q);
hra.desc();
}
}
继续改进,可以用基类代替子类,消除编译时的依赖;
如:
class highChinese extends Chinese {
Person person; //基类代替子类,消除编译时的依赖
public void desc() {
super.desc();
System.out.println("是high人");
}
public highChinese(Person person) {
this.person = person;
}
}
//......其他类似
消除重复,highChinese与highAmerican可以合并为:highPerson等。
abstract class Person {
String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public abstract void desc();
}
class Chinese extends Person {
@Override
public void desc() {
// TODO Auto-generated method stub
System.out.println(name + "是中国人");
}
}
class American extends Person {
@Override
public void desc() {
// TODO Auto-generated method stub
System.out.println("是米国人");
}
}
class highPerson {
Person person; // 基类代替子类,消除编译时的依赖
public void desc() {
person.desc();
System.out.println("是high人");
}
public highPerson(Person person) {
this.person = person;
}
}
class richPerson {
Person person;
public void desc() {
person.desc();
System.out.println("是rich人");
}
public richPerson(Person person) {
this.person = person;
}
}
class highrichPerson {
Person person;
public void desc() {
person.desc();
System.out.println("是high&rich人");
}
public highrichPerson(Person person) {
this.person = person;
}
}
public class Main {
public static void main(String[] args) {
Chinese p = new Chinese();
p.setName("yaoming");
highPerson hc = new highPerson(p);
hc.desc();
p.setName("mayun");
richPerson rc = new richPerson(p);
rc.desc();
American q = new American();
q.setName("rom");
highrichPerson hra = new highrichPerson(q);
hra.desc();
}
}
发现问题 : 为了保证从继承转组合以后的抽象接口函数public void desc() 遵循接口规范 ,即继承基类设置的抽象接口函数public void desc() 。还是需要通过继承来完善接口规范,不过只需要继承基类Person。
abstract class Person {
String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public abstract void desc();
}
class Chinese extends Person {
@Override
public void desc() {
// TODO Auto-generated method stub
System.out.println(name + "是中国人");
}
}
class American extends Person {
@Override
public void desc() {
// TODO Auto-generated method stub
System.out.println("是米国人");
}
}
class highPerson extends Person {
Person person; // 基类代替子类,消除编译时的依赖
public void desc() {
person.desc();
System.out.println("是high人");
}
public highPerson(Person person) {
this.person = person;
}
}
class richPerson extends Person {
Person person;
public void desc() {
person.desc();
System.out.println("是rich人");
}
public richPerson(Person person) {
this.person = person;
}
}
class highrichPerson extends Person {
Person person;
public void desc() {
person.desc();
System.out.println("是high&rich人");
}
public highrichPerson(Person person) {
this.person = person;
}
}
public class Main {
public static void main(String[] args) {
Chinese p = new Chinese();
p.setName("yaoming");
highPerson hc = new highPerson(p);
hc.desc();
p.setName("mayun");
richPerson rc = new richPerson(p);
rc.desc();
American q = new American();
q.setName("rom");
highrichPerson hra = new highrichPerson(q);
hra.desc();
}
}
继续发现问题:根据重构,当类中含有重复字段和方法 ,应该将其提到基类中去。
解决:设计一个中间基类 。这样就引出了装饰模式 。
改进版本二(使用装饰模式 改进版本二(使用装饰模式< 中间基类>)
abstract class Person {
String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public abstract void desc();
}
class Chinese extends Person {
@Override
public void desc() {
// TODO Auto-generated method stub
System.out.println(name + "是中国人");
}
}
class American extends Person {
@Override
public void desc() {
// TODO Auto-generated method stub
System.out.println("是米国人");
}
}
abstract class DecoratorPerson extends Person {
Person person;
public DecoratorPerson(Person person) {
this.person = person;
}
}
class highPerson extends DecoratorPerson {
@Override
public void desc() {
// TODO Auto-generated method stub
person.desc();
System.out.println("是high人");
}
public highPerson(Person person) {
super(person);
}
}
class richPerson extends DecoratorPerson {
@Override
public void desc() {
// TODO Auto-generated method stub
person.desc();
System.out.println("是high人");
}
public richPerson(Person person) {
super(person);
}
}
class highrichPerson extends DecoratorPerson {
@Override
public void desc() {
// TODO Auto-generated method stub
person.desc();
System.out.println("是high人");
}
public highrichPerson(Person person) {
super(person);
}
}
public class Main {
public static void main(String[] args) {
Chinese p = new Chinese();
p.setName("yaoming");
highPerson hc = new highPerson(p);
hc.desc();
p.setName("mayun");
richPerson rc = new richPerson(p);
rc.desc();
American q = new American();
q.setName("rom");
highrichPerson hra = new highrichPerson(q);
hra.desc();
}
}
此时,无论是增加国家还是增加属性只需增加一个类。
扩展操作,对各国人进行 操作,增加一个属性:
abstract class Person {
String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public abstract void desc();
}
class Chinese extends Person {
@Override
public void desc() {
// TODO Auto-generated method stub
System.out.println(name + "是中国人");
}
}
class American extends Person {
@Override
public void desc() {
// TODO Auto-generated method stub
System.out.println("是米国人");
}
}
abstract class DecoratorPerson extends Person {
Person person;
public DecoratorPerson(Person person) {
this.person = person;
}
}
class highPerson extends DecoratorPerson {
@Override
public void desc() {
// TODO Auto-generated method stub
person.desc();
System.out.println("是high人");
}
public highPerson(Person person) {
super(person);
}
}
class richPerson extends DecoratorPerson {
@Override
public void desc() {
// TODO Auto-generated method stub
person.desc();
System.out.println("是high人");
}
public richPerson(Person person) {
super(person);
}
}
class highrichPerson extends DecoratorPerson {
@Override
public void desc() {
// TODO Auto-generated method stub
person.desc();
System.out.println("是high人");
}
public highrichPerson(Person person) {
super(person);
}
}
class handsomePerson extends DecoratorPerson {
// 为避免重复,实现接口继承DecoratorPerson
// Person person; // 基类代替子类,消除了编译时依赖
public void desc() {
person.desc();
System.out.println(" 是handsome 人");
}
public handsomePerson(Person person) {
super(person);
}
};
public class Main {
public static void main(String[] args) {
Chinese p = new Chinese();
p.setName("yaoming");
highPerson hc = new highPerson(p);
hc.desc();
p.setName("mayun");
richPerson rc = new richPerson(p);
rc.desc();
American q = new American();
q.setName("rom");
// highrichPerson hra = new highrichPerson(q);
// hra.desc();
highPerson hp = new highPerson(p);
richPerson rp = new richPerson(hp);
rp.desc();
handsomePerson hsp = new handsomePerson(rc);
hsp.desc();
hc = new highPerson(hsp);
hc.desc();
}
}
二、装饰模式(Decorator)
装饰模式是动态的给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更加的灵活。
//Component类
abstract class Component{
public abstract void Operation();
}
//ConcreteComponent类
class ConcreteComponent extends Component{
@Override
public void Operation() {
// TODO Auto-generated method stub
System.out.println("具体对象的操作");
}
}
//Decorator类
abstract class Decorator extends Component{
protected Component component;
public void SetComponent(Component component) {
this.component=component;
}
public void Operation() {
if(component!=null) {
component.Operation();
}
}
}
//ConcreteDecoratorA类
class ConcreteDecoratorA extends Decorator{
private String addedState;
public void Operation() {
super.Operation();
addedState="New State";
System.out.println("具体装饰对象A的操作");
}
}
class ConcreteDecoratorB extends Decorator{
public void Operation() {
super.Operation();
AddedBehavior();
System.out.println("具体装饰对象B的操作");
}
private void AddedBehavior() {
// TODO Auto-generated method stub
}
}
public class Main {
public static void main(String[] args) {
ConcreteComponent c=new ConcreteComponent();
ConcreteDecoratorA d1=new ConcreteDecoratorA();
ConcreteDecoratorB d2=new ConcreteDecoratorB();
d1.SetComponent(c);
d2.SetComponent(d1);
d2.Operation();
}
}
三、一个可以给人搭配衣服的系统
Person类
class Person {
private String name;
public Person(String name) {
super();
this.name = name;
}
public void WearTShirts() {
System.out.print("大T恤"+" ");
}
public void WearBigTrouser() {
System.out.print("垮裤"+" ");
}
public void WearSneakers() {
System.out.print("破球鞋"+" ");
}
public void WearSuit() {
System.out.print("西装"+" ");
}
public void WearTie() {
System.out.print("领带"+" ");
}
public void WearLeatherShoes() {
System.out.print("皮鞋"+" ");
}
public void Show() {
System.out.println("装扮的" + name);
}
}
public class Main {
public static void main(String[] args) {
Person xc = new Person("小菜");
System.out.println("第一种装扮:");
xc.WearTShirts();
xc.WearBigTrouser();
xc.WearSneakers();
xc.Show();
System.out.println("第二种装扮:");
xc.WearSuit();
xc.WearTie();
xc.WearLeatherShoes();
xc.Show();
}
}
改进:
class Person {
private String name;
public Person(String name) {
super();
this.name = name;
}
public void Show() {
System.out.println("装扮的" + name);
}
}
//服饰类
abstract class Finery {
public abstract void Show();
}
//大T恤
class TShirts extends Finery {
@Override
public void Show() {
// TODO Auto-generated method stub
System.out.print("大T恤" + " ");
}
}
class BigTrouser extends Finery {
@Override
public void Show() {
// TODO Auto-generated method stub
System.out.print("垮裤" + " ");
}
}
class WearSneakers extends Finery {
@Override
public void Show() {
// TODO Auto-generated method stub
System.out.print("破球鞋" + " ");
}
}
class WearSuit extends Finery {
@Override
public void Show() {
// TODO Auto-generated method stub
System.out.print("西装" + " ");
}
}
class WearTie extends Finery {
@Override
public void Show() {
// TODO Auto-generated method stub
System.out.print("领带" + " ");
}
}
class WearLeatherShoes extends Finery {
@Override
public void Show() {
// TODO Auto-generated method stub
System.out.print("皮鞋" + " ");
}
}
public class Main {
public static void main(String[] args) {
Person xc = new Person("小菜");
System.out.println("第一种装扮:");
Finery dtx = new TShirts();
Finery kk = new BigTrouser();
Finery pqx = new WearSneakers();
dtx.Show();
kk.Show();
pqx.Show();
xc.Show();
System.out.println("第二种装扮:");
Finery xz = new WearSuit();
Finery ld = new WearTie();
Finery px = new WearLeatherShoes();
xz.Show();
ld.Show();
px.Show();
xc.Show();
}
}
用装饰模式改进:
class Person{
public Person() {
}
private String name;
public Person(String name) {
super();
this.name = name;
}
public void Show() {
System.out.println("装扮的" + name);
}
}
class Finery extends Person{
protected Person component;
public void Decorate(Person component) {
this.component=component;
}
public void Show() {
if(component!=null) {
component.Show();
}
}
}
class TShirts extends Finery {
@Override
public void Show() {
// TODO Auto-generated method stub
System.out.print("大T恤" + " ");
super.Show();
}
}
class BigTrouser extends Finery {
@Override
public void Show() {
// TODO Auto-generated method stub
System.out.print("垮裤" + " ");
super.Show();
}
}
class WearSneakers extends Finery {
@Override
public void Show() {
// TODO Auto-generated method stub
System.out.print("破球鞋" + " ");
super.Show();
}
}
class WearSuit extends Finery {
@Override
public void Show() {
// TODO Auto-generated method stub
System.out.print("西装" + " ");
super.Show();
}
}
class WearTie extends Finery {
@Override
public void Show() {
// TODO Auto-generated method stub
System.out.print("领带" + " ");
super.Show();
}
}
class WearLeatherShoes extends Finery {
@Override
public void Show() {
// TODO Auto-generated method stub
System.out.print("皮鞋" + " ");
super.Show();
}
}
public class Main {
public static void main(String[] args) {
Person xc=new Person("小菜");
System.out.println("第一种装扮:");
WearSneakers pqx=new WearSneakers();
BigTrouser kk=new BigTrouser();
TShirts dtx=new TShirts();
pqx.Decorate(xc);
kk.Decorate(pqx);
dtx.Decorate(kk);
dtx.Show();
System.out.println("第二种装扮:");
WearLeatherShoes px=new WearLeatherShoes();
WearTie ld=new WearTie();
WearSuit xz=new WearSuit();
px.Decorate(xc);
ld.Decorate(px);
xz.Decorate(ld);
xz.Show();
}
}
运行结果:
第一种装扮:
大T恤 垮裤 破球鞋 装扮的小菜
第二种装扮:
西装 领带 皮鞋 装扮的小菜
注:以上部分摘取自朱红梅老师2020年5月的课件。