面向对象的特点:封装、继承和多态。
多态:同一行为,通过不同的事物,可以体现出来的不同的形态;同一个对象在不同的时刻表现出来的形态是不同的。
子类可以重写和实现父接口中的方法,最后调用实现的方法是子类重写后的方法。
多态的前提:
要有继承或实现关系
要有方法的重写
要由父类引用指向子类对象
多态的格式:
- 普通类多态的格式
父类 对象 = new 子类();
- 抽象类多态的格式
抽象类 对象名 = new 抽象类子类();
- 接口多态的格式
接口 对象名 = new 接口实现类();
多态中的成员访问特点:
1.成员变量
编译看左边(父类),运行看左边(父类)
2.成员方法
编译看左边(父类),运行看右边(子类)
代码演示:
publicclassAnimal { publicintage=40; publicvoideat() { System.out.println("动物吃东西"); } }
publicclassCatextendsAnimal { publicintage=20; publicintweight=10; //子类要重写父类中的方法publicvoideat() { System.out.println("猫吃鱼"); } publicvoidplayGame() { System.out.println("猫捉迷藏"); } }
publicclassAnimalDemo { publicstaticvoidmain(String[] args) { //有父类引用指向子类对象Animala=newCat(); //成员变量//编译看左边(父类),运行看左边(父类)System.out.println(a.age); // System.out.println(a.weight);//成员方法//编译看左边(父类),运行看右边(子类)a.eat(); // a.playGame(); } }
多态的好处和弊端:
1.多态的好处:
提高程序的扩展性。定义方法时候,使用父类型作为参数,在使用的时候,使用具体的子类型参与操作
2.多态的弊端:
不能使用子类的特有成员
多态中的转型:
当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误。也就是说,不能调用子类拥有,而父类没有的方法;所以,想要调用子类特有的方法,必须做向下转型。
向上转型:
多态本身是子类类型向父类类型向上转换的过程,这个过程是默认的。
父类类型 变量名 = new 子类类型();如:Animal a = new Cat();
向下转型:
父类类型转换为子类类型,这个过程是强制的;“子类调用自身定义的方法,就是向下转型!”
一个已经向上转型的子类对象,将父类引用转为子类引用,可以使用强制类型转换的格式,便是向下转型。
//子类类型 变量名 = (子类类型) 父类变量名; Cat c =(Cat) a;
abstractclassAnimal { abstractvoideat(); } classCatextendsAnimal { publicvoideat() { System.out.println("吃鱼"); } publicvoidcatchMouse() { System.out.println("抓老鼠"); } } classDogextendsAnimal { publicvoideat() { System.out.println("吃骨头"); } publicvoidwatchHouse() { System.out.println("看家"); } }
publicclassTest { publicstaticvoidmain(String[] args) { // 向上转型 fu f = new zi()Animala=newCat(); a.eat(); // 调用的是 Cat 的 eat// 向下转型 zi z = (zi)fu; Catc= (Cat)a; c.catchMouse(); // 调用的是 Cat 的 catchMouse } }
转型异常:
publicclassTest { publicstaticvoidmain(String[] args) { // 向上转型 Animala=newCat(); a.eat(); // 调用的是 Cat 的 eat// 向下转型 Catc= (Cat)a; c.catchMouse();//调用自己的方法System.out.println("================"); // 向下转型 Dogd= (Dog)a; //引用的父类,是多态cat类,并不是dogd.watchHouse(); // 调用的是 Dog 的 watchHouse 【运行报错】 } }
这段代码可以通过编译,但是运行时,却报出了ClassCastException类型转换异常!这是因为,明明创建了Cat类型对象,运行时,当然不能转换成Dog对象的。这两个类型并没有任何继承关系,不符合类型转换的定义。
为了避免ClassCastException的发生,Java提供了instanceof关键字,给引用变量做类型的校验,格式如下:
instanceof使用格式
变量名 instanceof 数据类型
如果变量属于该数据类型,返回true。
如果变量不属于该数据类型,返回false。
代码展示:
publicclassTest { publicstaticvoidmain(String[] args) { // 向上转型 Animala=newCat(); a.eat(); // 调用的是 Cat 的 eat// 向下转型 if (ainstanceofCat){ Catc= (Cat)a; c.catchMouse(); // 调用的是 Cat 的 catchMouse } elseif (ainstanceofDog){ Dogd= (Dog)a; d.watchHouse(); // 调用的是 Dog 的 watchHouse } } }