简单理解Java中转型问题(向上转型和向下转型)介绍及区别
———————————————————————————————
本文内容仅仅为个人的理解,仅供大家参考。如果本文中存在一些错误的地方还请大佬们指出,本人感激不尽。
———————————————————————————————
1.向上转型[ 格式: 父类名 对象名=new 子类名(); ]
我先把代码展示出来,再对其进行简单讲解
class Animal{
int num=100;
void say(){
System.out.println("It's an Animal.");
}
}
class Dog extends Animal{
int num=50;
void say(){
System.out.println("It's a Dog.");
}
void bark(){
System.out.println("汪汪汪!");
}
}
public class example{
public static void main(String[] args) {
Animal dog=new Dog();//向上转型
System.out.println(dog.num);
dog.say();
// dog.bark();
}
}
运行结果:
100
It's a Dog.
解释: 向上转型的格式和实际运用如上所示,基本格式还是容易掌握的,所以在此就讲以下三个方面
a.向上转型的作用
b.为什么是这个运行结果
c.需要注意的问题
a. 作用:当创建一个父类对象时,通过向上转型可以用此对象访问父类变量和子类重写的父类方法(子类没有重写父类方法的话就只能访问父类里面的方法)
b. 运行结果:看作用的文字介绍可能不容易那么懂,下面我结合代码对其讲解:
这里我们通过Dog类向上转型Animal类有了dog这个对象,那么dog这个对象能干什么呢?由上述作用我们可以知道:dog这个对象可以访问dog对应类(Animal)里面的变量但不能访问Dog类里面的变量,dog还可以访问Animal子类的Dog类里面的say()方法(重写的父类方法)。固最后的运行结果就是上面那样。
c. 注意:
1.若子类没有重写父类方法那么该对象只能访问自己的变量和自己类里的方法。
2.不能通过此对象访问子类新增的方法即子类有但父类里没有的方法,所以在上面的代码中main里面就不能运行dog.bark();这行代码。
------------------------------------------------------------------------------
2.向下转型[ 格式: 子类名 对象名=(子类名) 已向上转型的对象名; ]
我对上面代码进行一些了改动然后将其展示如下
class Animal{
int num=100;
void say(){
System.out.println("It's an Animal.");
}
}
class Dog extends Animal{
int num=50;
void say(){
System.out.println("It's a Dog.");
}
void bark(){
System.out.println("汪汪汪!");
}
}
public class example{
public static void main(String[] args) {
Animal dog=new Dog();//向上转型
Dog dog2=(Dog) dog;//向下转型
System.out.println(dog2.num);
dog2.say();
dog2.bark();
}
}
运行结果:
50
It's a Dog.
汪汪汪!
解释: 当我们理解了向上转型后,我们对向下转型就很好理解了,基本格式和用法如上所示,所以我对其还是讲以下三个方面
a.向下转型的作用
b.为什么是这个运行结果
c.需要注意的问题
a. 作用:当有了向上转型的操作后,我们紧接着创建一个子类对象,通过向下转型我们可以用此对象访问父类和子类里的变量,同样我们可以通过此对象访问父类和子类里的方法。(所以我们可以看出来向下转型它访问的范围要比向上转型访问的范围要大很多)
b. 运行结果:由上述作用应该不难理解运行结果,所以我就解释一下为什么输出是50而不是100,其原因很简单因为子类中变量和父类变量重名,类似于“重写”,子类的变量就把父类相同的变量给覆盖掉了即100被50给覆盖,所以我们访问的num变量值是50而不是100。(所以我们就记住这个道理:子类重写就覆盖,不重写我依然可以访问父类里面的东西,所以访问方法也是这个道理)
c. 注意:向下转型需要建立在向上转型的基础之上,即在进行向下转型的时候必须要有向上转型的步骤否则会报错,错误用法如下:
Animal dog=new Animal();//仅仅创建了一个父类对象,并没有向上转型
Dog dog2=(Dog)dog;//向下转型,运行时编译器会报错
------------------------------------------------------------------------------
二者的区别:
这里我就说简单一点:
向上转型: 只有当子类重写方法时访问该方法会优先访问子类的那个重写方法,其余情况都只能访问父类里面的变量和方法。
向下转型: 建立在向上向上转型的基础之上,其所创建的对象可以访问父类,子类里任意变量和方法,但注意!如果子类变量和父类变量重名,则访问该变量值优先访问的是子类里该变量的值,如果子类方法重写了父类方法,同理,访问该方法优先访问的是子类重写的方法。
——————————————————————————————————————————————————————————————
拓展代码(转型的另外一种运用,这里看代码知道可以这么用就行了,对其就不做解释了)
class Animal{
void speak(Animal dog){ //括号里的Animal dog等价于Animal dog=new Dog()
Dog dog2=(Dog)dog; //向下转型
dog2.bark();
}
}
class Dog extends Animal{
void bark(){
System.out.println("汪汪汪!");
}
}
public class example{
public static void main(String[] args) {
Animal animal=new Animal();
Dog dog=new Dog();
animal.speak(dog);
}
}
运行结果:
汪汪汪!