简体   繁体   中英

Overriding Interface Default Methods

I am having some trouble getting the following code to work:

Interface:

public interface UOWProcessor {
  public default Integer countUOW(Object args) {
    return 1;
  }
}

Implementation:

public class ListUOWProcessor implements UOWProcessor {
private Integer total;

@Autowired
private UOWProcessor uowProcessor;

@Override
public Integer countUOW(List<?> args) {
    for (Object arg : args) {
        total += uowProcessor.countUOW(arg);
    }

    return total;
  }
}

Edit: Adding second implementation to clarify intention

public class MapUOWProcessor implements UOWProcessor {
    private Integer total;

    @Autowired
    private UOWProcessor uowProcessor;

    @Override
    public Integer countUOW(Map<?, ?> args) {
        for (Object item : args.values()) {
            total += uowProcessor.countUOW(item);
        }

        return total;
    }
}

The trouble is the @Override annotation is giving an error that says the method does not override a method from its superclass . This is Java 11. What is the correct syntax for this?

Here is what I am trying to do in English if it is not clear from above:

Another class will call the interface method countUOW(Object of unknown type).

If there exists an implementation of this interface for the type of object (for example, ListUOWProcessor for Lists, MapProcessor for Maps) the implementation will then be called and will iterate and return a total (basically a count of objects). This is called recursively to account for nested arrays/lists.

If there exists no implementation, we can assume the Object being passed is some non-specific Object which then has a count of 1.

To the original call of the method we should then return a count of all the Objects in the parent Object that was passed, including those in nested arrays or maps.

I could also remove this word "default" from the Interface and just create an ObjectUOWProcessor which does the same thing - however I am worried it might take precedence over every other implementation because List, Array, Map are all extensions of Object.

Edit: I understand that this is not an Override, now, but an Overload. Will the code without the @Override annotation achieve the described functionality?

You did well to include the @Override annotation. Because of this, the compiler informed you that you did not properly override the countUOW method. The parameter types differ -- the interface method takes an Object and the implementing class method takes a List<?> . This means that you have overloaded the method, not overridden it.

You can do one of the following:

  1. Change the signature of the interface method to match.

     public default Integer countUOW(List<?> args) { return 1; } 
  2. Change the signature of the implementing class method to match.

     @Override public Integer countUOW(Object args) { for (Object arg : (List<?>) args) { total += uowProcessor.countUOW(arg); } return total; } 
  3. Make the interface generic and have the implementing class supply the type as a parameter.

     public interface UOWProcessor<T> { public default Integer countUOW(T args) { return 1; } } public class ListUOWProcessor implements UOWProcessor<List<?>> { // ... @Override public Integer countUOW(List<?> args) { for (Object arg : args) { total += uowProcessor.countUOW(arg); } return total; } } 

Note that none of this has anything to do with the fact that your method is default . You'd get the same error, with the same options to resolve the issue, whether it was a default method or an abstract method, and whether the overridden method was in an interface, an abstract class, or a concrete class.

Well, you can't pass a String as a parameter in your implementation since it's expecting a List<?> , while the interface clearly says that all classes should be able to be passed as parameters since all classes extend Object . You are thus not following the criteria specified in the interface. You have changed the signature of the method and are thus not overriding it; you are overloading it.

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