Hi,你好,我们一起来学习类的继承。
继承呢,可以说是面向对象程序中最为重要的
特性之一,当然,这个我们说面向对象呢有三大特性,就是
封装,就是把什么比如说性别、年龄都封装到一个Person这个类。
第二个是继承,第三个是多态,多态我们前面提过了, 就是说我写一个语句,它能自动识别应该怎么做。
那么继承呢可以说是这里面呢最为重要的特征。
它的,我们在继承过程当中呢,有子类跟
父类的一个关系,那么子类呢它就继承了父类或者称为超类的 那一些特征,那么当这个父类呢还
包括了它上,父类的父类,也就是间接的那个父类。
java里面呢,它这个继承呢一方面
它用了继承,另一方面它也很直接地就是它只支持单继承,也就是说,
一个类只能有一个直接的父类,就是一个类只有一个父类呢
我们就避免了很多麻烦事,比如说我们在初始化的时候,
它既是这个的父类,又是那个,既是这个的子类,又是另一个类的子类的话,我们就搞不清楚- 我们初始化
应该做什么。就像一个孩子,如果有两个父亲,这个就有点麻烦。
那这个是单继承呢是java里面
它把这个我们说是C++--,就是把C++的复杂的东西去掉了,
它这个就更简洁一些。那么这个继承有什么好处?我们说它是最重要的特征之一了,
就是子类它可以自动地继承父类的状态和行为。这样的话 我们就不用写好多遍了,所以呢,比如说我们学生
他就是人的一个子类,这样的话自动地,学生自动地
就有人的特点,比如说姓名啊,年龄啊,打招呼啊等等。那么
同时,它在继承的同时还可以修改父类的这些行为, 状态和行为,还可以添加状态和行为。
所以这样的话,我们说继承,包括修改或添加,
都能够,所以我们后面就要学习,就是说我在怎么样去
修改父类的,怎么样添加,怎么样继承,所以这我们后面就要逐渐地学到。
那总地说呢,这个继承的好处呢就是,一个是提高程序的抽象程度,我们把
所有的,比如说有学生,有老师,还有各种管理
人员,那他都是人,那我们提高了我们定义的人呢,就把他抽象
出来,同时呢,实现了代码重用,所有关于人的,不论你是学生还是老师,还是管理人员,
都可以呢使用它,那么就可以提高开发效率和可维护性。
在一定意义上,面向对象程序设计如果没有继承的话呢,基本上是也没什么用,
那基本上最多也就是把变量和函数写 到一起而已。所以继承呢,是相当相当重要的。
那么这个派生的这个子类呢,它是怎么写呢?它就是用一个关键词
extends,我们翻译成继承也可以,翻译成扩展也可以。
这个学生它就继承了人的所有特征,同时又扩展了
人的特征,如果我们不翻译呢,我们直接叫extends Person。
如果一个类,我们在定义一个类的时候没有写extends语句,那么java呢
它有一个处理,统一的处理,就是说默认为
是java.lang.Object的子类。就是任何一个类
它都是Object的子类,在这个意义上呢,所有的类都是直接或间承的,
间接地继承Object的子类,这个好处太明显了,就是说我们任何的
对象它都是object的子类,那我们可以更,最高层次呢,就是 object,那就object。当然任何一个对象我们都可能用它的
比如说toString,都用toString方法,都可以转成字符串, 我们都可以克隆等等。所以它这种呢,把所有的都
统一起来了,所以这是一个很好的一个思路。就是即使你不写,
它也是object的子类。那么在继承关系的里面呢,
我们通常呢,就所谓的UML图,就是 统一模型语言,我们简单地说就是我们把各种
程序里的这些类啊,用一种图来表示, 那这个图呢我们经常用个箭头,就是表示它
学生类,就继承了person这个类,用一个箭头 来表示。那么所有的继承呢都相当于is
a的关系, 那is a的关系,也就是说,任何一个学生他一定是一个人,所以相当于is
a, 所以这个意义上来说呢,我们可以说如果我们定义成一个角色的话, 它不能是is
a父母,就是所以他们之女和父母呢它不能叫做这么一个 继承关系。当然我们这里呢学生和人它就是一个继承关系,
所以这个继承关系你看我们在extends在继承的同时, 又可以增加什么呢?比如说增加他的学校,增加
他的分数,然后呢判断他是不是一个好学生等等。
那很显然在这里面呢,我们就没有必要再重写人的姓名啊
年龄啊,sayHello啊等等。所以这个意义上呢,继承呢,它
提高了这个开发效率。好,下面我们就来 详细地来说呢,继承呢包括对字段的继承和
这个方法的继承,包括增加呀,包括
修改等等。那么字段呢,它是变量,所以它默认呢 就继承了父类的这个字段,那么自动地就继承了比如说
姓名和年龄。当然我们在一种特殊的情况下呢,继承呢还可以,
还可以把父类自动地继承,但是我们可以隐藏,也就是说我们定义一个完全相同的变量,
父类的这个变量呢,我们就隐藏了,但这种情况极少。
那总的来说还是可以在一定意义上呢,我又定义一个同样的,实际上就把父类给隐藏了,
或者说修改了,所以这个很少用。更多的就是添加, 我们刚才说的,比如说我在继承的同时,又添加他的学校
添加了分数,还添加了其他的一些比如说判断 其他的一些属性,所以这个继承很简单
直接就增加,直接就可以再增加一些。
那么方法也是一样的,方法默认情况下呢,也是继承的。所以,
父类的这些方法呢它也是自动地就继承了,我们不需要做特殊的声明,它自动继承,
当然除非对一些是你加了private私有的,那它就没法继承了,这个我们是特殊情况,- 我们以后再说,
比如说student自动地继承了Person的sayHello和isOlderTh- an等等这些方法。
在继承的同时,我们也可以覆盖,或者是修改,或者修改了父类的方法,这个
覆盖呢称为override,那么在定义 同样的同名的方法,定义一个同名的方法,
它还对父类的方法呢进行了覆盖或修改。我们下面看,
比如说这个例子,子类呢,也定义了一个
sayHello,打招呼,然后呢它就有,这个方法呢写的就不一样了,system.- out说
Hello,我是谁,然后我是来自哪个学校的,所以这样的一个声明呢
让我们就修改了普通人打招呼,普通人打招呼只能说Hello,
我是谁,对吧?那这里呢,我还介绍了我学校是谁,我是来自哪个学校的,
所以它就override,又覆盖了或者改写了、 修改了父类的打招呼方式。那么以后我们在调用
一个学生的打招呼,它会自动地去调这个学生的打招呼方式, 它就不会调普通人打招呼的方式。在
JDK 1.5以后呢,可以用一个特殊的 注记,特殊的标注,或者叫特殊的注记
annotation,这个注记呢是用一个@,@一个Override, 注意这个O是大写的啊,所以@Override
然后来表示我这个方法呢是覆盖了父类的方法。这样就更清晰一些,有了这个注记。
当然了,不用也是可以的,因为早期是没有的,没有这个,所以我们最好还是写上这个,看得- 更清楚。
通过方法的覆盖呢,它其实是修改了父,父类对象的
具体的实现方法,所以它既可以增加,也可以修改,
修改就是override。那么当然添加呢就简单,我们可以
添加,比如说刚才说isGoodStudent,然后我们就,就写一个什么 就这样的话,增加一些方法,这个好理解。
还有一个比较特殊的增加的方式呢,称为方法的重载, 那就是重载呢我们虽然是名字是一样的,比如说sayHello,
但是我们带的参数的签名是不同,所谓签名呢,就是说我带的参数 的类型或个数,比如Student我带一个Student
这样一个,那我跟另一个人打招呼,另一个同学打招呼,这实际上是增加了一个方法,但是呢
因为他名字相同,签名又不同, 所以这种呢我们就称为重载,重载呢实际上是新加的一个方法,
当然我们就可以写方法体不一样了,比如说,先说Hi,打招呼的声音也不同了,Hi,然后呢
如果是同样的学生呢,我们可以说,我们是同校
生,我们是同一个学校的,我们是同学,所以它就可以重载 父类的行为。