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(); } }

猜你喜欢

转载自www.cnblogs.com/406070989senlin/p/10762162.html