9、Java基础---类类型的字段

类类型的字段

一、类类型的字段

public class Car {
	private String name;		// 名称
	private int width;			// 宽度
	private int height;			// 高度
	private int length;			// 长度
	private double x;			// 当前位置的X坐标
	private double y;			// 当前位置的Y坐标
	private double fuel;		// 剩余燃料
	private Day purchaseDay;	// 购买日期

	//--- 构造函数 ---//
	public Car(String name, int width, int height, int length, double fuel,
				  Day purchaseDay) {
		this.name = name;  		this.width = width;	this.height = height;
		this.length = length;	this.fuel = fuel;		x = y = 0.0;
		this.purchaseDay = new Day(purchaseDay); 
	}
	public double getX() { return x; }			// 获取当前位置的X坐标
	public double getY() { return y; }			// 获取当前位置的Y坐标
	public double getFuel() { return fuel; }	// 获取剩余燃料
	public Day getPurchaseDay() {				// 获取购买日期
		return new Day(purchaseDay);
	}
	//--- 显示型号 ---//
	public void putSpec() {
		System.out.println("名称:" + name);
		System.out.println("车宽:" + width  + "mm");
		System.out.println("车高:" + height + "mm");
		System.out.println("车长:" + length + "mm");
	}

	//--- 向X方向移动dx、向Y方向移动dy ---//
	public boolean move(double dx, double dy) {
		double dist = Math.sqrt(dx * dx + dy * dy);		// 移动距离

		if (dist > fuel)
			return false;				// 无法移动 … 燃料不足
		else {
			fuel -= dist;				// 减掉移动距离所消耗的燃料
			x += dx;
			y += dy;
			return true;				// 移动结束
		}
	}
}

private Day purchaseDay;---是用于保存购买日期的字段purchaseDay, 字段的类刚是类类型也就是说,如图所示它不是Day类型的电路(实例)、而是遥控器(引用实例的变量);

this.purchaseDay = new Day(purchaseDay); ---中通过构造函数设置日期,使用new运算符和复制构造函数创建购买日期的实例;创建形参purchaseDay中接收到的日期的副本,并将该副本的引用赋给字段purchaseDay,因此,字段purchaseDay就会引用形参中接收到的日期的副本。

public Day getPurchaseDay() {				// 获取购买日期
		return new Day(purchaseDay);
	}

是购买日期的getter方法这里也使用了复制构造函数、创建购买日期字段的副本、并返同该副本的引用。

二、返回引用的方法

购买日期的getter方法getPurchaseDay并不是直接返回字段purchaseDay的值,而是在调用复制构造函数创建副本之后、再返同该副本的引用, 我们来思考一下这么做的原因。

class CarTester1 {

	public static void main(String[] args) {
		Day d = new Day(2010, 10, 15);
		Car myCar = new Car("爱车", 1885, 1490, 5220, 90.0, d);

		Day p = myCar.getPurchaseDay();
		System.out.println("爱车的购买日期:" + p);

		p.set(1999, 12, 31);		// 改写购买日期(?)

		Day q = myCar.getPurchaseDay();
		System.out.println("爱车的购买日期:" + q);
	}
}

程序的运行结果如下图所示,图a是类Car按照代码进行定义的程序,图b是定义方法getPurchaseDay且接返回字段purchaseDay的值的程序;

myCar是2010 年10月15 日购买的汽乍。1中通过方法getPurchaseDay获取了购买日期,并将其显示出来;
2中对获取的日期 p调用方法set, 将日期设置为1999年12月31日。

3中再次获取并显示购买日期;图a中的购买日期仍然是2010年10月15日,但图b中的购买日期则被改写成了1999年12月31日

图a …方法getPurchaseDay返回new Oay(purchaseDay)

方法getPurchaseDay会创建purchaseDay引用的日期实例的副本,并返回引用目标。1中,由于p被初始化为该副本的引用,因此2中会改写购买日期字段的副本;

