Java编程思想第八章总结+练习

多态的作用是消除类型间的耦合。对象可以作为自己本身的类型使用,也可以作为他的基类使用。

练习一:

class Cycle{
	void print() {
		System.out.println("Cycle");
	}
}

class Unicycle extends Cycle{
	void print() {
		System.out.println("Unicycle");
	}
}

class Bicycle extends Cycle{
	void print() {
		System.out.println("Bicycle");
	}
}

class Tricycle extends Cycle{
	void print() {
		System.out.println("Tricycle");
	}
}
public class Test1 {
	static void print(Cycle temp) {
		temp.print();
	}
	public static void main(String[] args) {
		Unicycle uc=new Unicycle();
		Bicycle bc=new Bicycle();
		Tricycle tc=new Tricycle();
		print(uc);
		print(bc);
		print(tc);
	}
}

这个代码可以运行,需要了解绑定的知识。绑定是将一个方法调用同一个方法主体关联起来,分为前期绑定和后期绑定。c语言只有前期绑定。

这个程序得益于后期绑定,根据运行时对象的类型进行绑定。java中除了static和final方法,其他方法都是后期绑定的。

练习二:

import java.util.Random;

class Shape{
	void draw() {}
	void erase() {}
}

class Circle extends Shape {
	@Override
	void draw() {
		System.out.println("Circle.draw()");
	}
	@Override
	void erase() {
		System.out.println("Circle.erase()");
	}
}
class Square extends Shape{
	@Override
	void draw() {
		System.out.println("Square.draw()");
	}
	@Override
	void erase() {
		System.out.println("Square.draw()");
	}
}
class Triangle extends Shape{
	@Override
	void draw() {
		System.out.println("Triangle.draw()");
	}
	@Override
	void erase() {
		System.out.println("Triangle.erase()");
	}
}
class RandomShapeGenerator{
	private Random rand =new Random(42);
	Shape next() {
		switch(rand.nextInt(3)) {
		default:
		case 0:return new Square();
		case 1:return new Circle();
		case 2:return new Triangle();
		}
	}
}
public class Test2 {
	private static RandomShapeGenerator gen=new RandomShapeGenerator();
	public static void main(String[] args) {
		Shape[] s=new Shape[9];
		for(int i=0;i<s.length;i++) {
			s[i]=gen.next();
		}
		for(Shape i:s) {
			i.draw();
			i.erase();
		}
	}
}

练习九:

import java.util.Random;

class Rodent{
	void voice() {}
	void eat() {}
}
class Mouse extends Rodent {
	@Override
	void voice() {
		System.out.println("Zhi");
	}
	@Override
	void eat(){
		System.out.println("everything");
	}
}
class Gerbil extends Rodent{

	@Override
	void voice() {
		System.out.println("perhaps Zhi");
	}

	@Override
	void eat() {
		System.out.println("perhaps everything");
	}
	
}
class Hamster extends Rodent{

	@Override
	void voice() {
		System.out.println("I don't know");
	}

	@Override
	void eat() {
		System.out.println("I don't know, maybe everything");
	}
	
}
class RandomRodentGenerator{
	private Random rand =new Random(42);
	Rodent next() {
		switch(rand.nextInt(3)) {
		default:
		case 0: return new Mouse();
		case 1: return new Gerbil();
		case 2: return new Hamster();
		}
	}
}
public class Test9 {
	private static RandomRodentGenerator gen=new RandomRodentGenerator();
	public static void main(String[] args) {
		Rodent[] array=new Rodent[9];
		for(int i=0;i<array.length;i++) {
			array[i]=gen.next();
		}
		for(Rodent temp:array) {
			temp.eat();
			temp.voice();
		}
	}
}

练习十:

class Base{
	String out() {
		return "hello";
	}
	void print() {
		System.out.println(out());
	}
}
class Inherit extends Base{
	@Override
	String out() {
		return "nihao";
	}
}
public class Test10 {
	public static void main(String[] args) {
		Base sample =new Inherit();
		sample.print();
	}
}

private被自动认为是final方法,对导出类是屏蔽的。只有非private方法才能被覆盖。导出类中基于基类中的private方法,最好采用不同的名字。

注意:只有普通的方法调用可以是多态的。直接访问某个域,这个访问将在编译期进行解析,此时不是多态的。如果某个方法是静态的,他的行为也不具有多态性。切记,静态方法是和类,而非单个对象相关联。

构造器其实是static方法,只不过隐藏起来了。基类的构造器总在导出类的构造过程中被调用,且按照继承层次逐渐向上链接,以使得每个基类的构造器被调用。对象调用遵循下面规则

1.调用基类构造器。这个步骤会不断地反复递归下去,首先是构造这种层次结构的根,然后是下一层导出类,以此类推。

2.若构造器内部有多态方法,则会调用。(注意在所有事情发生前,分配给对象的储存空间均是初始化为二进制的0)

3.按声明顺序调用成员的初始化方法

4.调用导出类构造器主体。

清理中销毁顺序和初始化顺序相反。 

编写构造器有效的准则:用尽可能简单的方法使得对象进入正常状态;如果可以,避免调用其他方法。构造器内唯一能安全调用的是基类中final方法(private也可以),原因是这些方法不能被覆盖。

协变返回类型,导出类中的被覆盖方法可以返回基类方法的导出类型。

注意导出类中接口的扩展部分不能被基类访问,一旦向上转型,就不能调用新方法。java中所有类型转换都会得到检查(RTTI运行时类型识别),如果想通过父类引用访问导出类对象的扩展,要向下转型。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值