zoukankan      html  css  js  c++  java
  • Java从零开始学十六(多态)

    一、什么是多态

    多态性是指允许不同类的对象对同一消息作出响应.多态性包括参数化多态性和包含多态性.多态性语言具有灵活、抽象、行为共享、代码共享的优势,很好的解决了应用程序函数同名问题.
    多态有两种表现形式:重载和覆盖
    首先说重载(overload),是发生在同一类中.与什么父类子类、继承毫无关系.
    标识一个函数除了函数名外,还有函数的参数(个数和类型).也就是说,一个类中可以有两个或更多的函数,叫同一个名字而他们的参数不同.
    他们之间毫无关系,是不同的函数,只是可能他们的功能类似,所以才命名一样,增加可读性,仅此而已!
    再说覆盖(override),是发生在子类中!也就是说必须有继承的情况下才有覆盖发生.
    我们知道继承一个类,也就有了父类了全部方法,如果你感到哪个方法不爽,功能要变,那就把那个函数在子类中重新实现一遍.
    这样再调用这个方法的时候,就是执行子类中的过程了.父类中的函数就被覆盖了.(当然,覆盖的时候函数名和参数要和父类中完全一样,不然你的方法对父类中的方法就不起任何作用,因为两者是两个函数,毫不关系)

    二、简单实现

    package com.pb.demo6;
    
    public abstract class Pet {
       private String name;  //宠物名字
       private String sex;    //宠物性别
       private int health;        //宠物的健康值
       
       //宠物看病的方法
       abstract void toHospital();
    
    public String getName() {
        return name;
    }
    
    public void setName(String name) {
        this.name = name;
    }
    
    public String getSex() {
        return sex;
    }
    
    public void setSex(String sex) {
        this.sex = sex;
    }
    
    public int getHealth() {
        return health;
    }
    
    public void setHealth(int health) {
        this.health = health;
    }
       
    }
    package com.pb.demo6;
    /*
     * 小狗类
     */
    public class Dog extends Pet {
    
        @Override
        void toHospital() {
            //小狗看病的方法
            System.out.println("小狗看病:打针、吃药!");
    
        }
    
    }
    
    package com.pb.demo6;
    /*
     * 小猪类
     */
    public class Pig extends Pet {
    
        @Override
        void toHospital() {
            System.out.println("小猪看病:打针、睡觉!");
    
        }
    
    }
    package com.pb.demo6;
    /*
     * 小鸟类
     */
    public class Bird extends Pet {
    
        @Override
        void toHospital() {
            //小鸟看病的方法
            System.out.println("小鸟看病:吃药、休息!");
    
        }
    
    }
    package com.pb.demo6;
    /*
     * 宠物医生类
     */
    public class Doctor {
        
        //医生治疗方法
        public void cure(Pet pet){ //将宠物传参
            
            if(pet.getHealth()<50){ //判断健康值小于50
                //调用看病的方法
                pet.toHospital();
                //将健康值设置为60,健康
                pet.setHealth(60);
            }
        }
    
    }

    测试类

    package com.pb.demo6;
    /*
     * 测试类
     */
    public class Test {
    
        public static void main(String[] args) {
            //声明医生对象
            Doctor dc=new Doctor();
            //声明宠物对象为小鸟
           Pet brid=new Bird();
           //调用医生的治疗方法
           dc.cure(brid);
         //声明宠物对象为小狗
           Pet dog=new Dog();
         //调用医生的治疗方法
           dc.cure(dog);
         //声明宠物对象为小猪
           Pet pig=new Pig();
         //调用医生的治疗方法
           dc.cure(pig);
           
        }
    
    }

    结果:

    小鸟看病:吃药、休息!
    小狗看病:打针、吃药!
    小猪看病:打针、睡觉!

    三、对象的多态性

     对象的多态性主要分为以下两种类型:
    向上转型和向下转型

    3.1 对象向上转型:

    父类 父类对象 = 子类实例 ;
    向上转型:子类对象 ->父类对象
    对于向上转型,程序会自动完成,格式:
    如上面的:
     //声明宠物对象为小鸟
           Pet brid=new Bird();
    //声明宠物对象为小狗
           Pet dog=new Dog();
     //声明宠物对象为小猪
           Pet pig=new Pig();

    编译时类型为:Pet,而运行时类型为具体的类型

    也就是说编译时类型由声明该变量时使用类型决定,而运行时类型由实际赋给该变量的对象决定

    3.2 对象向下转型:

    向下转型:父类对象 ->子类对象
    对于向下转型时,必须明确的指明要转型的子类类型,格式:
    子类 子类对象 = (子类)父类实例 ;强制类型转换
     
     上面的例中,子类没有自己的方法,如果子类有自己的方法,医生类中还能调用吗?显然不能,因为是向上转为父类后,只能调用父类的方法,如果要调用子类的方法就需要用到向下转型要用到instannceof

    四、instanceof 关键字

    在java中可以使用instanceof关键字判断一个对象到底是那个类的实例
    对象 instanceof 类   ->返回boolean类型
    package com.pb.demo6;
    
    public abstract class Pet {
       private String name;  //宠物名字
       private String sex;    //宠物性别
       private int health;        //宠物的健康值
       
       //宠物看病的方法
       abstract void toHospital();
    
    public String getName() {
        return name;
    }
    
    public void setName(String name) {
        this.name = name;
    }
    
    public String getSex() {
        return sex;
    }
    
    public void setSex(String sex) {
        this.sex = sex;
    }
    
    public int getHealth() {
        return health;
    }
    
    public void setHealth(int health) {
        this.health = health;
    }
       
    }
    package com.pb.demo6;
    /*
     * 小鸟类
     */
    public class Bird extends Pet {
    
        @Override
        void toHospital() {
            //小鸟看病的方法
            System.out.println("小鸟看病:吃药、休息!");
    
        }
        public void fly(){
            System.out.println("小鸟会飞!");
        }
    
    }
    package com.pb.demo6;
    /*
     * 小狗类
     */
    public class Dog extends Pet {
    
        @Override
        void toHospital() {
            //小狗看病的方法
            System.out.println("小狗看病:打针、吃药!");
    
        }
        public void run(){
            System.out.println("小狗在地上跑!");
        }
        
    }
    package com.pb.demo6;
    /*
     * 小猪类
     */
    public class Pig extends Pet {
    
        @Override
        void toHospital() {
            System.out.println("小猪看病:打针、睡觉!");
    
        }
      public void sleep(){
          System.out.println("小猪要睡觉!");
      }
    }
    package com.pb.demo6;
    /*
     * 宠物医生类
     */
    public class Doctor {
        
        //医生治疗方法
        public void cure(Pet pet){ //将宠物传参
            
            if(pet.getHealth()<50){ //判断健康值小于50
                //调用看病的方法
                pet.toHospital();
                //将健康值设置为60,健康
                pet.setHealth(60);
                //判断是宠物类型
                if(pet instanceof Dog){
                    //向下转型,强制类型转制
                    Dog dog=(Dog)pet;
                    //调用小狗自己的方法
                    dog.run();
                }else if(pet instanceof Bird){
                    //向下转型,强制类型转制
                    Bird bird=(Bird)pet;
                    //调用小鸟自己的方法
                    bird.fly();
                }else if(pet instanceof Pig){
                    //向下转型,强制类型转制
                    Pig pig=(Pig)pet;
                    //调用小猪自己的方法
                    pig.sleep();
                }
            }
        }
    
    }
    package com.pb.demo6;
    /*
     * 测试类
     */
    public class Test {
    
        public static void main(String[] args) {
            //声明医生对象
            Doctor dc=new Doctor();
            //声明宠物对象为小鸟
           Pet brid=new Bird();
           //调用医生的治疗方法
           dc.cure(brid);
         //声明宠物对象为小狗
           Pet dog=new Dog();
         //调用医生的治疗方法
           dc.cure(dog);
         //声明宠物对象为小猪
           Pet pig=new Pig();
         //调用医生的治疗方法
           dc.cure(pig);
           
        }
    
    }

    结果:

    小鸟看病:吃药、休息!
    小鸟会飞!
    小狗看病:打针、吃药!
    小狗在地上跑!
    小猪看病:打针、睡觉!
    小猪要睡觉!

     五、父类做为形参

    package com.pb.demo2;
    /*
     * 商品类
     */
    public class Goods {
        //打印商品价格方法
        public void printPrice(){
            System.out.println("打印商品价格");
        }
    }
    
    package com.pb.demo2;
    /*
     * 食品类
     */
    public class Foods extends Goods {
    
        @Override
        public void printPrice() {
            System.out.println("打印食品类的商品价格!");
        }
    
        
    }
    package com.pb.demo2;
    /*
     * 电视类
     */
    public class TVs extends Goods {
    
        @Override
        public void printPrice() {
        System.out.println("打印电视类商品价格!");
        }
    
        
    }

    测试类:

    package com.pb.demo2;
    
    public class Test {
    
        public static void main(String[] args) {
            //声明3 个商品价格
            Goods good=new Goods();
            Foods food=new Foods();
            TVs tvs=new TVs();
            //调用方法
            showPrice(good);
            showPrice(food);
            showPrice(tvs);
    
        }
        //显示商品价格方法
      static void showPrice(Goods good){
          good.printPrice();
      }
    }

    结果:

    打印商品价格
    打印食品类的商品价格!
    打印电视类商品价格!
  • 相关阅读:
    关于线程池的线程复用
    Java线程锁之意难平的读写锁
    Java8之StringJoiner
    springboot整合thymeleaf
    一维数组转二叉树、注解回滚、eclipse配置代码自动补全
    Java之线程锁
    关于工作中的一些总结
    关于shiro的猜测
    Java之扫描不到mapper
    网页中引用css样式
  • 原文地址:https://www.cnblogs.com/liunanjava/p/4295810.html
Copyright © 2011-2022 走看看