3中在确认购买日期时,,会再次创建购买日期的副本,q会引用该副本;因此,购买日期还是2010年10月15日。

图b...方法getPurchaseDay返回purchaseDay

方法getPurchaseDay直接返同购买日期purchaseDay的引用。
1中将p初始化为购买日期字段purchaseDay的引用, 因此,2中改写的是购买日期字段本身;
3中在确认购买日期时,q会引用该日期; 因此,购买日期就变成了改写后的1999年12月31日。

【请注意不要返回引用类型的字段值,因为外部能通过该引用值间接改写值】

二、总结

1、除了用完就舍弃的内容,类和方法的声明中都可以加上public, 这样就可以在任何地方使用;

2、在类中,可以根据需要定义访问器用于获取字段abc的值的getter方法可以定义为getAbc,用于设置值的setter方法可以定义为setAbc;

3、当使用赋值或初始化复制类类型变量的值时,复制的并不是所有字段的值,而是引用目标;当通过方法的参数传递类类型的变量时,传递的是实例的引用;

4、当使用相等运算符比较类类型变量的值时,判断的是引用目标是否相等,而不是判断所有字段的值是否相等;

5、如果重载构造函数,该类的实例构建方法的选择范闱就比较广了。在构造函数的开头, 可以使用this(...)调用同一个类中的构造函数;

6、复制复制构造函数中会接收同一类类型的参数,并复制其全部字段的值,可以根据需要进行定义;

7、不应该将相同或者类似的代码分散在类中。如果要执行的处理在其他的方法或者构造函数中已经实现,就应该调用这个方法或者构造函数,委托其处理;

8、在类中,如果需要一个方法以字符串表示来返回实例的“当前状态”, 可以定义public String toString () { } ,该方法在“类类型变量+字符串” 和”字符串+类类型变量” 的运算中会被自动调用;

9、创建类类型的数组时,类类型变量的全部元素都会被初始化为空引用null ,各个元素是类类型的变量, 并不是实例,必须使用初始化或者赋值,将实例的引用赋给各个元素;

10、注意不要返回引用类型的字段值,这是因为外部能通过该引用值间接改写值。

//--- 二维坐标类 ---//
public class Point2D {
	private int x = 0;			// X坐标
	private int y = 0;			// Y坐标

	public Point2D() { }
	public Point2D(int x, int y) { set(x, y); }
	public Point2D(Point2D p)    { this(p.x, p.y); }

	public int getX() { return x; }
	public int getY() { return y; }

	public void setX(int x)       { this.x = x; }
	public void setY(int y)       { this.y = y; }
	public void set(int x, int y) { setX(x);  setY(y); }

	public String toString() { return "(" + x + "," + y + ")"; }
}
//--- 圆类 ---//
public class Circle {
	private Point2D center;			// 圆心坐标

	private int radius = 0;			// 半径

	public Circle() { center = new Point2D(); }

	public Circle(Point2D c, int radius) {
		center = new Point2D(c);  this.radius = radius;
	}

	public Point2D getCenter() { return new Point2D(center); }
	public int getRadius() { return radius; }

	public void setCenter(Point2D c) {
		center.set(c.getX(), c.getY());
	}
	public void setRadius(int radius) { this.radius = radius; }

	public String toString() {
		return "圆心坐标:" + center.toString() + " 半径:" + radius; 
	}
}
//--- 测试圆和坐标 ---//
public class CircleTester {

	public static void main(String[] args) {
		Point2D[] p = new Point2D[] {
			new Point2D(3, 7), new Point2D(4, 6)
		};
		Circle c1 = new Circle();
		Circle c2 = new Circle(new Point2D(10,15), 5);

		for (int i = 0; i < p.length; i++)
			System.out.println("p[" + i + "] = " + p[i].toString());

		c1.setRadius(10);
		System.out.println("c1 = " + c1.toString());
		System.out.println("c2 = " + c2.toString());
	}
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值