11-多态
多态
面向对象的三大特性——封装、继承、多态。
多态指的就是同一个行为具有多个不同的表现形式或者形态的能力。
多态体现在类与类的继承和类与接口的实现之间。
1、Java中的向上转型和向下转型
向上转型:使用父类或者接口来定义变量存储子类或者实现类的对象
向下转型:将父类型的引用变量转换成子类或者实现类的类型
package k多态;
//父类
public class Animal {
public void eat(){
System.out.println("动物吃东西!");
}
}
package k多态;
//子类1
public class Cat extends Animal {
//重写
public void eat(){
System.out.println("猫吃鱼!");
}
//成员方法
public void move(){
System.out.println("猫走猫步!");
}
}
package k多态;
//子类2
public class Dog extends Animal{
//重写
public void eat(){
System.out.println("狗啃骨头!");
}
}
/*
* 关于java语言中的向上转型和向下转型
* 1.向上转型(upcasting):子--->父
* 2.向下转型(downcasting):父--->子
*
* 注意:无论是向上转型还是向下转型,两个类之间必须要有继承关系。
*/
package k多态;
public class Test01 {
public static void main(String[] args){
//向上转型又称:自动类型转换
//父类型的引用指向子类型的对象
//程序分两个阶段:编译阶段 和 运行阶段
//下面程序编译阶段只知道a1是一个Animal类型
//而在运行的时候堆中的实际对象是Cat类型的
Animal a1 = new Cat();
//程序在编译阶段a1被编译器看作Animal类型
//所以程序在编译阶段a1引用绑定的是Animal类中的eat方法 (静态绑定)
//但是程序在运行阶段堆中的对象实际上是Cat类型,而Cat已经重写了eat方法
//因而程序在运行时对象绑定的方法是Cat类中的eat方法 (动态绑定)
a1.eat();//猫吃鱼!
//向下转型:强制类型转换
Animal a2 = new Cat();
//要执行Cat类中自有的成员方法move,怎么做?
//只能强制类型转换,需加强制类型转换符
Cat c1= (Cat)a2;
c1.move();//猫走猫步!
//判断以下程序运行有什么问题
Animal a3 =new Dog();//向上转型
//强制类型转换
//Cat c2 = (Cat)a3;//报错java.lang.ClassException
//在做强制类型 转换的时候程序是存在风险的
//为了避免ClassException的发生,java引入了 instanceof
/*
* 用法:
* 1.instanceof运算符的运算结果是boolean类型
* 2.(引用 instanceof 类型) -->true/false
*
* 例如:(a instanceof Cat) 如果结果是true,表示 a引用指向堆中的java对象是Cat类型的
*/
Animal a4 = new Dog();
//在做向下转型的时候要用instanceof运算符判断,避免ClassException
if (a4 instanceof Cat){
Cat c2 = (Cat)a4;
}else {
System.out.println(a4 instanceof Cat);
}
}
}
2、多态的好处
package l多态的好处;
public class Animal {
public void eat(){
}
public static void name() {
System.out.println("调用静态方法");
}
}
/*
* 宠物
*/
package l多态的好处;
public class Cat extends Animal{
public void eat(){
System.out.println("主人在喂猫");
}
}
/*
* 宠物
*/
package l多态的好处;
public class Dog extends Animal{
public void eat(){
System.out.println("主人在喂狗");
}
public static void name() {
System.out.println("能否覆盖静态方法");
}
}
/*
* 模拟主人
*/
package l多态的好处;
public class Person {
/*
//喂养
public void feed(Dog d){
d.eat();
}
//因为用户的业务改变了所以软件要升级
public void feed(Cat c){
c.eat();
}
//以上代码得出:person类型的扩展能力太差
*
*/
//尽量不要面向具体编程,要面向父类编程,面向抽象编程
public void feed(Animal a){//也就说只要是继承了Animal类的都可以往这传,Animal a就相当于包括
a.eat(); //上面的Dog d 和Cat c,有多少子类就包括
} //测试调用方法中的参数写子类型的引用,不写父类型的引用a
public void test(Animal b){
b.name();
}
}
/*
* 多态的好处:
* 1.使用多态可以使代码与代码之间的耦合度降低
* 2.项目的扩展能力增强
*/
package l多态的好处;
public class Test01 {
public static void main(String[] args){
//创建主人
Person milen = new Person();
//创建宠物
Dog d = new Dog();
Cat c = new Cat();
//喂
milen.feed(d);//此时调用Animal a = d;
milen.feed(c);//此时调用Animal a = c;
d.name();//子类中的name方法
milen.test(d);//父类中的静态方法
//所以在方法覆盖中静态方法不建议重写,因为多态的好处项目代码多数使用多态,此间不调用子类的静态方法,重写了也没有意义
//而且静态方法写在工具类中
}
}