读<<Java解惑>>后的碎嘴子(第七章)

第七章--类问题(第二季)

66.
class Base {
    public String className = "Base";
}
class Derived extends Base {
    private String className = "Derived";
}
public class PrivateMatter {
    public static void main(String[ ] args) {
        System.out.println(new Derived().className);
    }
}
不知道大师出于何种考虑,本章又回到了语言机制本身,结果挺明显,编译不通过,因为Derived的className域是private,都知道父子类方法签名都相同会发生override,但父子类的field名称相同,则会发生hide,把private改成public会ok并打印Derived,但和方法的override完全不是一回事
总结:hide和overload,override不同,是面向对象中一种代表设计错误的机制,不要依赖这样的机制

67.
public class Test {

	public static void main(String[] args) {
		String s = new String("Hello world");
		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;
	}
}
挺有意思的一条,看着挺玄乎的,结果是运行时Error,找不到main入口方法,原因是自定义的String类优先于默认加载的java.lang.String,其实把main(String[] args)改成main(java.lang.String[] args)可以搞定
总结:本条看似娱乐,本质确有意义,定义类名时注意不要用java.lang包里面的,这是现实确实会发生的事情

68.
public class Test {
	println(X.Y.Z);
}

class X {
	static class Y {
		static String Z = "Black";
	}

	static C Y = new C();
}

class C {
	String Z = "White";
}
这个比上条还有意思,是内部类名称Y优先,还是引用变量名称Y优先?答案是White,引用变量名称Y优先,这种比hide现象还难出现的现象称作obscure,这里变量名将优先于类型名
总结:因为这里的例子达成前提是C类型的引用变量Y名称是大写的,所以如按照语言大小写规范来命名,可完全杜绝obscure现象

69.继68条后继续扩展讨论,第一次看到了内部类的extends用法,别的没什么深刻的印象

70.很简单的一条,两个位于不同包,又被default修饰方法,就算方法签名一样也不会发生override

71.
import static java.util.Arrays.toString;
public class Test {

	public static void main(String... args) {
		printArgs(1, 2, 3, 4, 5);
	}
	
	static void printArgs(Object... args) {
		System.out.println(toString(args));
	}
}
结果是编译不通过,编译器选择的是调用由Object继承而来的Object.toString(),这种由于static import功能带来的同名方法冲突,称作shade,和68条中的obscure不同之处在于shade是同类型名称冲突(如方法和方法),而obscure指的是不同类型的名称冲突(如类名和域名)
总结:事实上static import功能现实中应用很少,不要因为耍帅来使用它

72.
class Jeopardy {
    public static final String PRIZE = "$64,000";
}
public class DoubleJeopardy extends Jeopardy {
    public static final String PRIZE = "2 cents";
    public static void main(String[ ] args) {
        System.out.println(DoubleJeopardy.PRIZE);
    }
}
相当简单的一条,根据java的基本知识,final修饰的方法不能被override,但是final修饰的域则只是说明值不能被修改,像例子中就发生了hide,同时这也是一种错误的用法
总结:java中的final关键字在方法和域中具有不同的意义,这并不是一个好的语言设计方法,但是新版本随意新增关键词又会对现有应用本身造成极大的破坏影响

73.关于命名冲突的问题,本章重复了很多次,这条也是,在实际中只需要多留心就可以了,过度地区分hide,obscure和shade也没有什么太大的意义

74.本书已经写到了后期,娱乐的性质更多了一些,在<<Effective Java>>中也详细讨论了设计一个equals方法的几个重要原则

75.本章的最后一条,并没有什么实际的意义,得知了1.4和更早的版本,对于三目运算符的要求是更严格的,第二,三操作数,强制要求它们至少要有父子类型关系
总结:本章最后还总结了override,overload,hide,shade,obscure的意义,对于后三者,可以适当地去体会它们的区别,就当是增加一些技术词汇量
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章