How to rectify? — “both define getObjectCopy(), bu

2020-04-30 17:01发布

问题:

I have the following interface heirarchy (with all non-relevant functions stripped out). I am getting this error when trying to compile it:

types ValidLineGettable and ValidateValue<java.lang.String> are incompatible; both define getObjectCopy(), but with unrelated return types

This is all derived from the same function--not two different functions with the same name, the same function in the same interface. How do you deal with interfaces that must inherit from two different interfaces that themselves must inherit from a singular base interface?

There are two SO questions I've found regarding different functions that happen to have the same name

  • Inherit method with unrelated return types
  • Java - Method name collision in interface implementation

In my case it's the same function, both conceptually and in name.

(Although I am interested in opinions on if the Copyable interface is a good idea to begin with...it's in a lot of code that I use, and has worked well for me...I am mostly interested in the general inheritance/design question.)

I am not clear on how to best deal with this. I would appreciate any advice. Thank you.

public interface Copyable  {
   Copyable getObjectCopy();
}
interface ValidateValue<O> extends Copyable  {

   //Other functions...

   @Override
   ValidateValue<O> getObjectCopy();
}

//For classes that may be able to be Decorated into a TextLineValidator
interface ValidLineGettable extends Copyable  {

   //Other functions...

   ValidLineGettable getObjectCopy();
}
interface TextLineValidator extends ValidateValue<String>, ValidLineGettable  {

   //Other functions...

   @Override
   TextLineValidator getObjectCopy();
}

The error:

C:\java_code\Copyable.java:17: types ValidLineGettable and ValidateValue<java.lang.String> are incompatible; both define getObjectCopy(), but with unrelated return types
     interface TextLineValidator extends ValidateValue<String>, ValidLineGettable  {
     ^
 1 error

 Tool completed with exit code 1

回答1:

Assuming all the return values extend Copyable, have all versions of getObjectCopy() return Copyable. For example:

public interface ValidateValue<O> extends Copyable
{
     // Other functions...

     @Override
     Copyable getObjectCopy();
}

public Blammy implements ValidateValue<String>
{
    // Other functions...

     @Override
    public Copyable getObjectCopy()
    {
        SomethingThatExtendsCopyable blammy = new SomethingThatExtendsCopyable();

        return (Copyable)blammy;
    }
}

Edit

In your code above the error is caused by the fact that the "getObjectCopy" method has a different return value in the ValidateValue<String> and ValidLineGettable interfaces, but the calling signature is the same. In java, you do not get polymorphism by changing only the return value; this results in a compile error.

If you change the return value to Copyable then the TextLineValidator no longer gains value by extending both of its parent interfaces. A simpler approach is to have one interface (Copyable) and multiple classes that implement that interface, each of which returns a Copyable value which may be an instance of a class that extends (or implements) Copyable.



回答2:

The Eclipse compiler compiles your code without errors. JavaC from JDK 7 (1.7.0_45) and JDK 8 (1.8.0-ea) also work.

I think this is a bug in the JDK, most likely one related to bug #122881 (please note this one is fixed). I also found an issue in Google Protocol Buffer that points to another bug, but I can't find that one.

You could compile it with Eclipse or JDK 7, or change the code so that it doesn't require this feature.