#Java笔记 #程序实现:工厂设计模式的学习小结

program 3 工厂设计模式、类的继承

概述

《第一行代码 JAVA》的 4.7.3 接口的应用——工厂设计模式(Factory) 提到:“ 在客户端的操作上取消关键字new的使用,而使用Factory.getInstance()方法取得接口实例化对象,这时客户端不再需要关注具体子类,也不需要关注Factory类是怎么处理的,只需关注如何取得接口对象并且操作。 ”

可见,“客户端取消关键字new的操作”、“隐藏程序具体实现”、“客户端只看到接口” 是工厂设计模式的要点。

构造这样一个程序:客户端通过接口可以查询某样东西(Sth)能怎好(能吃吗?怎么吃?好吃吗?)。

仿造书中的图例,我也绘制了对应的逻辑框图如下。为了同时对比类的继承的特点,Sth接口 implements 在动物类 和 extends在植物接口上;动物类被Pig类和Bat类所继承;植物接口则被Grass类和Apple类应用。动物类这一支线体现了类的继承;植物接口这边则体现接口的继承和拓展。

经过调试,得到的一些小结有:

  • 工厂设计模式中,能够调用的方法是所使用的接口中定义的类。比如说,① 如果用Sth接口取得实例化对象,那么就可以调用getInfo()、howToEat()等方法,而不能调用植物接口中的 color() 方法,尽管草类和苹果类继承了植物接口。② 如果用Plant接口取得实例化对象,就能够调用 color() 方法了。
  • 接口的扩展,使用extends,继承上一个接口的所有抽象方法和全局变量。比如 interface Plant extends Sth{ }
  • 接口的应用,使用implements,继承接口的抽象方法。比如 public class Animal implements Sth { }
  • 类的继承,使用extends,继承上一个类的所有方法和变量。比如 public class Bat extends Animal { }
  • 接口中的抽象方法,在应用的类中一定要覆写。
  • 接口虽然更符合工厂设计模式的要求,但是接口中只能有抽象方法,没办法设置方法体,因此每个应用接口的类都要覆写抽象方法。而且,工厂设计模式下,每一个新的类都要在工厂类中新增方法。因此一定程度上还是不方便的。
  • 但如果使用类的继承,虽然在客户端中要考虑new出来的类别,但是新增类会很简单。只要父类方法预设合适,子类中只需传递变量即可。
  • 工厂类中的方法应为 static。这样不用new一个新对象即可以调用方法。

写的程序如下:

1. Sth 接口

interface Sth {
	public abstract void canBeEaten();
	public abstract void howToEat();
	public abstract void delicious();
	public abstract void getInfor();
}

2. Plant 接口

interface Plant extends Sth {
	public abstract void color();
	public abstract void smell();
}

2.1 Apple 类

public class Apple implements Plant {
	public void canBeEaten() {System.out.print("苹果能吃。");}
	public void howToEat() {System.out.print("苹果削皮吃。");}
	public void delicious() {System.out.print("苹果可好吃。");}
	public void color() {System.out.print("苹果有红有绿。");}
	public void smell() {System.out.print("苹果很好闻。");}
	public void getInfor() {
		System.out.print("植物名称:苹果");
		System.out.print("颜色:有红有绿");
		System.out.print("气味:很好闻");
		System.out.print("能怎好?:能吃、削皮吃、可好吃");
	}
}

2.2 Grass 类

public class Grass implements Plant {
	public void canBeEaten() {System.out.println("草不能吃。");}
	public void howToEat() {System.out.println("草没法吃。");}
	public void delicious() {System.out.println("草不好吃。");}
	public void color() {System.out.println("草一般是绿的。");}
	public void smell() {System.out.println("草闻起来很清新。");}
	public void getInfor() {
		System.out.println("植物名称:草");
		System.out.println("颜色:一般是绿的");
		System.out.println("气味:闻起来很清新");
		System.out.println("能怎好?:不能吃、没法吃、不好吃");
	}
}

3. Animal 类

public class Animal implements Sth {
	private String name;
	private String moveStyle;
	private String foodStyle;
	private boolean beEaten;
	private String howEat;
	private boolean tasteGood;
	
	public Animal(){
		
	}
	
	public Animal(String name,String moveStyle,String foodStyle){
		this.name = name;
		this.moveStyle = moveStyle;
		this.foodStyle = foodStyle;
	}
	
	public String getName() {return this.name;}
	public void setName(String name) {this.name = name;}
	
	public String getMoveStyle() {return this.moveStyle;}
	public void setMoveStyle(String moveStyle) {this.moveStyle = moveStyle;}
	
