I have a class Party that has a constructor that takes a Collection<Foo>. I plan to have two subclasses NpcParty and PlayerParty. All Party instances have an upper limit on the size of the input collection (6). However, an NpcParty has a lower bound of 1, while a PlayerParty has a lower bound of 0 (or rather, there is an implied minimum bound because a List cannot have a negative size). This is a violation of LSP because the NpcParty strengthens the preconditions in terms of the size of the input collection.An NpcParty is intended to be immutable; meaning that the only Foos it will ever have, are those that are specified in the constructor. A PlayerParty's Foos can be changed at runtime, either in order, or reference/value.public class Party {    // collection must not be null    // collection size must not exceed PARTY_LIMIT    public Party(List<Foo> foos) {        Objects.requireNonNull(foos);        if (foos.size() > PARTY_LIMIT) {            throw new IllegalArgumentException(foos exceeds party limit of  + PARTY_LIMIT);        }    }}public class NpcParty extends Party {    // additional precondition that there must be at least 1 Foo in the collection    public NpcParty(List<Foo> foos) {        super(foos);        if (foos.size() < 1) {            throw new IllegalArgumentException(foos must contain at least 1 Foo);        }    }}public class PlayerParty extends Party {    // no additional preconditions    public PlayerParty(List<Foo> foos) {        super(foos);    }}In what ways can I resolve this violation, such that an NpcParty is allowed to have a minimum bound?EDIT: I'm going to give an example of how I might test this.Suppose I had a class AbstractPartyUnitTests that tested the minimum contract of all Party implementations.public class AbstractPartyUnitTests {    @Test(expected = NullPointerException.class)    public void testNullConstructor() {        createParty(null);    }    @Test    public void testConstructorWithEmptyList() {        party = createParty(new ArrayList<Foo>());        assertTrue(party != null);    }    @Test(expected = IllegalArgumentException.class)    public void testConstructorThatExceedsMaximumSize() {        party = createParty(Stream.generate(Foo::new)                                  .limit(PARTY_LIMIT + 1)                                  .collect(Collectors.toList()));    }    protected abstract Party createParty(List<Foo> foos);    private Party party;}With subclasses for PlayerParty and NpcPartypublic class PlayerPartyUnitTests extends AbstractPartyUnitTests {    @Override    protected Party createParty(List<Foo> foos) {        return new PlayerParty(foos);    }}andpublic class NpcPartyUnitTests extends AbstractPartyUnitTests {    @Test    public void testConstructorThatMeetsMinimumSize() {        party = createParty(Stream.generate(Foo::new)                                  .limit(1)                                  .collect(Collectors.toList());        assertTrue(party != null);    }    @Test(expected = IllegalArgumentException.class)    public void testConstructorThatDoesNotMeetMinimumSize() {        party = createParty(new ArrayList<Foo>());    }    @Override    protected Party createParty(List<Foo> foos) {        return new NpcParty(foos);    }}All of the test cases would pass, with the exception of testConstructorWithEmptyList while running as an NpcPartyUnitTests. The constructor would fail, and as such, the test would fail.Now, I could remove that test from the AbstractPartyUnitTests class, as it does not really apply to all types of Party; but then anywhere I have a Party, I may not be able to have a 1:1 replacement of NpcParty.
How to resolve LSP violation based on minimum precondition
java;design patterns;object oriented design;liskov substitution