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");
}
}