向上转型:
- 本质:父类引用指向了子类的对象
- 语法:父类类型 引用名 = new 子类类型();
- 特点:编译类型看左边,运行类型看右边
可以调用父类中的所有成员(需访问权限)
不能调用子类特有的成员;
最终运行效果看子类的具体实现!
方法的调用:
public class OuterClass{
public static void main(String args[])
{
A a = new B(); //父类引用指向子类对象
a.print(); //输出结果:B:print
}
}
class A {
public void print() {
System.out.println("A:print");
}
}
class B extends A {
int x=5;
public void print() {
System.out.println("B:print");
}
}
并且 此时如果子类中没有重写父类的方法,那么会直接调用父类的方法;另外如果是子类特有方法,是无法调用的。
通俗点讲,对象.方法,能.什么方法是左边编译类型决定的,也就是父类决定的,而具体效果,是先由右边的运行类型决定,也就是子类决定。
属性的调用:
刚刚主要讲的是方法的调用,是体现出来了方法的重写的,那么调用属性呢?
public class OuterClass {
public static void main(String args[]) {
A a = new B(); //父类引用指向子类对象
System.out.println(a.x);//结果: 3
}
}
class A {
int x = 3;
}
class B extends A {
int x = 5;
}
经过实验发现这里并没有调用子类的属性,可以发现属性是没有重写之说的,属性的值看编译类型,也就是由“=”左边的类型决定。如果父类没有这个属性,子类有,那等于没有,是直接报错的!‘’
向下转型:
- 语法:子类类型 引用名 = (子类类型) 父类引用;
- 特点:只能强转父类的引用,不能强转父类的对象
要求父类的引用必须指向的是当前目标类型对象
当向下转型后,可以调用子类类型中的成员
public class OuterClass {
public static void main(String args[]) {
A a = new B(); //父类引用指向子类对象
B b = (B)a; // 向下转型
System.out.println(b.x); // 这里输出父类的方法,子类里没有的方法,在父类中找到
b.print();//子类有这个属性,输出子类的属性
b.my();//可以调用子类独有的方法了
}
}
class A {
int x = 3;
public void print(){
System.out.println("A:print");
}
}
class B extends A {
int x = 5;
public void my(){
System.out.println("这是子类独有的方法");
}
}
可以看到,向下转型后的对象,无论是调用方法,还是属性,都是从子类出发了,找不到,再去父类找,
注意点:
A aa = new A();
B bb =(B)aa; //这是错误的,不能强转父类的对象
/*假设还有个C类也继承了A类*/
A aaa = new C();
B bbb =(B)aaa; //这样也是错的,因为aaa并不是指向当前子类(B)的引用