Java 多态

目录

1.多态的基础语法

1.什么是多态?

2.多态的前提条件

3. 多态的类型转型

1.向上转型

 2.向下转型

3.向下转型经典异常报错 

4.使用instanceof操作符避免异常报错

2.多态在实际开发中作用思想指导【代码+详解】


1.多态的基础语法

1.什么是多态?

不同的子类在继承父类后分别都重写覆盖了父类的方法,即父类同一个方法,在继承的子类中表现出不同的形式。

2.多态的前提条件

  • 子类与父类有继承关系
  • 要有方法重写
  • 有父类引用指向子类对象

3. 多态的类型转型

1.向上转型

1.语法结构:

父类类型 引用名 = new 子类类型();
//右侧创建一个子类对象,把它转换为父类类型的对象,这是自动转换

2.注意:

  1. 编译类型看左边,运行类型看右边
  2. 可以调用父类的所有成员(需遵守访问权限)
  3. 不能调用子类的特有成员

结合代码理解上面的注意点

package 集成开发.多态;

 public class Animal {
    String abc;
    public void some(){
        System.out.println("动物在动");
    }
    public void fun(){
        System.out.println("动物们都很快乐");
    }
}

class Cat extends Animal{
     String df;
    public void some(){
        System.out.println("猫在走猫步");
    }
    public void move(){
        System.out.println("猫在抓老鼠");
    }
}

class Bird extends Animal{
    public void some(){
        System.out.println("鸟儿在飞");
    }
}

class text{
    public static void main(String[] args) {
        //编译类型看左边,运行类型看右边
        Animal am=new Cat();
        //编译时编译器只认识am变量是一个Animal类型,这里将Cat类型转换为Animal类型是自动转换
        am.some();
        /*你以为这里是"动物在动"?实际上这里返回的是"猫在走猫步",因为虽然在编译阶段am是一个Animal类型的引用
        但是在运行阶段因为am的底层其实是一个Cat类型的对象,所以调用的是Cat的some方法*/

        //可以调用父类的所有成员
        am.abc="123";
        am.fun();//动物们都很快乐

        //不能调用子类的特有成员
        am.move();
        //!报错,因为此时的am是Animal对象,move方法是Cat类独有的方法,且Animal类没有move方法
    }
}

 2.向下转型

1.语法格式:

子类类型 引用名 = (子类类型) 父类引用;
//用强制类型转换的格式,将父类引用类型转为子类引用类型

2.注意

  1. 只有向上转型后的才可以向下转型
  2. 向下转型容易出现Exception in thread "main" java.lang.ClassCastException异常报错【编译没有出错,但是运行会报错】
  3. 向下转型多用于需要访问子类的独有方法时候才向下转型

结合代码理解上面的注意点

package 集成开发.多态;

 public class Animal {
    String abc;
    public void some(){
        System.out.println("动物在动");
    }
    public void fun(){
        System.out.println("动物们都很快乐");
    }
}

class Cat extends Animal{
     String df;
    public void some(){
        System.out.println("猫在走猫步");
    }
    public void move(){
        System.out.println("猫在抓老鼠");
    }
}

class text{
    public static void main(String[] args) {
     //只有向上转型后的子类才可以向下转型
     Animal am=new Cat();
     Cat cat=(Cat)am;
     //move是cat的独有方法
     cat.move();//猫在抓老鼠

     //这里没有先向上转型,直接向下转型。编译阶段不会报错,运行阶段这里报错Exception in thread "main" java.lang.ClassCastException  
     Cat cat2=(Cat)new Animal();
    }
}

3.向下转型经典异常报错 

package 集成开发.多态;

 public class Animal {
    public void some(){
        System.out.println("动物在动");
    }
}

class Cat extends Animal{
    public void some(){
        System.out.println("猫在走猫步");
    }
    public void move(){
        System.out.println("猫在抓老鼠");
    }
}

class Bird extends Animal{
     public void some(){
         System.out.println("鸟在飞");
     }
}
class text{
    public static void main(String[] args) {
     Animal am=new Bird();
     Cat cat=(Cat)am;//编译不会报错,运行报错Exception in thread "main" java.lang.ClassCastException
    }
}

4.使用instanceof操作符避免异常报错

1.instanceof的语法格式

语法格式:
        引用 instanceof 数据类型

返回值:
        true: 代表这个引用指向的对象是这个数据类型
        false:代表这个引用指向的对象是这个数据类型

