继承
本章目标:
1.继承
1.1 什么是继承?
1.2 为什么要继承?
1.3 如何使用继承操作?
1.4 父类中哪些是子类所不能继承的?
2.super
2.1 子类如何访问父类的属性和方法?
2.2 super的三种结构
2.3 super()的应用及注意事项
3.重写
3.1 什么是重写?
3.2 为什么要重写?
3.3 什么情况下才能重写?
3.4 如何重写?
4.挑战:掌握继承状态下父类、子类构造方法、static代码块、代码块的执行顺序

具体讲解:
1.继承
1.1.什么是继承?
(1)现实生活中的继承

现实生活中继承指的是对象与对象的继承关系。

(2)程序中的继承

继承是面向对象编程(OOP)的三大特征之一。

继承的概念:
继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的属性和方法,或子类从父类继承方法,使得子类具有父类相同的行为。

程序中的继承是指类与类之间的继承关系。
Java的继承通过extends关键字来实现,实现继承的类被称为子类,被继承的类称为父类(或叫基类、超类)。

继承关系的梳理:
父类和子类的关系是一种一般与特殊(is-a)的关系。
举例:水果(Fruits)和苹果(Apple)的关系
苹果继承了水果,苹果是水果的子类,则苹果是一种特殊的水果。

1.2.为什么需要继承?
(1)提高代码的重用性。
(2)优化代码,方便修改。
(3)类与类之间产生了关系,是多态的前提。

1.3.如何使用继承操作?
(1)继承的格式
通过 extends 关键字,可以声明一个子类继承另外一个父类,定义格式如下:

class 父类 {
 …
 }
 
 class 子类 extends 父类 {
 …
 }

继承演示代码如下:

//员工类
 class Employee{
 private String name; //姓名
 private int age; //年龄
 private double salary = 5000.0; //薪水
 public Employee(){}
 public Employee(String name, int age, double salary){
 this.name = name;
 this.age = age;
 this.salary = salary;
 }
 public double getSalary(){
 return salary;
 }
 }//经理类继承自员工类
 class Manager extends Employee{
 private double bonus; //奖金
 public void setBonus(double bonus){
 this.bonus = bonus;
 }
 }//测试类
 public class Test{
 public static void main(String[] args){
 Manager manager = new Manager();
 double sal = manager.getSalary();
 System.out.println(“继承的薪水为:” + sal);
 }
 }


1.4.父类中哪些是子类所不能继承的?
(1)私有化的,即用private修饰的成员变量和成员方法。
(2)构造方法。
(3)子类与父类不在同一个包中,父类使用默认访问权限的成员变量和成员方法。

1.5.继承的其他特点
(1)单继承
Java中只支持单继承,不支持多继承。
Java虽然不直接支持多继承,但是保留了这种多继承机制,进行改良。

为什么不支持多继承呢?
因为当一个类同时继承两个父类时,两个父类中有相同的方法,那么子类对象调用该方法时,运行哪一个呢?

(2)多重继承(继承体系)
Java支持多重继承,例如:
class A{}
class B extends A{}
class C extends B{}
多重继承的出现,就有了继承体系。体系中的顶层父类是通过不断向上抽取而来的。

(3)继承关系下,子类与父类的成员变量同名会有什么影响?
同名看实例化对象是哪个类就以哪个类中的成员变量值为准。
举例:如果new的是子类,则以子类中的值为准;
如果new的是父类,则以父类中的值为准。

(4)继承关系下,子类与父类的成员方法会有什么影响?
调用成员方法,先在子类中查找是否有该方法,有就执行,没有就去父类中查找执行。
父类中没有则直接报错。

2.super
2.1.子类如何访问父类的属性和方法?
(1)super.属性名
(2)super.方法名()
2.2.super的三种结构
(1)super.属性名
访问父类的属性: super.name;

(2)super.方法名()
访问父类的方法: super.print();

(3)super();
调用父类构造方法:super(name,age);
注意:该句只能出现在子类构造方法中的第一行。
2.3.super()的应用及注意事项
(1)super()出现在子类构造方法,表示调用父类的构造方法。
(2)如调用父类带参构造方法,则用:super(参数列表);
(3)super()只能出现在子类构造方法中的第一行。
2.4.super与this

3.重写
注意:重写的前提是类之间具有继承关系。
3.1.什么是重写?
重写也称覆盖,是在继承关系下,子类对父类方法代码的修改。
举例:动物类(Animal)中的吃方法(eat),有些动物吃草,有些动物吃肉,都是吃的功能,但是动物不一样,实现的方式也不一样。
3.2.为什么要重写?
(1)父类已具有某个功能的方法,子类假如有相同功能的方法,使用重写的方式更加便利,不会造成子类既继承得到了父类的这个功能,又自己拥有一个同样的功能而方法名却不一样的尴尬境地。
(2)继承是多态的前提,重写方法也是为了多态的扩展性的。
3.3.什么情况下才能重写?
当子类跟父类拥有相同的功能,但是实现方式不同时,子类重写父类的方法即可。
3.4.如何重写?
方法的重写要遵循“两同两小一大”的原则:
两同:方法名和参数列表必须相同
两小:返回值类型、声明异常 比(被重写的)父类的小(或一样)
一大:访问修饰符比(被重写的)父类的大(或一样)

示例:

public class Father {
 public Father method(){
 return new Father();
 }
 }
 public class Sun extends Father {
 @Override
 public Sun method() { //两同:方法名和参数列表相同
 // TODO Auto-generated method stub
 return new Sun();
 }
 }

4.挑战:掌握继承状态下父类、子类构造方法、static代码块、代码块的执行顺序
执行顺序如下:
(1)父类的静态代码块
(2)子类的静态代码块
(3)父类的代码块
(4)父类的构造方法
(5)子类的代码块
(6)子类的构造方法

父类属性 > 父类构造方法 > 子类属性 > 子类构造方法