一、简述
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