例如:
        a instanceof String;
        如果返回真表示a是一个String类型对象
        如果返回假表示a不是一个String类型对象

2.实例演示

package 集成开发.多态;

 public class Animal {
    public void some(){
        System.out.println("动物在动");
    }
}

class Cat extends Animal{
    public void some(){
        System.out.println("猫在走猫步");
    }
    public void move(){
        System.out.println("猫在抓老鼠");
    }
}

class Bird extends Animal{
     public void some(){
         System.out.println("鸟在飞");
     }
}
class text{
    public static void main(String[] args) {
        Animal am=new Cat();
        if(am instanceof Cat){
            Cat cat=(Cat)am;
            cat.some();
        }else{
            Bird bi=(Bird) am;
            bi.some();
        }
        //输出结果为:猫在走猫步
    }
}

2.多态在实际开发中作用思想指导【代码+详解】

首先我们来假设一个场景,主人投食宠物,宠物接受投食吃东西,在不看下面代码之前,尝试自己写一下这个程序

public class Text {
    public static void main(String[] args) {
        //创建主人对象
        zhuRen ren=new zhuRen();
        //创建小狗对象
        dog dg=new dog();
        //主人对小狗投食,小狗吃骨头
        ren.feed(dg);//小狗正在啃骨头
    }

}

class zhuRen{
    public void feed(dog d){
        d.eat();
    }
}

class dog{
   public void eat(){
       System.out.println("小狗正在啃骨头");
   }
}

此时我们又养了养了一只猫,这只猫主人也可以对它进行投食,猫也可以接受投食吃东西,显然为了满足这个需求,我们需要对上面主人的feed方法进行重载,通过传入不同的宠物类型,给不同的宠物投食

package 集成开发;

public class Text {
    public static void main(String[] args) {
        //创建主人对象
        zhuRen ren=new zhuRen();
        //创建小狗对象
        dog dg=new dog();
        //主人对小狗投食,小狗吃骨头
        ren.feed(dg);

        //创建小猫对象
        Cat cat=new Cat();
        //小猫接受投食吃鱼
        ren.feed(cat);//小猫正在吃鱼
    }

}

class zhuRen{
    public void feed(dog d){
        d.eat();
    }

    //对feed方法针对cat进行重载
    public void feed(Cat cat){
        cat.eat();
    }
}

class dog{
   public void eat(){
       System.out.println("小狗正在啃骨头");
   }
}

class Cat{
    public void eat(){
        System.out.println("小猫正在吃鱼");
    }
}

试想以下,如果我们后面养了越来越多的宠物,那么每增加一个宠物就要对主人的feed投食方法进行重载,每次都要更改我们的主程序,这样的作法导致我们的主程序的包容性非常的差,如果主程序中有大量的代码和复杂的逻辑关系,那么每进行一次增加就意味着主程序要进行新的测试,这样势必会增加软件的开发成本,那么我们下面采用Java的多态机制对上面的代码进行优化,创建一个新的Pet类,所有的宠物都继承它,将主人的feed方法面向这个Pet类型的对象,每增加一个新的宠物,将这个宠物强制转换成Pet类型,然后不同的宠物调用实际上是自己底层的eat方法

package 集成开发;

public class Text {
    public static void main(String[] args) {
        //创建主人对象
        zhuRen ren=new zhuRen();
        //创建小狗、小猫对象,然后向上转型成Pet类型
        dog dg=new dog();
        Pet dog=dg;
        Cat ct=new Cat();
        Pet cat=ct;

        //然后主人投食
        ren.feed(dog);//小狗正在啃骨头
        ren.feed(cat);//小猫正在吃鱼
        
注释:我们定义了一个新的宠物类Pet,主人在调用投食feed的时候面向的对象是Pet类型,把所有
的猫、狗等动物都继承Pet类型,然后向上转型都转换成Pet类型,当我们主人在调用feed()方法时候,
如果向里面传入的是cat的向上转型,那么底层任然是cat类型,如果传入的是dog的向上转型,
那么底层任然是dog类型,他们任然会调用自己的eat方法


    }

}


class zhuRen{
    public void feed(Pet d){
        d.eat();
    }

}

class Pet{
    public void eat(){

    }
}
class dog extends Pet{
   public void eat(){
       System.out.println("小狗正在啃骨头");
   }
}

class Cat extends Pet{
    public void eat(){
        System.out.println("小猫正在吃鱼");
    }
}

  • 6
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值