zoukankan      html  css  js  c++  java
  • Java——多态

    》什么是多态

      简单来说,多态(Polymorphism)是具有表现多种形态能力的特征。更专业的说法:同一个实现接口,使用不同的实例而执行不同操作。

       多态的定义:值允许不同的类的对象对同一消息做出响应,就是同一消息可以根据发送对象的不同采取不同的行为方式。

    多态存在的三个必要条件:

      》要有继承

      》要有重写

      》父类引用指向子类对象

    》举例说明

    》父类
    public abstract class Pet {
    
        protected String name="无名氏";
        protected int heagth=100;    //健康值 
        protected int love=0;        //亲密度
        public Pet(String name) {
            this.name = name;
        }
        /**
         * 输出宠物信息
         */
        public void print(){
            System.out.println("宠物的自白:
    我的名字叫"+this.name+",健康值是"+this.heagth+",和主人的亲密度是"+this.love+"");
        }
        
        /**
         * 抽象方法eat(),负责宠物吃饭功能
         */
        public abstract void eat();
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public int getHeagth() {
            return heagth;
        }
        public void setHeagth(int heagth) {
            this.heagth = heagth;
        }
        public int getLove() {
            return love;
        }
        public void setLove(int love) {
            this.love = love;
        }

    》子类

    public class Dog extends Pet{
        
        
         {
            System.out.println("我是子类");
        }
    
        private String strain;  //品种
        
        public Dog(String name,String strain) {
            super(name);
            this.strain=strain;
        }
    
        /**
         * 实现狗狗的吃饭方法
         */
        @Override
        public void eat() {
            super.heagth+=3;
            System.out.println("狗狗"+super.name+"吃饱啦!健康值增加3。");
        }
    
        /**
         * 重写父类print()方法
         */
        public void print(){
            super.print();
            System.out.println("我是一只"+this.strain+"");
        }
        
        
        public void catchingFlyDisc(){
            System.out.println("狗狗在玩飞盘");
        }
    }
    public class Penguin extends Pet {
    
        private String sex;
        public Penguin(String name,String sex) {
            super(name);
            this.sex=sex;
        }
    
        /**
         * 重写父类方法
         */
        public void print(){
            super.print();
            System.out.println("性别是"+this.sex+"");
        }
        /**
         * 实现企鹅吃饭的方法
         */
        @Override
        public void eat() {
            super.heagth +=5;
            System.out.println("企鹅"+super.name+"吃饱啦!健康值增加5。");
    
        }
        
        
        public void swimming(){
            System.out.println("企鹅在游泳");
        }
    
        public String getSex() {
            return sex;
        }
    
        public void setSex(String sex) {
            this.sex = sex;
        }
    
    }

    》主人类

    public class Master {
    
        private String name;   //主人名字
        private int money;     //元宝数
        public Master(String name, int money) {
            this.name = name;
            this.money = money;
        }
        
        /**
         * 使用父类作文方法参实现多态
         * 主人给宠物喂食
         */
        public void feed(Pet pet){
            pet.eat();
        }
        
        /**
         * 主人给Dog喂食
         */
        public void feed(Dog dog){
            dog.eat();
        }
        
        /**
         * 主人给 Penguin喂食
         */
        public void feed(Penguin pgn){
            pgn.eat();
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getMoney() {
            return money;
        }
    
        public void setMoney(int money) {
            this.money = money;
        }
        
    }

    》子类到父类的转换(向上转型)

    public static void main(String[] args) {
            //主人对象
            Master master = new Master("王先生",100);
            
            //通过父类引用子类对象
            Pet pet = new Dog("欧欧", "雪纳瑞");
            master.feed(pet);
            pet.print();
            
            
            //pet.catchingFlyDisc();    向上转型不能调用子类独有的方法
        }

       当把子类对象直接赋给父类引用变量时,例如  Pet pet = new Dog("欧欧", "雪纳瑞");  这个pet引用变量的编译类型是 Pet ,运行时类型是 Dog,当运行时调用该引用变量的方法时,其方法行为总是表现出子类方法行为的特征,而不是父类方法的行为特征,这就可能出现:相同类型的变量、调用同一个方法时呈现出多种不同行为特征,这就是多态。 


    》父类到子类的转换(向下转型)

      当向上转型发生后,将无法调用子类特有的方法。但是当需要调用子类特有的方法时,可以通过将父类再转换为子类来实现。将一个指向子类对象的父类引用赋给一个子类引用,称之为向下转型,此时必须进行强制类型转换。

    public static void main(String[] args) {
            //主人对象
            Master master = new Master("王先生",100);
            
            //通过父类引用子类对象
            Pet pet = new Dog("欧欧", "雪纳瑞");
            master.feed(pet);
            pet.print();
            
            //pet.call();    向上转型不能调用子类独有的方法
            
            
            Dog dog=(Dog)pet;   //强制转换成 Dog 对象
            dog.catchingFlyDisc();  //调用狗狗玩飞盘方法
            
            Penguin pgn=(Penguin)pet;   //强制转换成 Penguin 对象
            pgn.swimming();            //调用企鹅的游泳方法
        }

    结果:

       把 pet 强制转换为 Dog 后,可以访问 Dog 类特有的玩飞盘方法。但必须转换为父类指向真实子类类型 Dog ,不是任意强制转换,如当转换为 Penguin类(Penguin pgn=(Penguin)pet;)时,将出现类型转换异常 ClassCastException。

    如果没有转换为真实子类类型,就会出现类型转换异常。如何有效避免出现这种异常呢?Java 提供了 instanceof 运算符来进行的判断。


    》instanceof 运算符

      该运算符用来判读一个对象是否属于一个类或实现了一个接口。结果为 true或 false 。在强制类型转换之前通过 instanceof 运算符检查对象的真实类型,在进行相应的强制类型转换,这样就可以避免类型转换异常,从而提高代码的健壮性。

    public static void main(String[] args) {
            //主人对象
            Master master = new Master("王先生",100);
            
            //通过父类引用子类对象
            Pet pet = new Dog("欧欧", "雪纳瑞");
            master.feed(pet);
            pet.print();
            
            //pet.call();    向上转型不能调用子类独有的方法
            
            if(pet instanceof Dog){
                Dog dog=(Dog)pet;   //强制转换成 Dog 对象
                dog.catchingFlyDisc();  //调用狗狗玩飞盘方法
            }else if(pet instanceof Penguin){
                Penguin pgn=(Penguin)pet;   //强制转换成 Penguin 对象
                pgn.swimming();            //调用企鹅的游泳方法
            }
            
        }

      

      需要注意:instanceof 运算符前面操作数的编译时类型要么与后面的类相同,要么与后面的类具有父子继承关系,否则会引起编译错误。

  • 相关阅读:
    众包实验:《分享上海》出书计划
    程序员笔试题(附答案)
    "客户管理系统"终于开发完毕,在这快乐元宵节里深吸一口气(图)
    SOA 初步阅读理解
    大型网站性能优化的通用方法(转)
    读《恒源祥彪悍广告是如何出炉的》后学习到的
    Asp.net生成静态页面最简单方法(源码)
    综合实习报告 写了一下午 图图图。。。。全是图
    程序员笔试题 将人民币金额转换成大写的金额
    扬太集团的网站也做完了,写篇日记算做总结吧
  • 原文地址:https://www.cnblogs.com/szj-ang/p/7306206.html
Copyright © 2011-2022 走看看