I'm very surprise by a non expected behaviour of a class I'm building (kind of Composite pattern).
Here's the point and the classes involved :
IGroupableis an interface with 2 methodspublic interface IGroupable {
BigDecimal getTotal(); Boolean isManuallySettlable();}
Eventclass implementsIGroupable@Entity @Table(name="V_ALL_BUSINESS_EVENTS") public class EventView implements IGroupable, Serializable {
@Id @Column(name="UNIQUE_ID") private long eventId; ... @Override public BigDecimal getTotal() { return this.eventGrossAmount; } @Override public Boolean isManuallySettlable() { return (this.eventIsManuallySettlable == null || this.eventIsManuallySettlable == false) ? false : true; }AbstractGroupabstract class implementsIGroupable:public abstract class AbstractGroup implements IGroupable, Serializable {
private static final long serialVersionUID = 1L; protected int nbRows; protected transient List<IGroupable> groups; ...CurrencyGroup,BuyerPlatformGroupandCounterpartExecDateGroupall extendAbstractGroup, so each has aList<IGroupable> groupspropertypublic class CurrencyGroup extends AbstractGroup {
protected String currency; // -------------------------------------------------------- public CurrencyGroup(String currency) { this.currency = currency; super.groups = new ArrayList<>(); } ... @Override public BigDecimal getTotal() { BigDecimal total = new BigDecimal(0); total = this.groups.stream() .map(groupable -> groupable.getTotal()) .reduce(total, BigDecimal::add); return total; } @Override public Boolean isManuallySettlable() { boolean isSettlable = true; for(IGroupable g : groups) { if(!g.isManuallySettlable()) { isSettlable = false; } } return isSettlable; }public class BuyerPlatformGroup extends AbstractGroup {
protected String buyerName; protected String buyerRTS; protected String platform; // -------------------------------------------------------- public BuyerPlatformGroup(String buyerName, String buyerRTS, String platform) { this.buyerName = buyerName; this.buyerRTS = buyerRTS; this.platform = platform; super.groups = new ArrayList<>(); } ... @Override public BigDecimal getTotal() { BigDecimal total = new BigDecimal(0); total = this.groups.stream() .map(groupable -> groupable.getTotal()) .reduce(total, BigDecimal::add); return total; } @Override public Boolean isManuallySettlable() { boolean isSettlable = true; for(IGroupable g : groups) { if(!g.isManuallySettlable()) { isSettlable = false; } } return isSettlable; }}
public class CounterpartExecDateGroup extends AbstractGroup {
protected String counterpart; protected Date execDate; protected BigDecimal amount; protected String step; protected String operationType; // -------------------------------------------------------- public CounterpartExecDateGroup() { super.groups = new ArrayList<>(); } ... @Override public BigDecimal getTotal() { BigDecimal total = new BigDecimal(0); total = groups.stream() .map(groupable -> groupable.getTotal()) .reduce(total, BigDecimal::add); return total; } @Override public Boolean isManuallySettlable() { boolean isSettlable = true; for(IGroupable g : groups) { if(!g.isManuallySettlable()) { isSettlable = false; } } return isSettlable; }}
-> they all inherit from 'AbstractGroup' and also all are 'IGroupable' objects
@Test
public void allIGroupableTest() {
List<EventView> events = eventDao.findAll();
EventView event = (EventView) events.get(0);
CurrencyGroup ccyGrp = new CurrencyGroup("EUR");
BuyerPlatformGroup buyerGrp = new BuyerPlatformGroup(event.getEventBuyerName(), event.getEventRTSCode(), event.getEventPlatform());
CounterpartExecDateGroup counterpartGrp = new CounterpartExecDateGroup();
ccyGrp.addGroup(buyerGrp); // OK
buyerGrp.addGroup(counterpartGrp); // OK
counterpartGrp.setGroups(events); **// ERROR**
But I've got an error, telling me : The method setGroups(List<IGroupable>) in the type AbstractGroup is not applicable for the arguments (List<EventView>).
Why does it behave this way ?
As the Event class implements IGroupable interface, a list of IGroupable objects should be able to accept a list of Events, isn't it ?