java知识理解2

对象的转型:

向上转型:子类对象转为父类,向上转型不需要显示的转化。 Father father = son; 向上转型会丢失子类独有的特性

向下转型:父类对象转为子类,向下转型需要强制转化。 Son son = (Son)Father; 向下转型可能会出现错误,需要谨慎。

public class Pet {
    public String name = "Pet";

    public void speak() {
        System.out.println("I am a pet");
    }
}

public class Dog extends Pet{
    public String name = "dog";

    @Override
    public void speak(){
        System.out.println("I am a Dog");
    }

    //这是Dog对象独有的方法
    public void run(){
        System.out.println("Dog is running");
    }
}

public class LittleGril {
    public void feed(Pet pet){
        pet.speak();
        pet.run();//报错,因为feed(Pet)中传入的参是Dog类型,Dog向上转型,失去了自己特性run()
    }

    public static void main(String[] args) {
        LittleGril littleGril = new LittleGril();
        littleGril.feed(new Dog());
    }
}
public class Pet {
    public String name = "Pet";

    public void speak() {
        System.out.println("I am a pet");
    }
}

public class Dog extends Pet{
    public String name = "dog";

    @Override
    public void speak(){
        System.out.println("I am a Dog");
    }

    //这是Dog对象独有的方法
    public void run(){
        System.out.println("Dog is running");
    }
}

public class LittleGril {
    public void feed(Pet pet){
        pet.speak();
        if(pet instanceof Dog){ 
            Dog dog = (Dog)pet; //Pet对象向下转型
            dog.run();
        } // 需要用if条件判断,避免向下转型的错误,因为如果 传参不是Dog类型,那么强制转Dog就错了

    }

    public static void main(String[] args) {
        LittleGril littleGril = new LittleGril();
        littleGril.feed(new Dog());
    }
}
重载、重写的分派
public class Animal {

    public void eat() {
        System.out.println("animal is eating");
    }
    public void eat(String food) {
        System.out.println("animal is eating" + food);
    }
}

public class Dog extends Animal {
    @Override
    public void eat() {
        System.out.println("dog is eating");
    }
    @Override
    public void eat(String food) {
        System.out.println("dog is eating" + food);
    }

    public static void main(String[] args) {
        Animal animal = new Dog();
        animal.eat(" meat");
        //输出结果:dog is eating meat
    }
}

这个案例里边有重载,也有重写,最终会选择Dog类的(String food)方法。

相关字节码信息如下:

我们从字节码里面分析第一步是静态分派的过程,jvm从Animal类的多个重载方法中选择了 Animal::eat(String food) 这个方法,并且生成指令 Animal::eat(String food)。 invokevirtual 第二步是动态分派的过程,是根据运行时类型确定具体调用谁的 eat(String food) 方法,因为运行时类型是Dog,所以最终的方法选择 是 Dog::eat(String food) 。

重载是静态分派,重写是动态分派。这两个过程是相辅相成,不是有你没我的关系。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值