面向对象语言三个特性,封装继承多态。说完封装说继承。
达尔文的物种起源中提到,要用发展的眼光看问题,继承就是为了反映这个的。子类会继承父类中除了private,construtor,static类型以外的所有内容。
子类在使用这些方法的时候跟使用自己的没有不同,只是上一篇文章说的那样,继承来的成员的命名空间还是与父类相同的。
继承的一些语法规则:
- 使用extends关键字。
- 如果父类中有非默认的构造函数,需要在子类的构造函数中使用super(param)进行显示的调用。
- final类是不能够被继承的。
产生了继承之后,如果子类跟父类有同名的方法会产生什么现象呢?这时就会有三个概念:重载(overloading),覆盖(override),隐藏。
实际上吧,这三个概念其实挺不容易混淆的。
重载
方法名相同,但是形参列表不同。包括了顺序的不同和父子类的不同。
父类中继承来的方法跟本身的方法一样,是能够进行重载的。
覆盖和隐藏。
非static方法,方法名相同,参数列表也相同的就是覆盖。覆盖的方法可见性不能缩小,抛出的异常不能扩大。另外final的方法是不能够覆盖的。
而statci方法,方法名相同,参数列表也相同的就是隐藏,实际上static方法是不能够被继承的,跟覆盖没什么相同的地方,用代码来解释一下就是这样的:
打印的结果为:
pub_sub
pub_static_base
可见,同样是父类的引用,子类的实例,调用的方法却不同,有覆盖现象的调用的是子类的方法。
刚才说了final的类不能够继承,final的方法不能够覆盖,可见final强调了一个不能改变的意思,下面我们就来详细的讨论一下final。
final数据
- 常量。就是不能改变的量,如果再加上static的话就是只占一块固定内存的常量了。可以在声明的时候指定初始值,这是编译时的常量。也可以声明是不指定初始值,但是在构造器中必须指定,否则会有编译错误,这个是运行时常量。
- 引用。用于引用类型的时候,表示这个引用不能指向别的引用。
- 参数。表示在方法中,参数不能够重新定义。可以用来强制按照编程规范来开发。
final方法
- 使用final方法的时候通常是出于两个目的,效率或者是设计,
- 设计上的目的是禁止派生类进行修改。当我们想让一个方法被继承,但是不能被覆盖的时候就用这个。
- 在效率上,据说会采用内联的方式,会把方法拷贝过来进行进行编译,但是实际效果微乎其微,因此通常都是设计上的考
final类
表示不能继承的类,我们要慎用,因为我们不知道什么时候它会有用。
上传
这个是一个概念,继承赋予了能够把子类对象,当成自己本身类型或者是父类型来进行处理的功能,这样我们的同一份代码就能运行在这些不同的类别之上。。
这种能力叫做上传。
使用的时候就是形参为基类的,可以传入其派生类的实例来调用方法。因为把子类对象作为基类来处理,而在uml图中基类在上面因此命名为上传。