java解惑(谜题66。。。)

谜题66:一件私事
class Base{
	public String className = "Base";
}

class Sub extends Base{
	private String className = "subclass";
}
public class PrivateMatter {
	public static void main(String[] args) {

		System.out.println(new Sub().className);
	}
}

注意该程序有编译错误。因为子类中的变量比父类中的变量更具限制性的访问权限。而子类的变量是private,访问不了。尽管父类的变量被隐藏了,但是可以通过将子类实例转化为父类来访问它,如下可以打印出Base:System.out.println(((Base)new Sub()).className);
一旦一个方法在子类中被覆盖,你就不能在子类的实例上调用它了(除了在子类内部,通过使用super关键字的方法),然而,你可以通过将子类实例转化为父类来访问被隐藏的域。
谜题67:对字符串上瘾
public class StrungOut {

	public static void main(String[] args) {

		String s = new String("hello");
		System.out.println(s);
	}
}
class String{
	private final java.lang.String s;
	public String(java.lang.String s){
		this.s = s;
	}
	public java.lang.String toString(){
		return s;
	}
}

运行会出现下图错误并报异常:java.lang.NoSuchMethodError: main

java解惑(谜题66。。。)

VM找不到main方法,是因为它并不在那里。一个main方法必须接受一个单一的字符串参数,而此程序中String是我们自己定义的String类,而非java.lang.String类。
谜题68:灰色的阴影
public class Shade {

	public static void main(String[] args) {
		System.out.println(X.Y.Z);
	}
}
class X{
	static class Y{
		static String Z = "Black";
	}
	static C Y = new C();
}
class C{
	String Z= "White";
}

输出的是White。有一条规则决定着程序的行为,即当一个变量和一个类型具有相同的名字,并且它们位于相同的作用域时,变量名具有优先权。相似的,变量名和类型名可以遮掩包名。
注意:编程习惯,变量名小写,类名大写
谜题71:进口税
import static java.util.Arrays.toString;
public class ImportDuty {

	public static void main(String[] args) {

		printArgs(1,2,3,4,5);
	}
	 static void printArgs(Object...args) {
		 System.out.println(toString(args));
	}
}

编译错误,Arrays.toString(Object[])可以完全匹配,为啥出错呢?本例中toString引用的是Object继承而来的toString方法。简单地说, 本身就属于某个范围的成员在该范围内与静态导入相比具有优先权。
可改为:
import  java.util.Arrays;
public class ImportDuty {

	public static void main(String[] args) {

		printArgs(1,2,3,4,5);
	}
	 static void printArgs(Object...args) {
		 System.out.println(Arrays.toString(args)); //[1, 2, 3, 4, 5]
	}
}


谜题:
class Base {
	public static final String PRIZE = "$64,000";
}

public class Sub extends Base {
	public static final String PRIZE = "2 cents";

	public static void main(String[] args) {
		System.out.println(Sub.PRIZE); // 2 cents
	}
}

编译成功并打印出2 cents。
final修饰符对方法和域而言,意味着某些完全不同的事情。对于方法,final意味着该方法不能被覆写(对实例方法而言)或者隐藏(对静态方法而言)。对于域,final意味着该域不能被赋值超过一次。

你可能感兴趣的:(java,编程,C++,c,C#)