继承特点
。继承是面向对象的三个特征(封装、继承、多态)之一,也是软件复用的重要手段
继承的特点
。Java继承具有单继承的特点
。。每个子类只有一个直接父类
。。子类扩展(extends)父类、父类派生(derive)出子类
重写父类的方法
1.定义
。子类包含与父类包含的现象称为方法的重写(override),也被称为方法覆盖
2.规则
。两同
。。方法名相同
。。形参列表相同
。两小
。。子类方法返回值类型小于或等于父类方法返回值类型
。。子类方法声明抛出的异常;类应小于或等于父类方法声明抛出的异常类
。一大
。。子类方法的访问权限大于或等于父类方法访问权限
3.
。覆盖方法和被覆盖方法要么都是类方法要么都是实例方法
。。例
4.
。当子类覆盖父类方法后,子类对象将无法访问父类中被覆盖的方法
。可以在子类方法中调用父类中被覆盖的方法
。。使用super(被覆盖的是实例方法)或父类类名(被覆盖的是类方法)作为调用者来调用父类中被覆盖的方法
5.
。如果父类方法的访问权限是private,则该方法对自类是隐藏的,即子类对该方法无访问权限,也就无非重写该方法
。如果子类定义了一个private的同名方法、相同形参列表的(相同返回值类型),依然不是重写,只是重新定义了一个方法
。。即private方法不能被重写(覆盖)
Super限定
。要在子类方法中调用父类被覆盖的实例方法,则使用super限定来调用父类被覆盖的实例方法
。在构造器中使用super,则super用于限定该构造器初始化该对象从父类继承得到的实例变量或方法;而不能是该类自定义的实例变量
。。正如this不能出现在static修饰的方法中一样,super也不能
。子类和父类定义了同名的实例变量,则子类实例变量会隐藏父类中的实例变量
。。正常情况下子类定义的方法直接访问该实例变量默认访问子类自定义变量,无法访问到父类中的被隐藏的实例变量
。。子类定义方法可通过super关键字来访问父类中被隐藏的实例变量
。。例
。当程序创建一个子类对象时,系统不仅会为该类中定义的实例变量分配内存,也会为其从父类继承得到的所有实例变量分配内存,即使子类定义了与父类中同名的实例变量
。子类定义与父类同名的实例变量不会完全覆盖父类中定义的实例变量,只简单隐藏父类中的实例变量
。。例
。。以上将实例对象sub转换为Base类型可访问父类中的同名实例变量
调用父类构造器
。子类不会获得父类构造器,但子类构造器里可以调用父类构造器的初始化代码
。。在一个构造器例调用重载构造器使用this关键字调用完成
。。在子类构造器里调用父类构造器使用super关键字调用完成
。。使用super调用父类构造器必须出现在子类构造器执行体的第一行,所以this和super不能同时出现
。不论是否使用super调用来执行父类构造器的初始化代码,子类构造器总会调用父类构造器一次
。子类构造器调用父类构造器情况
。。子类构造器执行体的第一行使用super显示调用父类构造器,系统将根据super调用里传入的实参列表调用父类对应的构造器
。。子类构造器执行体的第一行使用this显示调用本类中的重载构造类,系统将根据this调用里传入的实参列表调用本类的另一个构造器。执行本类中另一个构造器时会调用父类构造器
。。子类构造器执行体既没有super调用,也没有this调用,系统将在执行子类构造器之前隐式调用父类无参数的构造器
。注
。。总之当调用子类构造器来初始化子类对象时,父类构造器总会在子类构造器之前执行
。。执行父类构造器时,系统会再次上溯执行其父类构造器。。。。。。以此类,创建任何Java对象,最先执行的总是java.lang.Objct类的构造器
。。例
*创建任何对象都是从该类所在继承树最顶层类的构造器开始(如此例中的Creature),然后依次向下执行直到本类
*若某个父类通过this调用同类中的重载构造器,则依次执行父类的多个构造器
* 创建java.lang.Object类构造器为默认的构造器,并没有任何显示输出,所以感受不到,但不代表没被调用