java重写

多态

java面向对象三大基本特征之一

对于不同的对象,同一个方法调用,造成不同的结果。

比如主人对猫和狗喂食,但是猫与狗吃的食物不同,按照之前的写法需要重写喂食方法,以便传入不同的参数执行不同的语句。下面使用多态可以简化步骤。

写出Animal类,有name属性,由Cat和Dog类继承。

class Animal {
    private String name;
    Animal(String name) {
    	this.name = name;
    }
    public String name {
        return name;
    }
}
class Cat extends Animal{
    Cat(String name) {
        super(name);
    }
}
class Dog extends Animal{
    Dog(String name) {
        super(name);
    }
}

写出Food类,有name属性,由Fish和Bone类继承。

class Food {
    private String name;
    Animal(String name) {
    	this.name = name;
    }
    public String name {
        return name;
    }
}
class Fish extends Food{
    Fish(String name) {
        super(name);
    }
}
class Bone extends Food{
    Bone(String name) {
        super(name);
    }
}

写出Monster类,创建feed方法

class Monster {
    private String name;
    Monster(String name) {
        this.name = name;
    }
        //传统做法,若添加了Animal或Food的子类则需要在此处添加相关方法
//    public void feed(Cat cat,Fish fish){
//        System.out.println(name + "对" + cat.getName() + "喂食" + fish.getName());
//    }
//    public void feed(Dog dog,Bone bone){
//        System.out.println(name + "对" + dog.getName() + "喂食" + bone.getName());
//    }
    public String feed(Animal animal,Food food) {
        return name + "对" + animal.getName() + "喂食" + food.getName();
    }
}

在main方法调用测试

public class main {
    public static void main(String[] args) {
        Cat cat1 = new Cat("tom");
        Fish fish1 = new Fish("fish");
        Dog dog1 = new Dog("spike");
        Bone bone1 = new Bone("bone");
        Monster monster = new Monster("我");
        System.out.println(monster.feed(tom1,fish1));
        System.out.println(monster.feed(dog1,bone1));
    }
}

如上,以子类参数调用feed方法是多态的体现

输出

我对tom喂食fish
我对spike喂食bone

向上转型与向下转型

向上转型:父类的引用指向了子类的对象

父类名 对象名 = new 子类名();

如上的main方法中创建cat1、fish1对象可以写成

//编译类型在等号左边,运行类型在等号右边
//编译类型确定后不能改变,运行类型可以改变
Animal cat1 = new Cat("tom");//运行类型为Cat,编译类型为Animal
Food fish1 = new Fish("fish");//运行类型为Fish,编译类型为Food

可以调用父类中的所有成员(须遵守访问权限), 但是不能调用子类特有的成员,也就是说,不能以调用cat1对象,调用其Cat类方法,但是可以调用Animal类方法。即使重写了方法,运行时还是优先从子类寻找方法,找不到再找父类方法。

向下转型

子类名 对象名 = (子类名) 已向上转型对象名;

将上面已经向上转型的cat1、fish1对象向下转型,指向新对象cat0,fish0

Cat cat0 = (Cat) cat1;//cat0的运行类型和编译类型均为Cat
Food fish0 = (Fish) fish1;

对象名必须为当前目标类型的对象 Animal可以转成Cat,Cat不能转成Dog

Dog dog = (Dog) cat1; //运行时抛出异常ClassCastException

instance比较操作符

用于判断对象的运行类型是否为XX类型或XX类型的子类型

public class main0 {
    public static void main(String[] args){
        //属性没有重写,属性的值看编译类型
        A a = new B();//向上转型
        System.out.println(a.num);//10
        B b = new B();
        System.out.println(b.num);//20
        
        //instanceof 比较操作符,用于判断对象的运行类型是否为XX类型或XX类型的子类型,是返回true,否返回false
        BB aa = new BB();
        System.out.println(aa instanceof AA);//true
        System.out.println(aa instanceof BB);//true
        AA bb = new BB();
        System.out.println(bb instanceof AA);//true
        System.out.println(bb instanceof BB);//true
    }
}
class A{
    int num = 10;
}
class B extends A{
    int num = 20;
}
class AA{
}
class BB extends AA{
}

多态数组

Animal[] animal = new Animal[4];
animal[0] = new Cat("tom10");
aniaml[1] = new Cat("tom100");
animal[2] = new Animal("jack10");
animal[3] = new Dog("spike10");
//编译类型为Animal,运行类型是根据实际情况由jvm判断

可根据下标获取对应的对象。本类或其子类的对象才能写入到数组中。

动态访问机制

看看下面会输出什么

public class DynamicBinding {
    public static void main(String[] args) {
        A a = new B();
        System.out.println(a.sum());
    }
}

class A{
    public int num = 100;
    public int sum(){
        return getNum() + 200;
    }
    public int getNum(){
        return num;
    }
}

class B extends A{
    public int num = 10;
    public int getNum(){
        return num;
    }
}

当调用对象方法时,该方法会和该对象的内存地址/运行类型绑定;当调用对象属性时,没有动态绑定机制,哪里声明,就在哪里使用

运行类型是B,就在B类中查找sum()方法,若没有找到,就向父类查找

在父类中调用方法getNum(),就要回去运行类型查找方法,即在子类找到,返回给父类方法sum()

输出

210
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值