java --向上转型和向下转型

一、简述

  Java 转型主要是用在继承和接口实现的场景,Java 转型可分为向上转型和向下转型,区别如下:

  • 向上转型:通过子类对象实例化父类对象,这属于自动转换。
  • 向下转型:通过父类对象实例化子类对象,这属于强制转换。

  只要记住一句话即可,父类引用指向子类对象,即 <父类型> <引用变量名> = new <子类型>()

二、向上转型

  子类引用的对象转换为父类类型称为向上转型。向上转型后的父类引用只能调用父类的属性,若子类重写了父类的方法,则通过父类引用调用的是子类重写后的方法(即 override),该调用过程即为“动态绑定”。示例如下所示:

public class Parent {

    public int i = 10;

    public void print(){
        System.out.println("我是父类的方法");
    }

    public void printA(){
        System.out.println("我是父类的方法,子类中没有重写该方法");
    }

}
public class Son extends Parent {

    public int i = 20;

    public void print() {
        System.out.println("我是子类的方法,我重写了父类的方法");
    }

    public void printSelf() {
        System.out.println("我是子类独有的方法,父类中没有该方法");
    }

    public static void main(String[] args) {
        Son son = new Son();
        Parent parent = son;

        System.out.println(son.i);
        son.print();
        son.printA();
        son.printSelf();

        System.out.println("================================");

        System.out.println(parent.i);
        parent.print();
        parent.printA();
    }
}

  结果如下所示:

20
我是子类的方法,我重写了父类的方法
我是父类的方法,子类中没有重写该方法
我是子类独有的方法,父类中没有该方法
================================
10
我是子类的方法,我重写了父类的方法
我是父类的方法,子类中没有重写该方法

  综上,可有如下结论:

  • 此时通过父类引用变量调用的方法是子类覆盖或继承父类的方法,不是父类的方法。
  • 此时通过父类引用变量无法调用子类特有的方法。
  • 此时通过父类引用只能访问到父类的属性。

三、向下转型

  将一个父类类型的变量强制转换为子类类型的过程称为向下转型。但并不是所有的对象都可以向下转型,只有当这个对象原本就是子类对象通过向上转型得到的时候才能够成功转型,在向下转型前,通过instanceof 判断某对象是否是某类的实例。此外,大部分情况下,不推荐进行向下转型。示例如下所示:

public class Animal {
    private String name = "Animal";

    public void look() {
        System.out.println(name + " look at you");
    }
}
public class Human extends Animal {
    private String name = "Human";

    public void look() {
        System.out.println(name + " looks at you");
    }

    public static void main(String[] args) {
        Animal a1 = new Human(); //向上转型
        Animal a2 = new Animal();
        Human b1 = (Human) a1; // 向下转型,编译和运行皆不会出错,安全的
        
        // 不安全的向下转型,编译无错但会运行会出错,java.lang.ClassCastException
        // Human c = (Human) a2;
    }
}

四、转型的好处

  转型体现了 Java 抽象编程的思想,可以在一定程度上减少不必要的冗余代码。示例如下:

public interface AnimalAction {
    public void eat();
}
public class Panda implements AnimalAction {

    @Override
    public void eat() {
        System.out.println("熊猫喜欢吃竹子");
    }

}
public class Cat implements AnimalAction {
    @Override
    public void eat() {
        System.out.println("猫喜欢吃鱼仔");
    }
}
public class Main {

    public static void print(AnimalAction animalAction) {
        animalAction.eat();
    }

    public static void main(String[] args) {

        Panda panda = new Panda();
        Cat cat = new Cat();

        print(panda);
        print(cat);
    }
}

  结果如下:

在这里插入图片描述

  上述示例中,print() 方法中的参数只要是实现了 AnimalAction 接口的类都可传入,即调用的方法体的实现逻辑一样,但传入的参数类型不同,则可通过 Java 转型避免针对不同的参数类型实现不同的方法,减少了冗余代码。

如有冒犯,请联系我删除哈,一起学习https://www.csdn.net/tags/NtzaYgzsNDYzMDctYmxvZwO0O0OO0O0O.html

 

  • 23
    点赞
  • 95
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值