当我们使用上一个资料库的话,CD和DVD两个几乎一模一样,重复,代码冗余。
这种代码不具有可拓展性,每增加一个新对象都要做很多工作。
那我们能不能从CD和DVD中提取出来一些共同的东西,让一个新的类去管理它们
先建立一个新类
- public class Item{
-
- }
然后CD和DVD 是一种特殊的Item ,继承Item的东西
- public class CD extends Item{
-
- }
- public class DVD extends Item{
-
- }
然后在调用存储它们的类Database里,创建了存 Item 的对象的容器
- public class Database{
- private ArrayList
- listItem = new ArrayList
- ();
- }
那往容器里面添加对象,也是对ArrayList
- 里面添加对象
public void add(Item item){ listItem.add(item); }成员函数里的参数是Item类的对象
那接着,输出容器里的对象的成员函数,只用做一个Item
public void list(){ for(Item item : listItem){ item.print(); } }这里利用for - each循环,将容器liteItem里面的对象赋值给Item类型的参数,那调用print的话,自然会调用自身类的成员函数
此时,没有print(),需要在Item里面创建成员函数
- public class Item{
- public void print(){
- System.out.println("Item");
- }
- }
此时,如果运行代码还是可以运行的,现在的关系是
Database 直接和Item挂钩,然后CD和DVD继承了Item里的所有变量和函数,直接和Item联系
此时我们add 成员函数接受的是Item类,而我们传入的参数是CD 和DVD,但是是可以接收的,为什么?
首先我们CD和DVD类表明了extends了Item类,但是这样说有点牵强,回过来看Database对item的全部认识如何,它认为item应该有一个print函数,因为这是在Database 唯一用到Item的东西,然后在Item里面说,是有print的,现在在CD里面也是有print(),对于
for( Item item : listItem){
item.print();
}
只要对象里有print就可以认为是Item,至于是Item中哪一个Item,是不关心的。因为函数要的就是有print()就可以了。
现在我们把CD里面的
public void print(){}
注释掉,然后来看一下,也没有出错
运行以下,输出了Item里的print内容,说明CD从Item得到继承了,
得到什么呢?得到了Item所有东西,即使CD里面没有print()函数,照样也会继承Item里面的print()。
我们可以去尝试一下,
注视完CD里面的print()函数,然后去CD主函数里面创建一个对象,去调用print函数
- public static void main(Stirng[] args){
- CD cd = new CD("aaa","fafa",2,3,"...");
- cd.print();
- }
debug一下,new创建对象的时候,会先去Item父类里面初始化对象,然后去调用函数的时候,直接跳转到Item的print()函数,这说明什么,说明CD天然得到了Item里面的函数。子类继承了父类的东西,子类也可以在自己类里面增加新东西。
我们把用来做基础派生其它类的那个类叫做父类、超类或者基类,而派生出来的新类叫做子类。Java用关键字extends表示这种继承/派生关系:
class ThisClass extends SuperClass {
//… }
继承表达了一种is-a关系,就是说,子类的对象可以被看作是父类的对象。比如鸡是从鸟派生出来的,因此任何一只都可以被称作是一只鸟。但是反过来不行,有些鸟是鸡,但并不是所有的鸟都是鸡。如果你设计的继承关系,导致当你试图把一个子类的对象看作是父类的对象时显然很不合逻辑,比如你让鸡类从水果类得到继承,然后你试图说:这只本鸡是一种水果,所以这本鸡煲就像水果色拉。这显然不合逻辑,如果出现这样的问题,那就说明你的类的关系的设计是不正确的。Java的继承只允许单继承,即一个类只能有一个父类。
讨论:
子类从父类得到什么?(子类从父类得到了什么?比如:成员函数?成员变量?设计一些场景,来检验一下子类从父类都得到什么了。)
答:子承父业,除了构造函数其他都得到了。构造函数必须用类的名字命名。简单来说,继承的效果,就相当于把父类的代码自动复制过来了
复制只是个比喻,而且这种“复制”是有条件的,根据父类里面修饰符的权限来复制