简体   繁体   English

使用子类的类型或其父类的类型创建子类对象

[英]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. 假设我有一个名为Person的超类,它具有私有实例变量的名称和年龄,以及一个名为Student的子类,它添加了一个名为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构造函数创建一个对象:

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”(人)和仅该类型进行排序。

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. 其中sort方法仅采用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 . 有几个原因使您可能希望将引用类型设置为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. 您的代码的未来读者将不必怀疑为什么类型必须是Student ,他们可能会思考并花太多时间试图弄清楚是否使用了Student特定的操作,或者为什么没有。
  • 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). 您可能需要稍后更改Person实例的子类(例如,如果您引入Teacher extends Person ),并且如果选择将变量声明为Person ,那么您肯定会不需要更改任何其他行。除了实例化之外,还需要编写代码,因为您没有调用任何在Student中重新定义/重写/包装的等效方法(我想如果存在这样的方法,通常是较差的设计,但可能的话)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM