我想编写Java代码(比方说,一种方法)来打印一些行。
打印的对象应由调用方提供。我希望我的代码不关心该对象到底是什么,只需调用对象的println()或println(String)方法即可。无论该对象是java.io.PrintStream (例如System.out)还是java.io.PrintWriter (例如,由调用方用new PrintWriter(System.out)或new PrintWriter(new ByteArrayOutputStream())构造),它都应该工作。
如果“可打印”对象的潜在类共享一些强制使用println()和println(String)方法的接口,这将非常容易。不管他们怎么想。
那么,通过编写两倍于本质上相同的实现,只使用交换的类型(就像在重载函数时那样),在不违反干原理的情况下,我应该在签名中添加什么呢?
public void sayHello( ??? outThingy) {
outThingy.println("Hello World");
outThingy.println();
// This just a minimal example.
// The real implementation might be more involved
// and non-trivial, so that avoiding duplication
// becomes a real concern.
};
// sayHello should be usable like this:
sayHello(System.out);
// but also like this:
baos = new ByteArrayOutputStream();
pw = new PrintWriter(baos)
sayHello(pw);
pw.flush();
System.out.println(baos.toString());或者,PrintStream和PrintWriter不共享这样的接口是否应该被视为在提供打印行的方法方面它们是不可互换的?(而不是在指定这些类时出现某种历史疏忽。)
发布于 2019-07-02 18:11:08
您可能对一种不同的、更实用的方法感兴趣。不必担心每种类型提供了什么以及如何在它们之间找到通用的interface,您可以通过使用Consumer和Runnable作为println方法的表示来实现相同的目标。
// This is the common class
class FuncPrinter {
private Consumer<String> consumer;
private Runnable runnable;
public FuncPrinter(PrintWriter writer) {
consumer = writer::println;
runnable = writer::println;
}
public FuncPrinter(PrintStream stream) {
consumer = stream::println;
runnable = stream::println;
}
public void println(String line) {
consumer.accept(line);
}
public void println() {
runnable.run();
}
}
class Talker {
void sayHello(FuncPrinter fp) {
fp.println("Hello World");
fp.println();
}
}你可以这样用它:
Talker t = new Talker();
FuncPrinter fp = new FuncPrinter(System.out);
t.sayHello(fp);
ByteArrayOutputStream ostream = new ByteArrayOutputStream();
PrintWriter pw = new PrintWriter(ostream);
fp = new FuncPrinter(pw);
t.sayHello(fp);
fp = new FuncPrinter(
line -> System.out.println(line),
() -> System.out.println(42));
t.sayHello(fp);发布于 2019-07-02 15:27:34
最简单的方法就是用接受PrintWriter的版本和接受PrintStream的版本重载该方法。
public void sayHello(PrintStream outThingy) {
outThingy.println("Hello World");
outThingy.println();
};
public void sayHello(PrintWriter outThingy) {
outThingy.println("Hello World");
outThingy.println();
};发布于 2019-07-02 15:53:31
这里有一种方法,您可以这样做,并至少保持客户端的outThingy。但是,你会为有效地上几节湿课而付出代价的。尽管如此,代码的数量仍然很小。
// Printer allows for a common interface
interface Printer {
void println(String line);
void println();
}
// Used with PrintStream
class StreamPrinter implements Printer {
private PrintStream ps;
public StreamPrinter(PrintStream ps) {
this.ps = ps;
}
@Override
public void println(String line) {
ps.println(line);
}
@Override
public void println() {
ps.println();
}
}
// Used with PrintWriter
class TypeWriter implements Printer {
private PrintWriter pw;
public TypeWriter(PrintWriter pw) {
this.pw = pw;
}
@Override
public void println(String line) {
pw.println(line);
}
@Override
public void println() {
pw.println();
}
}
class Talker {
// This class doesn't care!
void sayHello(Printer printer) {
printer.println("Hello world");
printer.println();
}
}https://stackoverflow.com/questions/56855585
复制相似问题