Java:域和静态方法不具有多态性

近日在工程中发现了这么一个bug:妄自以为子类的域可以像方法一样覆盖父类的域或者方法。
具体的情景可以抽象为以下:试图在父类中定义一个域(非private)并赋予初始值,各个子类算法默认情况下使用该域的默认初始值,在必要的情况下想覆盖该域重新定义该值,于是有了这样的代码:

public abstract class AbstractAlogrithm {
	protected int nTimeSpan = 12;
	
	protected void printTimeSpan(){
		System.out.println(nTimeSpan);
	}
}

public class BAlogrithm extends AbstractAlogrithm {
	
}

public class CAlogrithm extends AbstractAlogrithm {
	protected int nTimeSpan = 24;
}

public static void main(String[] args) {
	AbstractAlogrithm obj = new BAlogrithm();
	obj.printTimeSpan();  //12
	
	obj = new CAlogrithm();
	obj.printTimeSpan();  //12
	
	CAlogrithm obja = new CAlogrithm();
	obja.printTimeSpan();  //12
}

域:不并具备多态性
以为后两者的输出应该是24,实际并非如此;java编程思想已经很好的诠释:

一旦你了解了多态机制,可能就会开始认为所有的事物都是可以多态地发生。然而只有普通的方法调用可以是多态的。

实际上CAlogrithm.nTimeSpan和AbstractAlogrithm.nTimeSpan是相互独立的,他们有不同的存储空间;即使在obja中试图打印nTimeSpan,但是你调用的是基类的方法,那么他只能访问到基类的nTimeSpan,自然无法给你想要的值。
某些时候,你可能试图通过将父类强制转型成子类引用,试图访问子类的同名称域,但是任何域的访问都是编译器操作,因此这不是多态的。

静态方法:多态是运行时的行为,而静态方法是编译期就确定的,自然无法实现多态;

那么如何实现我们的意图了,去往罗马的路当然不止一种,以下便是一种:

public class CAlogrithm extends AbstractAlogrithm {
	//protected int nTimeSpan = 24;
	public CAlogrithm() {
		nTimeSpan = 24;
	}
}

还有一些demo,可以参见java编程思想第四版中文,第8.2.5章节:缺陷:域与静态方法

你可能感兴趣的:(JAVA)