Java多态的想法与理解

这里是Java小世界,我认为Java是一个很精妙的语言,闲话少说,今天我想聊的是Java三大特性(封装、继承、多态)之一的多态

这里主要说的是方法重写引起的运行时多态,对于方法重载引起的编译时多态我不太想聊


对于多态的简单解释:在有继承方法重写的条件下,父类引用指向子类对象

Animal a = new Cat(); //自动上转型

多态中的方法调用:

class Animal {
public void eat() {
System.out.println("动物吃东西");
}
}
class Cat extends Animal {
@Override
public void eat() {
System.out.println("猫吃鱼");
}
public void catchMouse() {
System.out.println("猫抓老鼠");
}
}
public class Test {
public static void main(String[] args) {
Animal a = new Cat(); // 向上转型
a.eat(); // 输出"猫吃鱼" - 调用子类重写的方法
// a.catchMouse(); // 编译错误,父类引用无法调用子类特有方法
}
}

多态中成员变量的访问:

class Parent {
int x = 10;
}
class Child extends Parent {
int x = 20;
}
public class Test {
public static void main(String[] args) {
Parent p = new Child();
System.out.println(p.x); // 输出10 - 成员变量不具多态性
}
}

更深一层

而当子类继承了父类的成员变量,并修改了它的值,然后子类在重写的方法中调用了该成员变量,那运行输出的是子类的那个成员变量还是原来父类的成员变量呢?

class Parent {
String value = "Parent"; // 父类的字段
public void printValue() {
System.out.println(value); // 访问字段
}
}
class Child extends Parent {
String value = "Child"; // 子类重新声明了同名字段(隐藏父类的字段)
@Override
public void printValue() {
System.out.println(value); // 访问的是子类的 value
}
}
public class Main {
public static void main(String[] args) {
Parent obj = new Child(); // 多态:父类引用指向子类对象
obj.printValue(); // 输出Child
System.out.println(obj.value); // 输出Parent
}
}

在实际应用时对这个问题是不是很纠结呢?我有一计,如果子类改变的成员变量是原来父类的成员变量的话,那Java继承就乱套了,在实际Java项目中如果子类能改到父类的东西,那么Java的运维就会极其困难且复杂,Java的设计者肯定不会这样去设计,所以子类改到的一定是自己的成员变量。


总结:

成员变量没有多态性,只有方法有多态性。

tips:静态方法、私有方法、final方法、构造方法不具有多态性!