2017-08-24 48 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