多态中,成员变量被隐藏(hiden),成员方法被覆盖(override)
也就是说,在这个例子中:
public class Test1 {
public static void main(String[] args) {
Father a=new Son();//运用多态,父类的引用指向一个子类的对象
System.out.println(a.i);
a.testMethod();
}
}
class Father{
int i=0;
public void testMethod(){
System.out.println("父类成员方法");
}
}
class Son extends Father{
int i=1;
public void testMethod(){
System.out.println("子类成员方法");
}
}
主函数运行会输出:
0
子类成员方法
如果想让 System.out.println(a.i); 输出的是子类中同名的成员变量,可以使用强制类型转换,例如把这句代码写成:
System.out.println(((Son)a).i);
此时输出的就是:
1
子类成员方法
为什么多态中,成员变量被隐藏,成员方法被覆盖?这种区别如何产生?
个人理解:成员变量是类的属性的一部分,而多态就好比给子类对象披上了父类的 马甲(也就是对父类所有属性的一个描述),成员变量作为这个“马甲”的一部分,自然它的值就是父类的,而成员方法是这个对象怎么做一件事,那么一个对象即使披上马甲,它做事的方式也是按它自己的方式来,而不是按马甲的主人做事的方式。
当然这只是一个比喻的说法,希望有真正了解为什么这么实现的读者能在评论里补充。
同理,静态成员和静态方法也都是类所具有的属性,所以它们在多态中的表现就和成员变量一样,即只能被隐藏,不能被覆盖
例如:
public class Test1 {
public static void main(String[] args) {
Father a=new Son();
System.out.println(a.i);
a.testMethod();
}
}
class Father{
static int i=0;
static public void testMethod(){
System.out.println("父类成员方法");
// System.out.println(i);
}
}
class Son extends Father{
static int i=1;
static public void testMethod(){
System.out.println("子类成员方法");
//System.out.println(i);
}
}
结果是:
0
父类成员方法
多态:某一个事物,在不同时刻(或条件下)表现出来的不同状态。
*
* Java语言中的多态指什么呢? “同一个对象”的行为(方法),在不同的时刻或条件下,表现出不同的效果。
*
* 要实现多态的效果,有前提条件:
* 1. 继承
* 2. 要有方法覆盖
* 3. 父类引用指向子类对象(对象有时也称之为实例)
*
* 多态成员的访问特征:父类引用指向子类对象的时候,如果我们父类引用,去访问子类对象中的成员
*
* 成员变量:
* 编译看左边,运行看左边
*
* 成员方法:
* 编译看左边,运行看右边
*
* 仅从理解的角度来解释:
* 1. 编译看左边: 父类引用指向子类对象,此时编看左边是在说,
* 通过引用变量可以访问到的子类成员的范围,是由引用类型来决定的
*
* a. 迄今为止,我们是怎么去访问一个对象?我们都是通过一个中间人即引用变量,间接访问堆上对象
* b. 也就是说,只有通过引用变量,我才能访问到堆上的对象
*
* 举例:
* 1. 我们如果把对象,当成我们的一台电视机,对于电视机而言,我们只能使用,遥控器去操作电视机
*
* 2. 这也就意味着,遥控器提供了什么样的功能,那我们只能使用,遥控器提供的功能,操作电视机
* 此时即使电视机提供了很多功能可以使用,但是如果遥控器提供了,极其有限的功能
*
* 3. 这意味着,我们可以使用的电视机的功能,被遥控器给限制了
*
* 所以,回到java程序,访问对象的时候,引用变量,就是我们用来操作对象的"遥控器",所以引用变量的类型
* 决定了,可以访问到的成员的范围。
*
* 2. 对于成员方法的,运行(结果)看 右边(多态)
* 就是说对于成员方法而言,通过引用变量,实际访问到的行为(方法), 是由引用实际指向的对象来决定的额
*
* 3. 对于成员变量,运行看左边
* 一个对象 属性(成员变量) 和 行为,一个对象的属性(成员变量表示),表示了一对象的外貌
* 1. 在多态中,此时对于子类对象而言,把子类对象赋值给父类类型的引用,就相当于给子类对象
* 披上了一个父类类型马甲, 因此,该子类对象开起来,就是一个父类对象(外貌特征,
* 表现出的就应该是父类的外貌特征)
*
* 1. 考虑到多态发生的条件是,
* 1.继承
* 2.方法覆盖
* 3.父类引用指向子类实例
* 所以哪些方法(行为),实现不了多态效果呢?不能在子类中被覆盖的方法(不能被继承的方法)
* a. 父类中的private方法(不能被子类覆盖)
* b. 父类中的构造方法(不能被子类继承)
* c. 父类中的静态方法(不能被子类覆盖)
* d. 父类中被final修饰的方法(不能被子类覆盖)