Javaday09(继承、多态)
一、继承
1.继承的意义
面向对象设计中的继承,是代码重用,能够大大提高开发效率。
继承是利用现有类来创建新类的过程,现有的类叫做父类(基类),新创建的类叫做子类(派生类)。
继承就是子类继承父类的特征和行为,使得子类对象具有和父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。
基本用法:
【访问权限修饰符】【修饰符】子类名 extends 父类名{子类体}
Java是单继承体系,子类只能继承一个父类。
子类拥有父类的属性和方法,(private成员由于权限关系因此不能访问)
子类可以拥有自己属性和方法,即子类可以对父类进行拓展。
子类可以用自己的方式来实现父类的方法(方法重写)。
子类继承不了父类的构造方法,构造方法只能调用不能继承。
当子类创建对象时,调用子类的构造方法时,会自动调用父类的无参构造方法。
当父类中只有private的构造方法时,子类创建对象时无法访问到父类的构造方法,所以无法创建子类对象。
2.super
子类构造器中可以使用super来调用父类的构造函数。
当父类中没有无参构造时,可以在子类构造器中使用super来调用父类的有参构造函数。
注意!!:this可以作为当前类对象的引用当做参数传递,但是super不可以!!
1 class Father{
2 public Father(int a){ }
3 }
4
5 class Son{
6 public Son(){ // 如果不适用super来调用有参构造的话,由于父类中没有默认的无参构造函数,所以会无法调用子类的构造方法来创建子类对象。
7 super(1);
8 }
9 }
3.方法重写
子类中有一个方法与父类中的返回值类型、方法名、参数列表都一样,重写方法体,称为方法的覆盖或者重写。
方法重写:两个方法的方法名、参数列表必须一致、如果返回值类型是基本数据类型,则返回值应该保持一致,如果返回值是类,则子类覆盖方法的返回值类型必须是父类方法返回值或其的子类(协变返回类型)。
子类异常不能大于父类异常。
子类方法的访问级别不能低于父类访问的级别。
注意!!:方法的重载:在同一个类中,方法名相同,参数列表不同,返回值类型可以不同。
1 public void eat(Dog dog){
2 System.out.print("dog的吃方法");
3 }
4
5 public void eat(Cat cat){
6 System.out.print("cat的吃方法");
7 }
二、多态(不同类对象对同一消息作响应)
多态性指的是允许不同类的对象对同一信息做出响应。
多态性语言具有灵活、抽象、行为共享、代码共享的优势。
1. 向上造型:父类引用(栈中)指向子类对象(堆中),在对象造型时,声明引用的父类类型,我们称之为编译器类型,而实际用于构建对象的子类类型我们称之为运行期类型。
Father father = new Son(); // Father是父类 father是父类引用名 new Son是创建子类对象 父类引用——>子类对象
编译器类型 运行期类型
如果现在使用father使用属性或者方法:
1.当子类对象存放到父类引用中,调用属性获取的是父类的属性。
2.当子类对象存放到父类引用中,调用方法获取的是子类的属性。
3.当子类对象存放到父类引用中,父类引用只能调用父类中的方法,不能调用子类有而父类中没有的方法。
4.无论子类对象存放到哪个引用中,对象的类型不变。
5.当子类对象存放到父类引用中,调用静态属性或者方法使用的是父类的静态属性或方法。
2. 向下造型:对象满足条件的情况下,可以进行向下造型。
要求:进行向下造型的对象的运行期类型必须是子类或者是以子类为根的继承树中的其他类型。
Father father = new Son(); // 子类引用指向父类引用 这是father引用里存放着子类对象的地址 所以可以满足向下造型的条件
Son son = (Son)father;
多态环境下对属性和方法的调用特点
静态绑定发生在编译期,动态绑定发生在运行时。
类的成员变量(属性)都是静态绑定的(编译时),也就是说,类中声明的成员变量不能被子类中的同名属性覆盖,通过该类的引用调用成员,始终调用该类自身中声明的属性(即始终调用编译期类型中的属性)
对于Java中的方法而言,除了final(后续详细介绍),static(后续详细介绍),private和构造方法是静态绑定外,其他的方法全部为动态绑定
这就意味着方法调用将动态使用运行期类型版本)
-
- 由上述特点可以看出:
- 重载方法中具体调用哪个版本是通过静态绑定在编译期就决定了的
- 重写覆盖的方法调用哪个版本是通过动态绑定在运行期决定的
- 由上述特点可以看出:
多态的使用
方法的参数类型声明为父类类型,调用方法代码前会隐式执行形参和实参之间的复制操作。由于子类对象赋值给父类的引用是合法的,那么调用方法时,实参就可以看做是以形参类型为根的继承树中的任意类型。
此时形参对应的运行期类型和传进来的实参运行期类型保持一致
返回值引用:
三、Instanceof
可以使用instanceof来判断类型,语法:
对象 instanceof 类
会返回一个boolean值 如果为true则属于这个类型 如果返回false则不属于这个类型