interface Printer {
void print(String text);
}
class ConsolePrinter implements Printer {
@Override
public void print(String text) {
System.out.println("Console Printer: " + text);
}
}
class FilePrinter implements Printer {
@Override
public void print(String text) {
// Simulating file printing
System.out.println("Printing to file: " + text);
}
}
class Document {
private final String content;
private final Printer printer;
public Document(String content, Printer printer) {
this.content = content;
this.printer = printer;
}
public void printDocument() {
printer.print(content);
}
}
public class Main {
public static void main(String[] args) {
Printer consolePrinter = new ConsolePrinter();
Document doc1 = new Document("This is a document.", consolePrinter);
doc1.printDocument();
Printer filePrinter = new FilePrinter();
Document doc2 = new Document("This is another document.", filePrinter);
doc2.printDocument();
}
}
在这个示例中,
Printer
是一个接口,有两个实现类ConsolePrinter
和FilePrinter
。Document
类接受一个Printer
对象作为构造函数参数,并且调用Printer
接口的在
Main
类中,我们创建了两个不同的打印机实例(ConsolePrinter
和FilePrinter
),并将它们分别传递给两个不同的文档实例。这展示了在不同场景下如何使用不同的打印机实现而不需要修改Document
类的代码。
Printer consolePrinter = new ConsolePrinter(); 和Printer filePrinter = new FilePrinter();都使用Printer来指向子类的对象 ,这是一个向上转型的例子。在Java中,向上转型指的是将一个子类类型的实例赋值给一个父类类型的引用变量。在这个例子中,
ConsolePrinter
是Printer
的实现类,而Printer
是一个接口。通过将ConsolePrinter
类型的对象赋值给Printer
类型的引用变量consolePrinter
,就实现了向上转型。 向上转型允许你以统一的方式处理不同类型的对象,这对于实现多态性和灵活性非常有用。通过父类引用可以调用子类中从父类继承的方法,但无法直接调用子类特有的方法。若需要调用子类特有的方法,可以通过向下转型将父类引用转换回子类类型。 (用接口这个例子不太合适,用子类继承父类这个例子合适)类与接口之间的关系更类似于合同关系。当一个类实现了一个接口时,它必须实现接口中定义的所有方法。接口定义了一组行为的契约,而类实现这个接口意味着它同意遵守这个契约并提供相应的功能。这使得我们能够利用多态性原则,在不同的类实例之间使用统一的方式进行处理。