	public String getFoodStyle() {return this.foodStyle;}
	public void setFoodStyle(String foodStyle) {this.foodStyle = foodStyle;}
	
	public boolean getBeEaten() {return this.beEaten;}
	public void setBeEaten(boolean beEaten) {this.beEaten = beEaten;}
	
	public String getHowEat() {return this.howEat;}
	public void setHowEat(String howEat) {this.howEat = howEat;}
	
	public boolean getTasteGood() {return this.tasteGood;}
	public void setTasteGood(boolean tasteGood) {this.tasteGood = tasteGood;}
	
	public void move() {
		System.out.println(this.name + "会" + this.moveStyle + "。");
	}
	
	public void food() {
		System.out.println(this.name + "吃" + this.foodStyle + "。");
	}
	
	public void canBeEaten() {
		if(this.beEaten){
			System.out.println(this.name + "可以吃。");
		}
		else System.out.println(this.name + "不能吃。");
	}

	public void howToEat() {
		if(this.beEaten){
			System.out.println(this.name + howEat);
		}
		else System.out.println(this.name + "没法料理。");
	}

	public void delicious() {
		if(this.beEaten && this.tasteGood){
			System.out.println(this.name + "好吃!");
		}
		else System.out.println(this.name + "可难吃。");
	}

	public void getInfor() {
		System.out.println("动物名称: " + this.name);
		
		System.out.println("运动方式: " + this.moveStyle);
		
		System.out.println("食物:" + this.foodStyle);
		
		System.out.print("能怎好?:");
		
		if(this.beEaten){
			System.out.print("能吃、" + howEat + "、");
		}
		else System.out.print("不能吃、" + "没法料理、");
		
		if(this.beEaten && this.tasteGood){
			System.out.println("好吃");
		}
		else System.out.println("不好吃");
	}
}

3.1 Bat 类

public class Bat extends Animal {
	String name = "蝙蝠";
	String moveStyle = "飞";
	String foodStyle = "果子";
	boolean beEaten = false;
	String howEat = "";
	boolean tasteGood = false;
	
	public Bat(){
		super();
		super.setName(this.name);
		super.setMoveStyle(this.moveStyle);
		super.setFoodStyle(this.foodStyle);
		super.setBeEaten(this.beEaten);
		super.setHowEat(this.howEat);
		super.setTasteGood(this.tasteGood);
	}
}

3.2 Pig 类

public class Pig extends Animal {
	private String name = "猪";
	private String moveStyle = "跑";
	private String foodStyle = "杂食";
	private boolean beEaten = true;
	private String howEat = "煮熟了吃";
	private boolean tasteGood = true;
	
	public Pig(){
		super();
		super.setName(this.name);
		super.setMoveStyle(this.moveStyle);
		super.setFoodStyle(this.foodStyle);
		super.setBeEaten(this.beEaten);
		super.setHowEat(this.howEat);
		super.setTasteGood(this.tasteGood);
	}
}

4. 工厂类

public class Factory {
//	static 声明很重要!
	public static Sth getInstance(String sthName){
		if("bat".equals(sthName)){
			return new Bat();
		}
		else if("pig".equals(sthName)){
			return new Pig();
		}
		else if("apple".equals(sthName)){
			return new Apple();
		}
		else if("grass".equals(sthName)){
			return new Grass();
		}
		else return null;
	}
	
	public static Plant getInstance2(String sthName){
		if("apple".equals(sthName)){
			return new Apple();
		}
		else if("grass".equals(sthName)){
			return new Grass();
		}
		else return null;
	}
}

5. 测试

public class TestFactory {
	public static void main(String[] args){
		// 工厂设计模式——通过接口实例化对象
		// 调用Sth接口中的抽象方法
		Sth a = Factory.getInstance("pig");
		a.delicious();
		a.getInfor();
		
		// 调用Plant接口中的抽象方法
		Plant b = Factory.getInstance2("grass");
		b.color(); 
		b.getInfor();
		
		// 通过子类实例化对象
		Animal c = new Bat();
		c.move(); // 调用Bat类中的抽象方法
		c.food();
	}
}

6. 结果

猪好吃!

动物名称: 猪
运动方式: 跑
食物:杂食
能怎好?:能吃、煮熟了吃、好吃

草一般是绿的。

植物名称:草
颜色:一般是绿的
气味:闻起来很清新
能怎好?:不能吃、没法吃、不好吃

蝙蝠会飞。
蝙蝠吃果子。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值