1.对象的多态性
- 多态性,是面相对象中最重要的概念.在java中的体现 : 对象的多态性 : 父类的引用指向子类的对象.
- 格式 : (父类类型 : 指子类继承父类的类型,或者实现的接口类型) 父类类型 变量名 =子类对象.
- 例 : Object o = new Person(),Object类型的变量o指向子类Person类型的对象.
- 在Java中,子类的对象可以替代父类的对象使用.所以,一个引用类型变量可能指向多个不同类型(子类类型)的变量
2.多态性的应用场景
- (虚方法的调用)在Java中,虚方法是在编译阶段不能确定方法的调用入口地址,在运行阶段才能确定的方法,即可能被重写的方法.Person p =new Man(),p.XXX().屏蔽了子类特有的属性和方法.
- 用父类做方法的形参,是多态使用最多的场合.即使增加了子类,方法也无需改变,提高了扩展性,符合开闭原则.
public class InsatnceText { public static void main(String[] args) { InsatnceText t = new InsatnceText(); t.method(new Person()); t.method(new Student()); t.method(new Graduate()); } public void method(Person e) { e.getInfo(); } 输出结果: a person a person a student a person a student a graduate public class Person { public Person() {} public void getInfo() { System.out.println("a person"); } } public class Graduate extends Person { public void getInfo() { System.out.println("a person"); System.out.println("a student"); System.out.println("a graduate"); } } public class Student extends Person { public void getInfo() { System.out.println("a person"); System.out.println("a student"); } }
- 在多态的场景下,调用方法时,(1).编译时,认为方法是左边声明的父类的类型的方法(即被重写的方法).(2).运行时,实际执行的是子类重写父类的方法.
- 即编译看左边,运行看右边.
3.使用前提和适用性
(1).使用前提 : 要有类的继承关系 ; 要有方法的重写.
(2).适用性 : 适用于方法,不适用于属性.
4.多态的好处和弊端
(1).好处 : 极大的减少的代码的冗余,不需要定义多个重载的方法.如方法形参里带父类的类型变量,实参传子类的对象.
(2).弊端 : 在多态的场景下,我们创建了子类的对象,也加载了子类特有的属性和方法,但由于声明为父类的引用,导致我们没有办法直接调用子类特有的属性和方法.(但可以通过向下转型)
5.向上转型
(1). class Animal{ public int i =1; public void eat() { System.out.println("Animal is.eating"); } } class Person extends Animal{ public int i =2; @Override public void eat() { System.out.println("Person is eating"); } public void sleep() { System.out.println("Person is sleeping"); } } class Cat extends Animal{ public int i =3; @Override public void eat() { System.out.println("Cat is eating"); } }
- Aminal a =new Person(); //父类的引用指向子类的对象.
- p只能调用父类声明的方法,而该方法通常被子类重写,故运行时实际上调用的是子类重写的方法.
- 由于编译类型为Animal,不能调用子类特有的方法,因为父类中并没有声明该方法,如果a.sleep(),编译器会报错.
- 通过new创造对象时父类的属性和方法,子类的属性和方法均被加载到内存中,如果将输出a.i的值,将输出1.同时体现了,方法才有多态性,而属性没有.
6.向下转型
- 如果我们确实需要调用子类特有的方法及属性,可以通过强制类型转换.
- 如果将输出p.i的值,将输出2.
Person p =(Person) a; //向下转型
此时编译类型为Person,可以调用子类特有的方法.p.sleep() //true
7.instanceof关键字
(1). (对象A) instanceof (类名B)
(2). A是否是B的实例,如果是,则返回true;否则,IDEA将产生异常.(if A为null,不会产生异常,只是返回false)
(3). 举例
Animal a =new Animal();
Person p =new Person();
Cat c =new Cat();
- a instanceof Object //true
- p instanceof Animal //true 人是动物
- c instanceof Animal //true cat是动物
- c instanceof Person //异常 cat不是人