【问题标题】:Force toString() implementation in subclasses强制在子类中实现 toString()
【发布时间】:2012-02-01 22:02:46
【问题描述】:

我有一个抽象父类,我希望它强制所有子类实现 toString() 方法。

但是说:

public abstract String toString();

导致编译错误:

Repetitive method name/signature for method 'java.lang.String toString()' in class ...

我相信这可能是由于 groovy 已经定义了 toString 造成的。

谢谢

【问题讨论】:

  • .NET 有一个 new 关键字来覆盖基本实现。我很好奇Java是否有类似的东西。

标签: java grails groovy


【解决方案1】:

这对我有用。这是新的还是其他人只是错过了它?

public abstract class Filterable
{
  @Override
  public abstract String toString();
}

public class ABC extends Filterable
{
  // Won't compile without toString();
}

【讨论】:

  • 我也用这个模式没问题
  • 只有当父类被设为abstract时它才会起作用,但这可能就是这里想要的。
【解决方案2】:

toString()java.lang.Object 类的一部分,该类已经有一个默认实现。所以你基本上不能强迫子类来实现它。如果您想强制这种行为(不知道为什么),那么您可以执行以下操作

public class abstract SuperClass {
  public abstract String myToString();

  public String toString() {
    return myToString();
  }
}

【讨论】:

  • Pangea 的答案会奏效,但如果您走这么远并迫使您的客户接受您的方式或高速公路,您可能应该在抽象类中将 toString() 设为 final。不过,在我看来,您可能在这里对您的客户进行了过多的控制。为什么要强制 toString 的实现超出 java.lang.Object 给你的范围?
  • 刚刚提到:toString 必须返回一个字符串值。所以它应该return myToString(); 而不是仅仅调用它
【解决方案3】:

简答:不可能。 长答案:您可以尝试通过执行以下操作来解决此问题,在父类中实现:

public final String toString() {
    getString();
}

public abstract String getString();

这导致子类需要实现“getString()”方法。但是,如果子类实现“getString()”方法,则子(孙)类的子类不能保证强制实现该方法。示例:

A is the parent class, with the getString() method.
B extends A, and implements the getString() method.
C extends B, doesn't have to implement the getString() method.

希望有帮助:)

【讨论】:

  • “决赛”加 1 - 这是一个非常有价值的补充。
【解决方案4】:

您不能强制它们重写 toString(),但您可以在抽象父类中让 toString() 调用另一个 m 抽象方法 youGottaOverideToString(),子类必须实现。

【讨论】:

    【解决方案5】:

    您可以编写一个单元测试来定位所有扩展您的抽象类的类,并验证它们是否声明了 toString()。要扫描你可以使用Reflections library:

      @Test
      public void validateToString() {
        final Reflections dtoClassesReflections = new Reflections(new ConfigurationBuilder()
          .setUrls(ClasspathHelper.forPackage("my.base.package"))
          .filterInputsBy(new FilterBuilder()
            .include(".*Dto.*") // optionally filter only some particular classes
            .exclude(".*Test.*")) // exclude classes from tests which will be scanned as well
          .setScanners(new SubTypesScanner(false)));
    
        final Set<Class<?>> allDtoClasses = dtoClassesReflections.getSubTypesOf(YourAbstractClass.class); // you set your class here (!!). You can set Object.class to get all classes
    
        allDtoClasses.forEach(dtoClass -> {
          logger.info("toString() tester testing: " + dtoClass);
    
          try {
            dtoClass.getDeclaredMethod("toString");
          } catch (NoSuchMethodException e) {
            fail(dtoClass + " does not override toString() method");
          }
        });
    
    
      }
    

    【讨论】:

      猜你喜欢
      • 2019-07-09
      • 1970-01-01
      • 2021-04-02
      • 2020-04-04
      • 2010-12-18
      • 2015-10-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多