首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >println(String)接口

println(String)接口
EN

Stack Overflow用户
提问于 2019-07-02 15:20:14
回答 3查看 406关注 0票数 4

我想编写Java代码(比方说,一种方法)来打印一些行。

打印的对象应由调用方提供。我希望我的代码不关心该对象到底是什么,只需调用对象的println()println(String)方法即可。无论该对象是java.io.PrintStream (例如System.out)还是java.io.PrintWriter (例如,由调用方用new PrintWriter(System.out)new PrintWriter(new ByteArrayOutputStream())构造),它都应该工作。

如果“可打印”对象的潜在类共享一些强制使用println()println(String)方法的接口,这将非常容易。不管他们怎么想。

那么,通过编写两倍于本质上相同的实现,只使用交换的类型(就像在重载函数时那样),在不违反干原理的情况下,我应该在签名中添加什么呢?

代码语言:javascript
复制
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());

或者,PrintStreamPrintWriter不共享这样的接口是否应该被视为在提供打印行的方法方面它们是不可互换的?(而不是在指定这些类时出现某种历史疏忽。)

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-07-02 18:11:08

您可能对一种不同的、更实用的方法感兴趣。不必担心每种类型提供了什么以及如何在它们之间找到通用的interface,您可以通过使用ConsumerRunnable作为println方法的表示来实现相同的目标。

代码语言:javascript
复制
// 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();
  }
}

你可以这样用它:

代码语言:javascript
复制
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);
票数 1
EN

Stack Overflow用户

发布于 2019-07-02 15:27:34

最简单的方法就是用接受PrintWriter的版本和接受PrintStream的版本重载该方法。

代码语言:javascript
复制
public void sayHello(PrintStream outThingy) {
    outThingy.println("Hello World");
    outThingy.println();
};
public void sayHello(PrintWriter outThingy) {
    outThingy.println("Hello World");
    outThingy.println();
};
票数 2
EN

Stack Overflow用户

发布于 2019-07-02 15:53:31

这里有一种方法,您可以这样做,并至少保持客户端的outThingy。但是,你会为有效地上几节湿课而付出代价的。尽管如此,代码的数量仍然很小。

代码语言:javascript
复制
// 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();
  }
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56855585

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档