之前在java的基础总结里提到过多态,没有详细分析,现在来好好分析一下java的面向对象三大特征之一------多态
多态性
多态可以干什么:利用多态可以得到良好的设计
在java中,多态的核心表现在两个方面:
- 方法的多态性
- 方法重载:同一个类中,定义方法名相同,参数类型或参数个数不同的方法,对访问权限没有限制,基于良好的设计,方法返回值类型最好相同。
- 方法覆写:在继承关系中,子类定义方法名称,参数返回值类型,参数类型和个数完全一致的方法,且子类中的方法的访问权限不能比父类中的更严格。在调用被覆写过的方法时,默认调用的是子类中覆写了的方法。
- 对象的多态性(前提:方法覆写)
- 对象的向上转型 :父类 父类对象 = 子类实例。
子类实例化出一个对象,此时该对象可以调用子类本身里所有的方法,而当子类对象向上转型后,转型成的父类对象就可以调用父类中的方法,但是不能再调用子类中的方法,除非该方法被子类覆写了,则调用的是子类中已覆写了的方法,至于子类中的其他方法已经无法调用。
- 对象的向下转型 :子类 子类对象 =(子类)父类实例。(强制转换)用instanceof关键字判断;
一般在子类需要扩充操作的时候才会向下转型。想要发生向下转型,必须先发生向上转型,否则会出现ClassCastException异常。
在发生了向上转型后,如果此时又想调用子类中的方法,而子类中的方法并不是覆写父类中的,则向上转型后的对象是不能调用的,所以要想调用只能将对象转型回来,因此会产生向下转型,由此也可以看出,没有关系的类对象是无法发生转型的,而向下转型也是因为向上转型后又有某些需求才会发生,所以向下转型很少见。
因为向下转型必须是有关系的两个类对象,没有关系的类对象转型会产生异常,所以在转型之前需要判断一下,利用instanceof关键字来判断:子类对象 instanceof 类,返回boolean类型
if (per instanceof Student)
多态的核心在于方法的覆写,对象的向上转型可以实现接收参数的统一,对象的向下转型可以实现对象子类扩充方法的调用,两个没有关系的类对象是不能进行转型的,一定会产生ClassCastException异常。
//能编译能执行
Person person = new Student("张三",true);//向上转换
Student student = (Student) person;//向下转换
//能编译,不能执行,CCE异常
Person p2 = new Person("李四",false);//定义一个对象
Student student = (Student)p2;//向下转换
上面提到了方法的覆写,这里面关系到继承关系,这里再连带一下知识点:
继承
继承关键字:extends
书写方式: class 子类(派生类)名称 extends 父类(超类)名称
java是单继承,只能有一个父类;
父类被final修饰就不能继承;
如果父类无默认构造方法,子类必须提供有参数的构造方法;
子类无参数构造方法调用时,有隐式的super();
子类无参构造方法调用:
class Student (){
super();//隐式调用
}
当父类没有默认构造方法,子类调用构造方法:
class Student(String name,boolen args){
super(name, arfs);//子类提供有参数构造方法,super必须有参数,参数在父类中得被定义过
}
子类能继承父类的所有结构(所有内部属性),但是不能访问父类的私有属性(子类可以访问自己的私有属性),想要访问必须有权限,就要使用getter或setter
覆写
子类定义了与父类相同的方法或属性
方法的覆写:
覆写在继承关系中,子类定义了与父类方法名称,参数类型和个数相同的方法,但是如果父类是私有的,那么子类就不能覆写(子类也可以public定义一个方法,但是此方法不是覆写,而是属于子类自己的方法);
如果父类访问权限是公开的,子类权限不能就私有。(子类访问权限必须大于等于父类访问权限);父类方法被final修饰就不能覆写;
子类返回类型最好与父类相同;
当子类覆写了父类的方法,表明子类放弃了父类的继承权,如果要覆写还要调用父类方法,要用super,不能用this,用this调用的是子类:
public void infor(){
super.infor(参数列表);//调用了父类的infor()方法
子类方法;
}
属性也是可以覆写的,但是用到的不多,就不赘述了;