java向上转型的作用
关于向上转型的作用,我们从一段代码引入:
public class Animal {
String name = "我是动物";
static int age = 20;
public void eat() {
System.out.println("动物可以吃饭");
}
public static void sleep() {
System.out.println("动物可以睡觉");
}
public void run(){
System.out.println("动物可以奔跑");
}
public static void main(String[] args) {
Animal am = new Dog();
am.eat();
am.sleep();
am.run();
//am.watchdog();这里会报错
System.out.println(am.name);
System.out.println(am.age);
}
}
class Dog extends Animal {
String name = "小狗";
static int age = 60;
public void eat() {
System.out.println("小狗可以吃饭");
}
public static void sleep() {
System.out.println("小狗可以睡觉");
}
public void watchdog() {
System.out.println("小狗可以看门");
}
}
运行结果:
但是可以看到代码块中,直接调用Dog的watchdog()方法会报错,
这就是因为我们此处进行的向上转型,am这个对象虽然指向子类,但是子类由于进行了向上转型,就失去了使用父类中所没有的方法的“权利”,在此处就是不能调用watchdog()这个方法。
而且结果里也可以看到,睡觉是引用的父类“Animal”的睡觉方法,这是因为Animal的睡觉方法为静态方法,可以总结如下:
如果是访问成员变量,编译的话就是看父类,运行同样是看父类
如果访问的方法,编译就看父类,运行则看子类
如果是静态方法,编译和运行都是看父类
那么向上转型的具体作用是什么,可以通过下面两端代码做个比较:
class Animal {
public void run() {
System.out.println("这是父类run()方法");
}
public void sleep() {
System.out.println("这是父类sleep()方法");
}
}
class Dog extends Animal {
public void run() {
System.out.println("小狗在跑");
}
public void sleep() {
System.out.println("小狗睡觉");
}
}
public class Cat extends Animal {
public void run() {
System.out.println("小猫在跑");
}
public void sleep() {
System.out.println("小猫在睡觉");
}
public void eat() {
System.out.println("小猫在吃");
}
public static void main(String[] args) {
show(new Dog());//向上转型实现
show(new Cat());
}
public static void show(Animal am) {//父类实例作为参数
am.run();
am.sleep();
}
}
以上代码中:
public static void main(String[] args) {
show(new Dog());//向上转型实现
show(new Cat());
}
public static void show(Animal am) {//父类实例作为参数
am.run();
am.sleep();
}
就体现了向上转型的优点,这也体现了Java抽象编程的思想。如果此处没有向上转型,要实现show每个子类的功能,那么有几个子类就要写多少函数。代码如下:
public static void main(String[] args) {
show(new Dog());
show(new Cat());
}
public static void show(Dog dog) {
dog.run();
dog.sleep();
}
public static void show(Cat cat) {
cat.run();
cat.sleep();
}
试想一下,一旦有很多子类,那么这个工作量将会比没有使用向上转型大很多。这也表明向上转型还有个优点就是提高了代码的简洁性。
总结
向上类型转换(小转大):
语法规则:<父类型> <引用变量名> = new <子类型>();
1.此时通过父类引用变量调用的方法是子类覆盖或继承
父类的方法,不是父类的方法。
2.此时通过父类引用变量无法调用子类特有的方法。
Q:
向上转型虽然使代码变得简洁,体现了JAVA的抽象编程思想,但是也出现了上面提到的子类无法调用其独有的方法,这要怎么解决呢?所以就有了与之对应的向下转型,弥补了向上转型所带来的缺陷。
借鉴博客:
https://blog.csdn.net/TNTZS666/article/details/80273986