简体   繁体   中英

Force toString() implementation in subclasses

I have an abstract parent class, and I would like it to all subclasses to implement toString() method. 所有子类实现toString()方法。

However putting:

public abstract String toString();

is causing a compilation error:

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

I believe this might be caused by groovy already having toString defined.

Thanks

This works for me. Is this new or did others just miss it?

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

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

The toString() is part of the java.lang.Object class which already has a default implementation for it. So you essentially can't force the sub-classes to implement it. If you want to force this kind of behavior (not sure why) then you can do something like below

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

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

Short answer: Isn't possible. Long answer: You could try get around this by doing the following instead, implement in the parent class:

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

public abstract String getString();

This causes the child class to need to implement the "getString()" method. However, the child of the child (grandchild) class has no guarantee of being forced to implement that method if the child class implements the "getString()" method. Example:

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.

Hope that helps :)

You can write a unit test which will locate all classes extending your abstract class and verify that they declare toString(). To scan you can use 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");
      }
    });


  }

你不能强制它们覆盖toString(),但你可以在抽象父类中使用toString()调用另一个抽象方法youGottaOverideToString(),这些子类必须实现。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM