Updated answer: In fact, there are not three situations, but two situations. Let me give you an example of a scenario that is often encountered in actual development, and you will understand why "we often have to transform an object into its parent class or interface for use."
Usually we write like this when using lists:
List list = new ArrayList();
instead of
ArrayList list = new ArrayList();
Why is the first one better than the second one?
Suppose you declare a list in two ways, and then it is referenced by others (or used by yourself in other places).
Suddenly one day, you find that using ArrayList is not good and you need to switch to LinkedList, then you must change the statement to:
LinkedList list = new LinkedList();
In this way, the type declaration must be changed wherever your list is used. More importantly, people who use your list write their own code based on the premise that "your list is an ArrayList." If you suddenly change it to a LinkedList, it may cause Their program breaks or needs to be rewritten.
But if you use the first declaration method from the beginning, you won’t have this problem. You can change the list at any time, and other people or other places that reference your list do not need to make any changes. For example:
List list = new LinkedList();
So, when you declare a variable, declare its type as generally as possible, and as specific as possible, the worse. The former is friendly to modifications, while the latter is not friendly to modifications.
Similarly, when determining the accessibility of a method (i.e. public, protected, default, private), when possible, the smaller the better.
ArrayList implements the List interface, so ArrayList must be of List type. Similarly, List implements the Collection interface, so List must be of Collection type. It can also be understood as the upward transformation of ArrayList.
For example, you are a wine god and have a special liking for wine. One day I went home and found several glasses on the table filled with white wine. It was impossible to tell what kind of wine it was from the outside. Only after drinking it could we guess what kind of wine it was. When you drink it, it’s Jiannanchun, when you drink it again, it’s Wuliangye, and when you drink it again, it’s Jiuguijiu... Here we can describe it as follows:
酒 a = 剑南春
酒 b = 五粮液
酒 c = 酒鬼酒
…
这里所表现的的就是多态。剑南春、五粮液、酒鬼酒都是酒的子类,我们只是通过酒这一个父类就能够引用不同的子类,这就是多态——我们只有在运行的时候才会知道引用变量所指向的具体实例对象。
诚然,要理解多态我们就必须要明白什么是“向上转型”。在继承中我们简单介绍了向上转型,这里就在啰嗦下:在上面的喝酒例子中,酒(Win)是父类,剑南春(JNC)、五粮液(WLY)、酒鬼酒(JGJ)是子类。我们定义如下代码:
JNC a = new JNC();
对于这个代码我们非常容易理解无非就是实例化了一个剑南春的对象嘛!但是这样呢?
Wine a = new JNC();
在这里我们这样理解,这里定义了一个Wine 类型的a,它指向JNC对象实例。由于JNC是继承与Wine,所以JNC可以自动向上转型为Wine,所以a是可以指向JNC实例对象的。这样做存在一个非常大的好处,在继承中我们知道子类是父类的扩展,它可以提供比父类更加强大的功能,如果我们定义了一个指向子类的父类引用类型,那么它除了能够引用父类的共性外,还可以使用子类强大的功能。
Updated answer:
In fact, there are not three situations, but two situations.
Let me give you an example of a scenario that is often encountered in actual development, and you will understand why "we often have to transform an object into its parent class or interface for use."
Usually we write like this when using lists:
instead of
Why is the first one better than the second one?
Suppose you declare a list in two ways, and then it is referenced by others (or used by yourself in other places).
Suddenly one day, you find that using ArrayList is not good and you need to switch to LinkedList, then you must change the statement to:
In this way, the type declaration must be changed wherever your list is used. More importantly, people who use your list write their own code based on the premise that "your list is an ArrayList." If you suddenly change it to a LinkedList, it may cause Their program breaks or needs to be rewritten.
But if you use the first declaration method from the beginning, you won’t have this problem. You can change the list at any time, and other people or other places that reference your list do not need to make any changes. For example:
So, when you declare a variable, declare its type as generally as possible, and as specific as possible, the worse. The former is friendly to modifications, while the latter is not friendly to modifications.
Similarly, when determining the accessibility of a method (i.e. public, protected, default, private), when possible, the smaller the better.
This is the parent class referencing the subclass object, that is, upward transformation, which is one of the necessary conditions for polymorphism
ArrayList implements the List interface, so ArrayList must be of List type. Similarly, List implements the Collection interface, so List must be of Collection type. It can also be understood as the upward transformation of ArrayList.
Parent class reference points to child class object
For example, you are a wine god and have a special liking for wine. One day I went home and found several glasses on the table filled with white wine. It was impossible to tell what kind of wine it was from the outside. Only after drinking it could we guess what kind of wine it was. When you drink it, it’s Jiannanchun, when you drink it again, it’s Wuliangye, and when you drink it again, it’s Jiuguijiu... Here we can describe it as follows: