组合,继承和代理

1.什么是代理

代理是组合和继承的中庸之道,类B包含类A(相当于组合),但是类B包含类A的所有方法(相当于继承),这个其实听起来觉得还挺乱,但其实真正写代码的时候,你觉得继承从理论上就说不通,自然会使用组合,然后你想将A类的方法也提供给客户端使用,自然就会使用代理这种方法。
代码如下:
package cn.com.codog.third;

public class A {

	protected int i;

	A(int i) {
		this.i = i;
	}
	
	protected void print(){
		System.out.println("A" + this.i);
	}
	
	@Override
	public String toString() {
		return "i = " + this.i;
	}
}
package cn.com.codog.third;

public class B {

	private A a;

	B(int i) {
		a = new A(i);
	}

	public void print() {
		a.print();
	}
	
	public static void main(String[] args) {
		B b = new B(89);
		b.print();
	}
}
输出如下:
A89

2.尽量使用父类声明

这里有一个小技巧,比如HashMap是Map的子类,当你没有特殊需求的时候,一般写作
Map map = new HashMap();
这样使得你的代码灵活性高


3.final关键字

3.1 final属性

当作用于属性或者局部变量的时候,分为final的属性和final的引用,当final是引用的时候,引用的对象内容是可以变化的,但是引用不可以变,如下代码:
package cn.com.codog.third;

public class FinalTest {

	final int i;
	final int a = 100;
	static final int b = 100;
	//static final int c;//The blank final field c may not have been initialized
	final A af = new A(100);
	static final A saf = new A(100);
	FinalTest(){
		i = 100;
		af.i =200;//af的引用是final的,但是类的内容是可以变化的
		//af = new A(200);//The final field FinalTest.af cannot be assigned
		//saf = new A(200);//The final field FinalTest.af cannot be assigned
		//c = 100;//The final field FinalTest.c cannot be assigned
	}
}

3.2 final参数

final参数的意思是在方法内部不能改变这个参数:
public void withFinal(final int i){
		i++;//The final local variable i cannot be assigned. It must be blank and not using a compound assignment
	}

3.3 final方法

public class A {

	protected int i;

	A(int i) {
		this.i = i;
	}
	
	protected void print(){
		System.out.println("A" + this.i);
	}
	
	final void printA(){
		System.out.println("A");
	}
	@Override
	public String toString() {
		return "i = " + this.i;
	}
public class C extends A{
	
	C(int i){
		super(i);
	}
	
	/*final void printA(){
		
	}*///Cannot override the final method from A
}
final方法是防止继承的,和private类似,但是final方法在子类中还可以访问,只是不能修改方法的实现

3.3 final类

public final class A {

	protected int i;

	A(int i) {
		this.i = i;
	}
	
	protected void print(){
		System.out.println("A" + this.i);
	}
	
	final void printA(){
		System.out.println("A");
	}
	@Override
	public String toString() {
		return "i = " + this.i;
	}
}

/*public class C extends A{//The type C cannot subclass the final class A
	
	C(int i){
		super(i);
	}
	
	final void printA(){
		
	}//Cannot override the final method from A
}*/
但是其实除了final域和final参数之外,其他的情况还是很少使用的。


4.继承与初始化

当继承与初始化放在一起是很有趣的,代码如下:
public class Father {

	public Father() {
		System.out.println("Father()");
	}
	private InnerClass b = new InnerClass(2);
	private static InnerClass a = new InnerClass(0);
}

public class Child extends Father{

	public Child(){
		System.out.println("Child()");
	}
	private InnerClass b = new InnerClass(3);
	private static InnerClass a = new InnerClass(1);
	
	public static void main(String[] args) {
		Father f = new Child();
	}
}
public class InnerClass {

	private int i;
	public InnerClass(int i) {
		System.out.println(i);
	}
}
0
1
2
Father()
3
Child()
所以总的顺序是先父类static-->子类的static-->父类的成员-->父类的构造函数-->子类的成员-->子类的构造函数





相关内容:
前言
对象和类型
操作符和引用
流程控制语句
初始化和清理
访问控制
组合和继承
接口和多态
接口与抽象类
容器
异常
类型信息
泛型
数组
IO系统
枚举类型
注解
多线程
总结