2017-08-24 54 views
0

我想實現的裝飾圖案,在這裏我specfication:裝飾模式,編譯器不允許類型傳播

public abstract class Menu{ //propagate the type 
} 

而且

public class Sandwich extends Menu{ // Concrete class which is a Menu 

} 

而且

public abstract class Extra extends Menu{ 

    Menu menu; 

    public Extra(Menu menu){ // the constructor takes a Menu type 
     this.menu=menu; 
    } 
} 

的問題是爲什麼編譯器不允許這樣做:

public class Test { 
    Menu sand1 = new Sandwich(); 
    sand1 = new Extra(sand1); //It's fine for the compiler 

    Sandwich sand = new Sandwich(); 
    sand = new Extra (sand);// Compiler cries here !! 
} 

三明治IS-A Menu通過inheritence,Extra的構造函數需要Menu所以爲什麼編譯器不開心?

編譯器消息:Type mismatch: cannot convert from Extra to Sandwich

感謝您的澄清。

+3

'Extra'不是'Sandwich' ...編譯器說什麼_exactly_? –

+0

@SotiriosDelimanolis我添加了編譯信息 – akuma8

+2

好吧,你去了,我不明白你的困惑。問題在錯誤消息中詳細說明。 –

回答

0

想象一下這樣的情況下(即夾心裏面有一些方法):

public class Sandwich extends Menu{ 
    public void addSalad(){ 
    //... 
    } 
} 

所以現在youre做這樣的:

Sandwich sand = new Sandwich(); 
sand.addSalad();//works 

sand = new Extra (sand);//imagine this doesnt throw errs 
sand.addSalad();//will fail as sands not a sandwich anymore 

上的代碼將失敗。因此,你不允許將非三明治分配給沙子。

+0

你說服了我,但在我的情況下,這兩個類共享一個同樣的方法,我希望在'new Extra(sand)'之後得到結果。 – akuma8

+0

@ akuma8那麼應該是一個Menu方法。沙子應該是一個菜單,而不是三明治 –

1

問題是未將sand傳遞給Extra構造函數,問題是試圖將new Extra(sand)分配給Sandwich類型。

+0

我明白了,但爲什麼?由於'三明治是一個菜單'和'額外'也是。 – akuma8

+0

僅僅因爲兩個類從同一個超類繼承並不意味着它們是相同的。試想一下,'Dog'是一個'Animal',一個'Cat'是一個'Animal',但是給'Cat'類型的一個實例指定'Dog'變量將毫無意義 –

+1

你是完全正確的! – akuma8