zoukankan      html  css  js  c++  java
  • java的方法重写 ,多态和关键字 instanceof和final

    package cn.pen;
    /*final 是一个java的关键字,用于修饰局部变量、属性、方法、类,表示最终的意思。
     final修饰类表示最终类,无法被继承。public final class Penguin{}
     final修饰符方法,方法就不能被重写。所以final修饰的是最终子类或最终类
     final 修饰属性,经常和static搭配使用,形成静态常量。静态常量不能被改变
     修饰变量final 修饰基本数据类型 ,表示a中的内容(值)不能被改变final int a = 10;
    final 修饰引用数据类型,表示person中的内容(地址)不能被概念 final Person person = new Person();*/    
    
    //子类 企鹅
    public class Penguin extends Pet {
        private String gender;
    
        public static final String SEX_MALE = "Q仔";
        public static final String SEX_FEMALE = "Q妹";
    
        public String getGender() {
            return gender;
        }
    
        public void setGender(String gender) {
            this.gender = gender;
        }
    
        public Penguin() {
            super();
        }
    
        public Penguin(String name, int health, int love, String gender) {
            super(name, health, love);
            this.gender = gender;
        }
    
        @Override
        public void showInfo() {//方法重写
            super.showInfo();
            System.out.println(",我是一只" + this.getGender());
        }
    
        @Override
        public void eat() {//方法实现,完全重写
            System.out.println(super.getName() + "在吃鱼...");
            super.setHealth(super.getHealth() + 5);
        }
        public void swimming() {
            System.out.println("企鹅在游泳...");
            super.setHealth(super.getHealth() - 10);
            super.setLove(super.getLove() + 5);
        }
    
    
    }
    package cn.pen;
    //主人类
    public class Master {
        private String name;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public Master() {
            super();
        }
    
        public Master(String name) {
            super();
            this.name = name;
        }
        //添加一种动物,就增加一条引用动物代码
        /*public void feed(Dog dog) {           //把子类Dog引用过来,提取Dog中的属性
            System.out.println(this.getName() + "正在喂:" + dog.getName());
            dog.eat();                    //再把Dog中eat方法引用过来           */
        
        
        
        //只需一条引用父类,就可以被所有动物使用
        //父类作为方法形参实现多态
    /*    public void feed(Pet pet) {           //把父类Pet引用过来,Dog把自己赋给Pet,
            System.out.println(this.getName() + "正在喂:" + pet.getName());
            pet.eat();  }
            
       
       
       父类作为方法的返回值实现多态:* */
      public Pet adoptPet(int type) {    //从Test得到type,然后判断
            Pet pet = null;              //类型转换
            if(1 == type) {
                pet = new Dog();
            }else  {
                pet = new Penguin();
            }
            return pet;                 //得到返回值 ,返回给Test
        }
            
        public void play(Pet pet) {
            if(pet instanceof Dog) {
                Dog dog = (Dog) pet;
                dog.catchFlyDisc();
            }else if(pet instanceof Penguin) {
                Penguin penguin = (Penguin) pet;
                penguin.swimming();
            }
        }
        
     
    }
    
    
    package cn.pen;
    //子类 狗
    public class Dog extends Pet{
        private String strain;
    
        public String getStrain() {
            return strain;
        }
    
        public void setStrain(String strain) {
            this.strain = strain;
        }
    
        public Dog() {
            super();
        }
    
        public Dog(String name, int health, int love, String strain) {
            super(name, health, love);
            this.setStrain(strain);
        }
        public void showInfo() {
            super.showInfo();//在继承的基础上部分重写,完全重写就不需要引入父类方法,自己全部重写
            System.out.println(",我是一只" + this.getStrain());
        }/*:方法的重写
        当子类从父类继承过来的方法不能满足自身需要时,子类可以根据自身情况进行方法重写(overwrite/override)
                方法重写建立在继承的基础上,没有继承,就没有重写! 子类根据自身情况,可以选择部分重写和完全重写
                重写的规则:1.方法名称相同2. 参数列表相同3. 子类的访问权限一定 >= 父类访问权限  4. 返回值和父类相同或者是其子类    
            何时使用继承: 符合 is – a 关系;学生 is a 人;老师 is a 人;
              继承实现代码重用
               当 多个子类拥有共同的属性和行为时,人为把共同的属性和方法提取到父类中,子类继承父类实现代码重用     
        */
        
        public void eat() {//方法实现(完全重写)
            System.out.println(super.getName() + "吃狗粮...");
            super.setHealth(super.getHealth() + 3);
            /*实现(implement):子类继承抽象父类时,一定要重写父类的抽象方法,此时父类的抽象方法没有方法体,也即没有实现;
             * 子类一定重写父类的抽象方法也即实现了父类的抽象方法。实现是一种特殊的重写。实现建立在重写的继承上。*/
            
            }
            
            //父类没有的方法
            public void catchFlyDisc(){
                System.out.println("狗狗在玩飞盘...");
                super.setHealth(super.getHealth() - 10);
                super.setLove(super.getLove() + 6);
        }
    
        
    }
     
    package cn.pen;
    //父类:动物
    public abstract class Pet {
    //abstract(抽象)     抽象类:public abstract class 类名 {}    
    //抽象类过于抽象,实例化后无语义 => 不能实例化
        private String name;
        private int health;
        private int love;
        
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public int getHealth() {
            return health;
        }
        public void setHealth(int health) {
            if(health < 0) {
                this.health = 100;
                System.out.println("健康值不合法!");
            }else {            
                this.health = health;
            }
        }
        public int getLove() {
            return love;
        }
        public void setLove(int love) {
            this.love = love;
        }
        public Pet() {
            this.health = 100;
            this.love = 0;
        }
        public Pet(String name, int health, int love) {
            
            this.name = name;
            this.health = health;
            this.love = love;
        }
        public void showInfo() {
            System.out.print("我的姓名:"+this.getName());
            System.out.print(",健康值:"+this.getHealth());
            System.out.print(",亲密度"+this.getLove());
        }//吃方法,动物都有吃的行为(方法);但不同的动物吃的方法不同,吃的东西不同,所以吃是个抽象方法
        public abstract void eat();
    /*因为动物都有睡觉的行为(动物共有的),但是不同的动物 睡觉方法不同,比如:
     * 人继承于动物,鱼继承于动物。人有睡觉(闭眼睡)的方法,鱼有睡觉的方法,动物也有睡觉的方法
     * 虽然都是睡觉,但是睡觉方法却不同,所以说睡觉这个方法不能再父类实习,只有在具体到子类时才能实现
     * 此时可以把该方法定义成抽象方法。抽象方法却只能存在于抽象类,所以有抽象方法的类称为抽象类(abstract class)
     * 所以:如果一个方法过于抽象无法实现,需要把该方法声明为抽象方法。形式:public abstract void eat();
     * 注意:抽象方法一定位于抽象类中。
                        抽象方法没有方法体。
                         抽象类中的方法不一定都是抽象方法。
                         子类继承抽象类,一定要根据自身情况重写抽象类的抽象方法,除非子类也是抽象类。
     
     * */
    }
    
    
    

    package cn.pen; //执行类 import java.util.Scanner;
    public class Test { public static void main(String[] args) { //Dog dog = new Dog("二狗",90,0,"土狗"); //把Dog的类引入进来 //Master master = new Master("王二小"); //在把主人类引用进来 //master.feed(dog); //把dog(Dog类的入口或钥匙)引入主人类的feed方法 //dog.showInfo(); //引出Dog类的showInfo方法 /*执行结果: * 王二小正在喂:二狗 二狗吃狗粮... 我的姓名:二狗,健康值:93,亲密度0,我是一只土狗*/ //每个动物都有吃,但吃的方法不同,造成的结果也就不同,但动物有很多种,我们不能每个动物子类都这样写一遍 //所以我们用到了:多态 /*多态 * * 软件设计原则—开闭原则 ,对拓展开放,对修改关闭。为什么要使用多态?对系统进行业务拓展,增加系统的可维护性。 可以理解为多种状态/多种形态 同一事物,由于条件不同,产生的结果不同 程序中的多态 同一引用类型,使用不同的实例而执行结果不同的。 同:同一个类型,一般指父类。 不同:不同的子类实例 不同:针对同一方法执行的结果不同 比如说睡觉,不同的动物睡觉方法不同,最后结果不同*/ /*在多态中存在两种类型转换,一种是自动类型转换,一种是强制类型转换。 在引用数据类型转换过程中, 自动类型转换也称向上类型转换。子类可以自动转换成父类。 多态的实现形式 * 父类类型 引用 子类对象(本质) Pet pet=null; //同一引用类型(父类) pet = new Dog("二狗",90,0,"土狗") ;// [ 自动类型转换] 父类类型引用子类对象,当调用eat方法时,执行的是被子类对象重写/实现的eat方法。 pet.eat(); // 呈现多态 结果:二狗吃狗粮... 王二小正在喂:二狗 * */ //父类作为方法形参实现多态 /*Pet pet=null; //同一引用类型(父类) pet=new Dog("二狗",100,0,"土狗"); // 父类引用 引用 子类对象 Master master = new Master("王二小"); master.feed(pet); // 呈现多态 pet.showInfo(); // 呈现多态 pet=new Penguin("大脚", 90, 50, Penguin.SEX_FEMALE); // 父类引用 引用 子类对象 master.feed(pet); // 父类引用 引用 子类对象 pet.showInfo(); // 呈现多态 同样的结果,但是我们只在主人类那只需写引用父类的代码就可以了 ,无需向上面那样每个动物都需在主人类那写一遍 * 现在没增加一种动物就只会多写一个类就可以了,无需再主人类那加一条方法;实现一个方法多种使用 结果: 王二小正在喂:二狗 二狗吃狗粮... 我的姓名:二狗,健康值:103,亲密度0,我是一只土狗 王二小正在喂:大脚 大脚在吃鱼... 我的姓名:大脚,健康值:95,亲密度50,我是一只Q妹 父类作为方法的返回值实现多态: */ System.out.println("欢迎光临sxt宠物店"); System.out.println("请选择领养的宠物 1.狗狗 2.企鹅 "); Scanner arr=new Scanner(System.in); int type=arr.nextInt(); //控台输入type Master master = new Master("王二小"); //引用Master类 Pet pet = master.adoptPet(type); //把type赋值给Master类adoptPet方法判断,得出来结果后赋给pet /*强制类型转换也称向下类型转换。父类可以强制转换成子类 * 子类类型 引用 = (子类)父类对象 * 一般而言,需要判断父类对象的真实类型,用instanceof关键字 * obj instanceOf 类/接口 判断obj是否是类/接口的实例
    instanceof通常和强制类型转换结合使用
    instanceof是判断是否能强制转换,能返回true * 如果要调用子类特有的方法时,一定要强制类型转换,通过instanceof鉴别具体类型
    */ if(pet instanceof Dog) { //得到从Master得到的返回值pet,然后判断是强制转换给Dog还是Penguin, Dog dog = (Dog) pet; //判断完之后再一个一个赋值 dog.setName("二狗"); dog.setHealth(90); dog.setLove(20); dog.setStrain("土狗"); }else if(pet instanceof Penguin) { Penguin penguin = (Penguin) pet; penguin.setName("大脚"); penguin.setHealth(90); penguin.setLove(20); penguin.setGender(Penguin.SEX_FEMALE); } master.play(pet); //再把被赋完值之后的pet引入Master的piay方法执行再返回结果 pet.showInfo(); } }
  • 相关阅读:
    javaweb学习总结二十六(response对象的用法二 下载文件)
    javaweb学习总结二十五(response对象的用法一)
    线程池的使用
    javaweb学习总结二十四(servlet经常用到的对象)
    javaweb学习总结二十三(servlet开发之线程安全问题)
    创建与删除索引
    Oracle中exists与in的区别
    win7安装IIS及将网站发布到IIS上
    C# toolstrip 上添加DateTimePicker Control控件
    用java实现zip压缩
  • 原文地址:https://www.cnblogs.com/406070989senlin/p/10762162.html
Copyright © 2011-2022 走看看