Home > Software engineering >  Spring does not accept an abstract class inheritor as an argument
Spring does not accept an abstract class inheritor as an argument

Time:10-10

I have the following problem while creating a model in Spring Boot.

Created an abstract model class -

public abstract class AbstractRequest {
    private String tariffType;
}

And his heir

public class Request extends AbstractRequest {
   // some fields
}

In the controller I pass an abstract request

@PostMapping
public ResponseEntity<PriceResponse> calculate(@RequestBody AbstractRequest request) {
    return ResponseEntity.ok(calculationService.calculate(request));
}

The service interface also has an abstract request class

public interface CalculationService {
    PriceResponse calculate(AbstractRequest request);
}

In the implementation of the service interface, I am trying to accept the successor of the abstract model

@Service
public class CalculationServiceFTL implements CalculationService {
    @Override
    public PriceResponse calculate(Request request) {
    }
}

And as a result I get an error

Class 'CalculationServiceFTL' must either be declared abstract or implement abstract method 'calculate(AbstractRequest)' in 'CalculationService'

Please explain why spring does not accept an abstract class heir as an argument and how should I be in this case if I can have several abstract model heirs and I need to process them differently in different services. Thanks

CodePudding user response:

If you are implementing an interface you need to implement all the unimplemented methods from the interface you're implementing with the same method signature .

public interface CalculationService {
    PriceResponse calculate(AbstractRequest request);
}

so your implemented class should also have same implemented method with same signature like

@Service
public class CalculationServiceFTL implements CalculationService {
    @Override
    public PriceResponse calculate(AbstractRequest request) {
    }
}

So in order to resolve this you can change the parameter type in interface class or your implemented service class so that those are same.

CodePudding user response:

  1. An abstract class cannot be instantiated directly but by its inheriting concrete classes.

  2. Any concrete class inheriting the abstract class should be instantiable with a constructor (if not abstract itself of course). But use of a constructor is prohibited by Spring because any class that we instantiate this way cannot be taken in charge by Spring’s automated dependency injection.

  • Related