java中的上转型对象
- 引言: 当学习到java的多态时,提到了上转型对象的概念,由于java中的多态十分重要,在本文中将介绍本人在学习过程中的疑惑和寻找到的解答并进行总结。
1.定义
如果B类是A类的子类或间接子类,当用B类创建对象b并将这个对象b的引用赋给A类对象a时,如:
A a;
a = new B();
OR
A a;
B b = new B();
a = b;
则称A类对象a是子类B对象b的上转型对象
2.性质
对象b的上转型a的实体是有子类B创建的,但是上转型对象会失去子类B的一些属性和功能。上转型对象具有以下特点:
- 限制:子类新增的
上转型对象不能操作子类新增加的成员变量,不能使用子类新增的方法。即为较子类B失去一些属性和功能,这些属性和功能是新增的。 - 权限:父类的
上转型对象可以操作子类继承或隐藏的成员变量(父类中的)或,也可以使用子类继承的或重写的方法。即为上转型对象可以操纵父类原有的属性和功能,无论这些方法是否被重写。 - 实现多态:上转型对象调用方法时,就是调用子类继承和重写过的方法。而不会是新增的方法,也不是父类原有的方法。
- 变量的处理:上转型对象调用方法时,父类和子类的变量是同时存在的,即使是同名。子类中看到的是子类的变量,父类中看到的是父类中的变量。它们互相隐藏,而同名的方法则是实实在在的覆盖(重写)。
- 可以将对象的上转型对象再强制转换到一个子类对象,强制转换过的对象具有子类所有属性和功能。
3.示例
示例1
class A{
int m;
int getM(){
return m;
}
int seeM(){
return m;
}
}
class B extends A{
int m;
int getM(){
return m+100;
}
}
public class E{
public static void main(String args[]){
B b = new B();
b.m = 20;
System.out.println(b.getM());//【代码1】
A a = b;
a.m = -100; //上转型对象访问的是被隐藏的m
System.out.println(a.getM());//【代码2】上转型对象调用的一定是子类重写的getM()方法
System.out.println(b.seeM());//【代码3】子类继承的seeM()方法操作的m是被子类隐藏的m
}
}
运行结果:
120
120
-100
分析:
引用只能调用其所属类中存在的变量/方法。
- A是父类,B是子类,其中b的类型是B,所以它的操作是对B类中的变量和函数进行的; b.m = 20;System.out.println(b.getM()); 输出120,完全只要在B类中考虑。
- A a = b; a是b的上转型对象,它的类型是A,所以只能对A中的变量和方法操作。但要注意的是,由于多态性,使当其调用了与子类B同名的函数getM(),执行的是子类B中的重写后的操作,而B中因为重载了变量m,导致存在在父类和子类中分别存在了两个相互独立的两个m,它们分别在它们所属类的方法之中被使用,也就是它们互相屏蔽了对方。
- b.seeM()中b调用B类中继承A的方法,因为方法存在于A之中,所以它是对A类中的m进行访问。因此,通过调用父类的方法,子类可以访问父类中被隐藏的成员变量。
java上转型对象操作子类继承或重写的成员变量,要怎么操作?
如果是继承的成员,可以直接操作,子类和父类使用的是同一个成员变量
如果子类重新声明过成员属性,则可以在子类和父类中都提供属性的get,set方法,之后通过方法操作的就是子类中的成员变量。
属性按编译期执行,也就是调用父类的属性
方法按运行期执行,也就是调用子类的方法(??怎么理解)