package day08.chouXiangLeiHeJieKou;
public class TestBirds {
/**组合 :
* 本来 设计的 Bird 类和 其子类中的 Firebird 还有 Redbird ,FoolBird,happyBird并没有shout方法
* 要求:现需要添加使RedBird能实现haha叫 其他三中鸟实现GaGa叫
* 1.刚开始是想着直接在父类中定义抽象方法去让子类去复写 这样的话 如果有很多种鸟 那每种鸟(即鸟的子类)都需要去
* 复写父类的方法 会造成代码冗余 。
* 2.那么想象 要不直接定义一个接口 让子类去实现这个接口 里面的叫方法 本质和第一种想法是一样的 还有个确定就是在
* 测试类中, 不能以多态的形式 去建立一个鸟类型的对象去访问子类型中的shout方法 因为父类型中 没有定义该方法
* 3.组合模式:
* 重点:
* 在 集合中 我们经常看到 诸如此类的构造方法
* ArrayList(Collection<? extends E> c)
构造一个包含指定 collection 的元素的列表,这些元素是按照该 collection 的迭代器返回它们的顺序排列的。
上面的代码是通过向Arraylist中传入实现了Collection接口的实现类 来构造一个新的ArrayList的类
那么 我们在这里能不能也这么做呢?
在添加新方法遇到困难时 我们已经想到的接口 那么 可不可以直接定义一些类(后期在这个例子中个人感觉
可以直接用匿名内部类)来实现一个Shouta 接口的呢? 所以我们定义了两个类HaHaShout 和 GaGaShout
定义这两个类是为了 构造一个新的FireBird 还有RedBird等, 那么这个时候我们是不是应该去重写我们的鸟子类中的
构造函数了呢? 故我们就真的这么做了 在FireBird类中定义了一个名为
fireBird(Shouta a)
{
super(a);
this.name= "fire Bird";
}
此时 会提示编译失败 因为父类中是没有定义这种构造函数的
所以我们去父类中也定义了这么一个构造函数
public Bird(Shouta a)
{
this.shout_a = a ;-->提示编译失败
}
因为没有shout_a这种属性 所以定义一个shout_a这个成员变量
在 我们的测试类中 Bird a = new FireBird(new HaHaShout(){public void shout(){System.out.println("HAHAHA")}});
中 需要调用 a.shout();这个函数 所以 还应该有一个在 父类中的一个 通过属性shout_a 来实现
public void shout()
{
shout_a.shout();
}
这样就圆满了、、、、、、、
总结 :
1.在实现添加新功能的时候 应该新建一个新功能接口
2.再建立新功能的相关对象
3.这就要求源对象重新新建一个 构造函数 并且这种构造函数的形参是 新功能的接口
4.修改父类中的成员变量 添加新功能的接口 定义调用新功能的函数 通过成员属性去调用接口中的函数
* @param args
*/
public static void main(String[] args) {
// HaHaShout h = new HaHaShout();
// GaGaShout g = new GaGaShout();
Bird a = new fireBird(new HaHaShout());
Bird b = new RedBird(new GaGaShout());
// a.trueShout();
b.attack();
b.fly();
b.shout();
a.attack();
a.fly();
a.shout();
}
}
package day08.chouXiangLeiHeJieKou;
public abstract class Bird //implements Shouta
{
protected String name;
protected Shouta shout_a;
public Bird(Shouta a)
{
this.shout_a = a ;
}
public String getName() {
return name;
}
public void shout()
{
shout_a.shout();
}
public void setName(String name) {
this.name = name;
}
public void fly()
{
System.out.println(name + " fly ");
}
// public void shout()
// {
// System.out.println(name + " oooooooo");
// }
public abstract void attack();
}
package day08.chouXiangLeiHeJieKou;
public class RedBird extends Bird {
RedBird(Shouta a)
{
super(a);
this.name = "red bird";
}
public void attack()
{
System.out.println(this.getName()+"attack foolly");
}
}
package day08.chouXiangLeiHeJieKou;
public class fireBird extends Bird {
fireBird(Shouta a)
{
super(a);
this.name= "fire Bird";
}
public void attack()
{
System.out.println(this.getName()+"fire the hole");
}
}
package day08.chouXiangLeiHeJieKou;
public interface Shouta {
public abstract void shout();
}
package day08.chouXiangLeiHeJieKou;
public class GaGaShout implements Shouta {
public void shout()
{
System.out.println("gagagaga");
}
}
package day08.chouXiangLeiHeJieKou;
public class HaHaShout implements Shouta {
public void shout()
{
System.out.println("hahahah");
}
}