7.0、Java继承与多态 - 多态的特性
面向对象的三大特征:封装性、继承性、多态性;
extends继承 或者 implements实现,是多态性的前提;
用学生类创建一个对象 - 小明,他是一个 学生(学生形态),但同时也是一个 人(人类形态)
小明是一个对象;这个对象既有 学生形态 也有 人类形态,一个对象拥有多种形态,这就是对象的多态性
代码中体现多态性,其实就是一句话 -> 父类引用指向子类对象;下面用代码给大家示范一下:
创建 People.java 类,如下所示 ->
public class People {
int num = 6;
public void eat() {
System.out.println("人类吃饭");
}
}
创建 Students.java 类,并让其继承 People 类,然后重写 eat() 方法,如下所示->
public class Students extends People {
int num = 9;
@Override
public void eat() {
System.out.println("学生吃饭");
}
}
创建 Main.java 类,如下所示 ->
public class Main {
public static void main(String[] args) {
//使用多态的写法
//左侧父类的引用,指向了右侧子类的对象
People people = new Students();
people.eat();//这里调用成员方法,看等号右边是谁就有先调用谁
System.out.println(people.num);//这里调用成员变量,看等号左边是谁就有先调用谁,所以输出的是 6
}
}
People people = new Students;people.eat(); -> 这里显然会调用 Students 中的 eat() 方法;因为 new 出来的是 Students 对象( 就是调用成员方法时 等号右边是谁就优先调用谁的方法 );
而下面的 System.out.println(people.num);调用的是成员变量,那么看的就是 等号左边 是谁就优先调用谁,显然调用的是 People 中的 num = 6;
当我们通过成员方法去访问成员变量时,访问的该成员方法属于哪个类,访问的成员变量就是哪个类的;
在访问 成员方法 的时候有一个口诀:编译看左边,运行看右边 -> 具体情况看下面代码实例:
创建父类 Fu.java 文件,如下所示 ->
public class Fu {
public void eat() {
System.out.println("父类吃东西");
}
public void fuMethod() {
System.out.println("执行fuMethod方法");
}
}
创建 Zi.java 文件,并让其继承 Fu 类,如下所示 ->
public class Zi extends Fu{
@Override
public void eat() {
System.out.println("子类吃东西");
}
public void ziMethod() {
System.out.println("执行ziMethod方法");
}
}
创建 Main.java 文件,如下所示 ->
public class Main {
public static void main(String[] args) {
Fu fu = new Zi();
fu.eat();//编译通过在Fu类中有eat()方法但是运行时看右边Zi类,所以执行的是Zi类中的eat()方法
fu.fuMethod();//编译通过在Fu类中有fuMethod()方法但是运行时看右边Zi类,但是Zi类中没有fuMethod()方法,所以向上找到父类中的fuMethod()方法执行
fu.ziMethod();//编译不通过,左边是Fu 但是在Fu类中并没有ziMethod()这个方法所以编译不通过
}
}
fu.eat();
编译通过在 Fu 类中有 eat() 方法但是运行时看右边 Zi 类,所以执行的是 Zi 类中的 eat() 方法;
fu.fuMethod();
编译通过在 Fu 类中有 fuMethod() 方法但是运行时看右边 Zi 类,但是 Zi 类中没有 fuMethod() 方法,所以向上找到父类中的 fuMethod() 方法执行;
fu.ziMethod();
编译不通过,左边是 Fu 但是在 Fu 类中并没有 ziMethod() 这个方法所以编译不通过;
注意一下:
该口诀针对的是 成员方法;不是 成员变量,访问 成员变量 的时候 [ 编译看左边,运行看右边 ] 的口诀不适用;访问成员变量的时候口诀应该变成是 -> [ 编译看左边,运行还是看左边 ];
那么多态在代码中的运用到底有什么作用呢?
下面给大家稍作解释 ->