2

Say I have an interface Interface, which only contains getters for various fields. This interface has multiple implementations (say Foo and Bar), each of which adds various fields. All these implementations are immutable.

Assume I have an instance interface of Interface, and I want to create a copy of this instance which changes one of the fields exposed by Interface. How can I achieve this without casting interface to a subtype? I cannot use a Builder class for Interface because this is an abstract interface.

I believe this problem is a fairly generic OOP problem but here is what the Java code for it would look like:

public interface Interface {
     public int getVersion();
}

public class Foo implements Interface {
     private final int version;
     private final String owner;

     public Foo(int version, String owner) {
          this.version = version;
          this.owner = owner;
     }

     public int getVersion() {
          return version;
     }

     public String getOwner() {
          return owner;
     }

     public String toString() {
          StringBuilder builder = new StringBuilder(owner);
          builder.append(" v");
          builder.append(version);
          return builder.toString();
     }
}

public Bar implements Interface {
     // similar to Foo
}

and the situation where I want to copy an existing instance:

Interface instance = new Foo(1, "some value");
assertEquals("some value v1", instance.toString());
Parent copy = // create the copy based on instance but updating the version to 2
assertEquals("some value v2", copy.toString());

2 Answers 2

1

Very simple. Add a method “copyWithVersion()” to the interface and implement it in both implementations.

BTW. “Parent” is not a good name for an interface. We might use that name for a base class but not for an interface.

2
  • But what about the return type of this method? Doesn't it force me to use the interface as return type in both classes?
    – pintoch
    Jan 25, 2018 at 12:20
  • Okay, it looks like Java actually allows to override return types with more specific subclasses, so that will do, thanks!
    – pintoch
    Jan 25, 2018 at 12:52
1

Since the Interface consists of "getters for various fields" you can simply make another object, perhaps called 'InterfaceCloner' that has the task of making copies. You could also add methods to the interface that 'change' the fields but actually return a new instance like this 3D vector class: https://introcs.cs.princeton.edu/java/stdlib/javadoc/StdDraw3D.Vector3D.html

Although I would like to point out that thinking of methods as 'exposing fields' and using 'getters' does not look like the most maintainable solution to me. The fact that the implementers, "each of which adds various fields", makes me think you are not using the full potential of the interface. I think of interfaces as things that have only behaviour, regardless of how that is backed up. All implementers may not add behaviour, since that would result in less usage of the interface (a violation of Liskov's Substitution Principle). I think that using my first suggestion alongside an equals(Object) method that only checks the interface methods (behaviour, not exposed fields!) is the most maintainable solution.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.