se-edu/addressbook-level4

Inheritance bug for List<Person>?

Closed this issue · 3 comments

Hi, I seem to have discovered an unexpected behaviour when creating subclasses for Person.

I created two Classes:
Customer extends Person
Runner extends Person

I then use addressbook.addPerson(Customer) and addressbook.addPerson(Runner) to add a new Customer and Runner in the list of Persons in the addressbook. However, upon using addressbook.getPersonList.get(index) to retrieve these two Person objects, and checking its type using instanceof Customer and instanceof Runner, it always returns false.

As a result I'm unable to retrieve and operate on subclasses of Person stored into addressbook's UniquePersonList, even though I am able to add them in the list without an exception being returned.

HOWEVER when I do it this way, the inheritance seems to be working properly:

//===Test that inheritance works with customer, runner, person w arraylist ===>
        ArrayList<Person> personList = new ArrayList<>());
        Customer cust = new Customer();
        Runner run = new Runner();
        personList.add(cust);
        personList.add(run);

        for(int i = 0; i < 2; i++) {
            Person test = personList.get(i);
            if (test instanceof Customer) {
                System.out.println("Customer");
            } else if (test instanceof Runner) {
                System.out.println("Runner");
            } else {
                System.out.println("Neither");
            }
        }

and the output is Customer and Runner

Why does retrieving Customer and Runner fail when using addresbook's list implementation, even though it works normally with an ArrayList?

Can I use subclasses of Person at all?

Without your code, it's quite hard to understand why this is happening. :p

Edit: Well, of course it fails.

public void addPerson(Person p) throws DuplicatePersonException {
Person person = syncWithMasterTagList(p);
// TODO: the tags master list will be updated even though the below line fails.
// This can cause the tags master list to have additional tags that are not tagged to any person
// in the person list.
persons.add(person);
}

Calling AddressBook#addPerson(Person) creates a new Person object; your Customer and Runner is being "converted" to a Person object :p

EDIT: Thanks.

I just realised the problem as well:

AddressBook.addPerson(Person person) calls Person syncWithMasterTagList(Person person), which returns a newly constructed Person, which is then passed to UniquePersonList.add(Person) etc.

Hence, when I pass an object which is a subclass of Person to ModelManager.addPerson(Person), the subclass doesn't eventually get stored in AddressBook.UniquePersonList. Modifications had to be made to AddressBook.syncWithMasterTagList() in order to pass the intended object to UniquePersonList.

Great job! :)