2017-04-20 64 views
1

我尝试编写一个装饰器模式的简单示例。省略在Java儿童中使用构造函数

我有一个Printable接口,一个具体的类印刷和抽象类的装饰:

// for all objects that can be printed 
interface Printable { 
    public void print(); 
} 


// classes for decorating 
class DisplayPrinter implements Printable { 
    public void print() { 
    System.out.println("Print to the display"); 
    } 
} 

class PaperPrinter implements Printable { 
    public void print() { 
    System.out.println("Print to the paper"); 
    } 
} 


// printer decorator for all possible decorators 
abstract class PrinterDecorator implements Printable { 
    private Printable printer; 

    public PrinterDecorator(Printable p) { 
    printer = p; 
    } 

    public void print() { 
    if (printer != null) 
     printer.print(); 
    } 
} 

请注意,我用抽象PrinterDecorator构造。 因此,我写了两个具体的装饰器来打印要打印的基本内容的页眉和页脚。这里页脚装饰是:

class FooterPrinterDecorator extends PrinterDecorator { 
    /*public FooterPrinterDecorator(Printable p) { 
    super(p); 
    }*/ 

    public void print() { 
    super.print(); 
    System.out.println("Footer"); 
    } 
} 

在这里,我想PrinterDecorator孩子们不要重新声明父类的构造。但我得到了一个错误,如果我与上述评论运行:

error: constructor FooterPrinterDecorator in class FooterPrinterDecorator cannot be applied to given types; 
Printable one = new FooterPrinterDecorator(new DisplayPrinter()); 
       ^
required: no arguments 
found: DisplayPrinter 
reason: actual and formal argument lists differ in length 

而且我试图手动写在父母装饰默认构造函数。在这种情况下,编译器给了我同样的错误,但在其他方面(指望它不带参数的构造函数,即使我给Printable作为参数的构造函数的调用:

Printable one = new FooterPrinterDecorator(new DisplayPrinter()); 

所以,我可以省略在其子女的父或母,构造的重复?

+0

@ brso05,是的,我试过了。但它不能解决问题。我更新了错误消息和对构造函数的调用。 – Bogdan

回答

2

你不能;如果你的父类没有默认的构造函数,那么每个孩子必须实现一个调用父类的构造函数。这是为了保持封装,并且因为构造函数不像方法那样继承。

你能做什么,不过,是有一种方法,而不是在PrinterDecorator构造:

abstract class PrinterDecorator implements Printable { 
    private Printable printer; 

    public void setDecorator(Printable p) { 
    printer = p; 
    } 

    public void print() { 
    if (printer != null) 
     printer.print(); 
    } 
} 

现在你的孩子并不需要乱用这种方法,他们将继承原样。

+0

这是一个正确的答案,并且这种技术可以节省编写样板构造函数的工作。虽然它引入了时间耦合:'setDecorator'必须在正确的时间恰好调用一次。如果有人忘记叫它,它会导致错误。如果有人更多次地自称,这也会导致丑陋的情况。所以我的建议是:考虑使用这些样板构造函数(即使您的IDE生成它),并使打印机领域'最终'。 – pcjuzer

1

答案是否定的。构造函数不是在java中继承的。你看这个错误,因为类FooterPrinterDecorator只默认的构造函数,它没有参数(required: no arguments)。

Java Constructor Inheritance