Thking in java(第四版)-查缺补漏(6-8章)

本文介绍了Java编程中的实用技巧,包括编译.java文件、静态import的使用、单例模式的实现、代理模式的应用等,并深入探讨了继承与多态的概念及其实现方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

背景

继续下面的查缺补漏

1.编译.java文件

当编译.java文件时,在.java文件中的每个类都会有一个输出文件,而该输出文件的名称与.java文件中每个类

名称相同,只是多了一个后缀名.class

 2.静态import

如下所示:

package tools;
import java.io.*;
public class Print {
	//Print with a newline:
	public static void print(Object obj){
		System.out.println(obj);
	}
	//Print a newline by itself:
	public static void print(){
		System.out.println();
	}
	//Print with no line break:
	public static void printnb(Object obj){
		System.out.print(obj);
	}
	//The new java SE5 printf() (from c):
	public static PrintStream printf(String format,Object... args){
		return System.out.printf(format,args);
	}
}

上面定义了一个Print类,里面有四个静态方法。

package c06;
import static tools.Print.*;
public class PrintTest {
	public static void main(String[] args){
		print("Available from now on!");
		print(100);
		print(100L);
		print(3.14159);
	}
}

静态import的语法:在import 后面加 static 。比如要使用Print类的静态方法,就要导入在tools包下的Print类后面

还要加上“.*”。静态import是针对静态方法,对于普通的方法是不起作用的。

3.取得对某成员的访问权限

提供访问器(accessor)和变异器(mutator)方法(也称作get/set方法),以读取和改变数值。

4.类访问权限

只有两个,包访问权限或public

5.singleton(单例)

例如:

class Soup2{
    private Soup2(){}
    private static Soup2 ps1=new Soup2();
    public static Soup2 access(){
        return ps1;
    }
}

单例:一种设计模式,只能创建一个对象。上面的代码中创建了一个静态Soup2对象,有且仅有一个,

只能通过access()方法来访问。

6.代理

我们通过继承,在子类中父类的所有方法都暴露出来,我们可以通过代理,选择只提供在成员对象中

的方法的子集。例如:

package c07;

public class SpaceShipControls {
	void up(int velocity){}
	void down(int velocity){}
	void left(int velocity){}
	void right(int velocity){}
	void forward(int velocity){}
	void back(int velocity){}
	void turboBoost(){}
}

上面是一个飞船的控制模块

package c07;

public class SpaceShipDelegation {
	private String name;
	private SpaceShipControls controls=
			new SpaceShipControls();
	public SpaceShipDelegation(String name){
		this.name=name;
	}
	//Delegated methods:
	public void back(int velocity){
		controls.back(velocity);
	}
	public void forward(int velocity){
		controls.forward(velocity);
	}
	public void left(int velocity){
		controls.left(velocity);
	}
	public void right(int velocity){
		controls.right(velocity);
	}
	public void turboBoost(){
		controls.turboBoost();
	}
	public void up(int velocity){
		controls.up(velocity);
	}
	public static void main(String[] args){
		SpaceShipDelegation protector=new SpaceShipDelegation("NSEA Protector");
		protector.forward(100);
	}
}

代理的语法:通过组合的方式,把成员对象设置成private,再通过方法调用成员对象的方法。

我们可以选择开放成员对象的某些方法,而不用全部暴露。

7.@Override

public class Lisa extends Homer{
	@Override void doh(Milhouse m){
		System.out.println("doh(Milhouse)");
	}
}

@Override 不是关键字,但是可以防止你在不想重载时而意外地进行了重载。

8.用组合还是继承

问一问自己是否需要从新类向基类进行向上转型。如果需要向上转型,就用继承。

9.多态

通过分离做什么和怎么做,从另一个角度将接口和实现分离开来。

多态也称作动态绑定、后期绑定、运行时绑定。

多种类型视为同一种类型来处理,可以用相同的代码运行在这些不同类型之上。

如果某个方法是静态的,它的行为就不具有多态性。静态方法是与类,而并非与单个对象相关联。

任何域访问操作都将由编译器解析,因此不是多态的。

10.继承与清理

如果确实遇到清理的问题,就必须为新类创建dispose()方法,由于继承的缘故,如果我们有其他作为垃圾回收

一部分的特殊清理动作,就必须在导出类中覆盖dispose()方法。当覆盖为继承类的dispose()方法时,就要调用

基类版本的dispose()方法,否则基类的清理动作就不会发生。

如果存在共享成员对象的情况,就需要使用引用计数来跟踪访问共享对象的对象的数量。例如:

package c08;
import static tools.Print.*;
class Shared{
	private int refcount=0;
	private static long counter=0;
	private final long id=counter++;
	public Shared(){
		print("Creating "+this);
	}
	public void addRef(){	refcount++;}
	protected void dispose(){
		if(--refcount==0)
			print("Disprsing"+this);
	}
	public String toString(){	return "Shared"+id;}
}
class Composing{
	private Shared shared;
	private static long counter=0;
	private final long id=counter++;
	public Composing(Shared shared){
		print("Creating"+this);
		this.shared=shared;
		this.shared.addRef(); 
	}
	protected void dispose(){
		print("disposing"+this);
		shared.dispose();
	}
	public String toString(){	return "Composing"+id;}
}
public class ReferenceCounting {
	public static void main(String[] args){
		Shared shared=new Shared();
		Composing[] composing={
				new Composing(shared),
				new Composing(shared),
				new Composing(shared),
				new Composing(shared),
				new Composing(shared),
		};
		for(Composing c:composing)
			c.dispose();
	}
}

11.协变返回类型

在导出类中的被覆盖方法可以返回基类方法的返回类型的某种导出类型。协变返回类型允许返回更具体的Wheat类型。

例如:

package c08;
class Grain{
	public String toString(){	return "Grain";}
}
class Wheat extends Grain{
	public String toString(){	return "Wheat";}
}
class Mill{
	Grain process(){return new Grain();}
}
class WheatMill extends Mill{
	Wheat process(){return new Wheat();}
}
public class CovariantReturn {
	public static void main(String[] args){
		Mill m=new Mill();
		Grain g=m.process();
		System.out.println(g);
		m=new WheatMill();
		g=m.process();
		System.out.println(g);
	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值