简体   繁体   中英

Creating a subclass object with the subclass's type or its superclass's type

Assume I had a superclass called Person with private instance variables name and age and a subclass called Student which adds an instance variable called school. My parent constructor is:

public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

My child constructor is:

public Student(String name, int age, String school) {
        super(name, age);
        this.school = school;
    }

I can create an object with the Student constructor in the following ways:

Student test = new Student("Joe", 20, "StackOverflow");
Person test = new Student("Joe", 20, "StackOverflow");

I am not sure what the difference is in this case, or in any case in general or if either has certain advantages over the other.

In small programs like this it is difficult to see the benefits of inheritance and specifically the ability to create students and persons the same way.

However, think for a second that you have a sorting algorithm that sorts the type 'Person' and only that type.

Person p = new Person(name, age);
ArrayList<Person> list = new ArrayList<Person>();

Sort(list);

Where the sort method only takes a list of type Person.

Later you realize that being able to sort students would be nice but you do not want to rewrite the sorting algorithm. Since your sorting algorithm is coded for only the 'Person' type you can now pass a student in but contained in a person. You can also override the a comparison method to sort students differently than people. This is a simple example and there are many more.

Person s = new Student(name, age, school);
list.add(s);
Sort(list);

The above are all valid and you had to do no rewriting of code. (assuming name, age, and school are the right types etc..).

There's a few reasons why you might want to have the reference type as Person . In general, it's more abstract, requires less thinking while coding and reading the code.

  • Future readers of your code won't have to wonder why the type needed to be Student , they may ponder and spend too much time trying to figure out if there's Student specific operations used or why there is not.
  • It limits the number of operations/fields as your coding, so the complexity of what's available to look at and call is lower. So, there's less potential for mistakes from calling the wrong methods, what you need is only what's available.
  • You may need to change what subclass your Person instance is later (like if you introduced Teacher extends Person ), and if you chose to declare the variable as a Person , then you know for sure you won't need to change any other lines of code besides the instantiation, as you did not call any equivalent methods that were redefined/rewritten/wrapped in Student (I suppose that would usually be a poor design if such methods existed, but possible).

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