1

I have an use-case where I need the objects to provide sensible String output in toString() method (Not the default Object.toString() output). I was thinking of enforcing toString() method implementation through an Interface contract.

Something like,

interface TestInterface {
    public String toString();
}

class TestClass implements TestInterface {
    // But there's no need to implement toString() since it's already present as part of Object class.
}

But as in the comment, it doesn't enforce implementing the toString() method.

I have 2 workarounds,

Make the interface an abstract class,

abstract class TestInterface {
    public abstract String toString();
}

class TestClass extends TestInterface {
    // You will be enforced to implement the toString() here.
}

But this seems to be an overkill just to provide a contract. This will also mean the class cannot extend from any other class.


Change the method name to something else.

interface TestInterface {
    public String toSensibleString();
}

class TestClass implements TestInterface {
    // Should implement it here.
}

But this would mean, those classes which already override the toString() method needs to have an unnecessary method. Also it would mean only those classes which know about the interface will get the proper String.


So, is there a way to provide a contract to (re)implement an existing method?

Note: I found this similar question but that's related to Groovy I guess (and his problem is not a problem in Java at all).

Community
  • 1
  • 1
Codebender
  • 14,221
  • 7
  • 48
  • 85
  • If you use java 8, you might use a interface, with default methods implementations, which throws an exception, but this type of enforcement is at run-time, instead of compile-time – Radu Toader Sep 07 '15 at 12:48
  • @RaduToader: [You cannot implement a `default String toString()` method in interfaces.](http://stackoverflow.com/q/24016962/521799) – Lukas Eder Sep 07 '15 at 12:52
  • duplicate to http://stackoverflow.com/questions/1718112/tostring-equals-and-hashcode-in-an-interface – PKuhn Sep 07 '15 at 12:54
  • @RaduToader Unfortunately you can't. `It is a compile-time error if a default method is override-equivalent with a non-private method of the class Object, because any class implementing the interface will inherit its own implementation of the method.` And even if you could, your default method would never be invoked, as `Object` already provides a more specific implementation. – biziclop Sep 07 '15 at 12:56

1 Answers1

5

You cannot enforce such a contract on an Object method from an interface. And you shouldn't. Relying on Object.toString() is not a good idea. This is your best approach:

interface TestInterface {
    public String toSensibleString();
}
Lukas Eder
  • 211,314
  • 129
  • 689
  • 1,509