引用传递分析实例

一、引用传递

引用传递是整个Java的精髓所在。

引用传递的核心意义:同一块堆内存空间可以被不同的栈内存所指向,不同栈内存可以对同一堆内存进行内容的修改。

范例:第一道引用传递范例

class Message {
	private int num = 10;

	public Message(int num) {
		this.num = num;
	}

	public void setNum(int num) {
		this.num = num;
	}

	public int getNum() {
		return this.num;
	}

}

public class TestDemo {
	public static void main(String args[]) {
		Message msg = new Message(30);
		fun(msg);
		System.out.println(msg.getNum());
	}

	public static void fun(Message temp) {
		temp.setNum(100);
	}
}

范例:第二道引用传递范例

public class TestDemo {
	public static void main(String args[]) {
		String msg = "Hello";
		fun(msg);
		System.out.println(msg);
	}

	public static void fun(String temp) {
		temp = "World";
	}
}

以上的题目只有一个解决思路:String类对象的内容一旦声明则不可改变,对象内容的改变依靠的是引用地址的改变。

范例:第三道引用传递

class Message {
	private String info = "nihao";

	public Message(String info) {
		this.info = info;
	}

	public void setInfo(String info) {
		this.info = info;
	}

	public String getInfo() {
		return this.info;
	}

}

public class TestDemo {
	public static void main(String args[]) {
		Message msg = new Message("Hello");
		fun(msg);
		System.out.println(msg.getInfo());
	}

	public static void fun(Message temp) {
		temp.setInfo("World");
	}
}

但是以上的内存描述并不严格,因为在程序里面,info也是一个String类的对象,所以要想描述的更加清楚,应该采用如下的内存关系图:

结论:虽然String属于类,属于引用类型,但是由于其内容不可改变的特点,很多的时候就直接把String当成基本数据类型使用,即:每一个String变量只能够保存一个数据。


二、引用传递实际应用

假如说,每一个人都有一辆车或没有车,要求可以通过面向对象的方式描述以上的关系。

下面先抛开Java不看,如果说现在要求你来设计可以满足以上数据存储的数据库,创建语句:

应该设计出两张表:人员表和汽车表。如果换回到程序思路,也应该创建两个类。

简单Java类的编写原则:

· 类名称 = 表名称;

· 属性名称(类型) = 表字段(类型);

· 一个实例化对象 = 一行记录;

· 多个实例化对象(对象数组) = 多行记录;

· 引用关系 = 外键约束;

范例:代码设计如下

class Member {
	private int mid;
	private String name;
}

class Car {
	private String pname;
}

以上实现了两个独立的类,并且没有任何的外键关系,但是在表中可以通过外键描述关系,那么在类之中可以采用引用来描述关系。

class Member {
	private int mid;
	private String name;
	// car有实例化对象表示有车
	// car为null表示没有车
	private Car car;// 表示属于人的车
}

class Car {
	private Member member;// 车属于一个人
	private String pname;
}

一定要记住的是Member和Car都是一个独立的对象,而后通过产生对象再发生关系。

class Member {
	private int mid;
	private String name;
	// car有实例化对象表示有车
	// car为null表示没有车
	private Car car;// 表示属于人的车

	public Member(int mid, String name) {
		this.mid = mid;
		this.name = name;
	}

	public String getInfo() {
		return "人员编号:" + mid + ",姓名:" + name;
	}
}

class Car {
	private Member member;// 车属于一个人
	private String pname;

	public Car(String pname) {
		this.pname = pname;
	}

	public String getInfo() {
		return "车的名字:" + pname;
	}
}

当Member或Car的对象产生之后,那么就应该为这两个对象设置彼此的关系。

class Member {
	private int mid;
	private String name;
	// car有实例化对象表示有车
	// car为null表示没有车
	private Car car;// 表示属于人的车

	public Member(int mid, String name) {
		this.mid = mid;
		this.name = name;
	}

	public String getInfo() {
		return "人员编号:" + mid + ",姓名:" + name;
	}

	public void setCar(Car car) {
		this.car = car;
	}

	public Car getCar() {
		return this.car;
	}
}

class Car {
	private Member member;// 车属于一个人
	private String pname;

	public Car(String pname) {
		this.pname = pname;
	}

	public String getInfo() {
		return "车的名字:" + pname;
	}

	public void setMember(Member member) {
		this.member = member;
	}

	public Member getMember() {
		return this.member;
	}
}

以上的程序类完成之后,下面需要对程序进行测试,但是程序的测试要求分两步:

· 第一步:根据定义的结构关系定义数据;

· 第二步:根据定义的结构关系取出数据;

public class TestDemo {
	public static void main(String args[]) {
		// 第一步:设置数据
		Member m = new Member(1, "张艺兴");// 独立对象
		Car c = new Car("奔驰");// 独立对象
		m.setCar(c);// 一个人有一辆车
		c.setMember(m);// 一辆车属于一个人
		// 第二步:取出关系
		// 通过人找到车的信息
		System.out.println(m.getCar().getInfo());
		// 通过车找到人的信息
		System.out.println(c.getMember().getInfo());
	}
}

下面可以进一步的设计,例如:每个人都有自己的孩子,孩子还可能有车。那么有两种设计方法:

  • 方法一:设计一个孩子类,如果有孙子,设计一个孙子类,如果有……

  • 方法二:一个人的孩子一定还是一个人,与人的类本质没有区别,可以在Member类里面设计一个属性表示孩子,其类型就是Member。
    class Member {
    	private int mid;
    	private String name;
    	private Member child;// 表示孩子
    	// car有实例化对象表示有车
    	// car为null表示没有车
    	private Car car;// 表示属于人的车
    
    	public Member(int mid, String name) {
    		this.mid = mid;
    		this.name = name;
    	}
    
    	public String getInfo() {
    		return "人员编号:" + mid + ",姓名:" + name;
    	}
    
    	public void setChild(Member child) {
    		this.child = child;
    	}
    
    	public Member getChild() {
    		return this.child;
    	}
    
    	public void setCar(Car car) {
    		this.car = car;
    	}
    
    	public Car getCar() {
    		return this.car;
    	}
    }
    
    class Car {
    	private Member member;// 车属于一个人
    	private String pname;
    
    	public Car(String pname) {
    		this.pname = pname;
    	}
    
    	public String getInfo() {
    		return "车的名字:" + pname;
    	}
    
    	public void setMember(Member member) {
    		this.member = member;
    	}
    
    	public Member getMember() {
    		return this.member;
    	}
    }
    
    public class TestDemo {
    	public static void main(String args[]) {
    		// 第一步:设置数据
    		Member m = new Member(1, "张艺兴");// 独立对象
    		Member chd = new Member(2, "欢欢");
    		Car c = new Car("奔驰");// 独立对象
    		Car cc = new Car("法拉利");
    		m.setCar(c);// 一个人有一辆车
    		c.setMember(m);// 一辆车属于一个人
    		chd.setCar(cc);
    		cc.setMember(chd);
    		m.setChild(chd);
    		// 第二步:取出关系
    		// 通过人找到车的信息
    		System.out.println(m.getCar().getInfo());
    		// 通过车找到人的信息
    		System.out.println(c.getMember().getInfo());
    		// 通过人找到孩子
    		System.out.println(m.getChild().getInfo());
    		// 通过人找到他孩子的车
    		System.out.println(m.getChild().getCar().getInfo());//代码链
    	}
    }

    还可以针对于引用做进一步的描述,例如:要求描述电脑,电脑由主机、显示器、键盘、内存、CPU、硬盘、显卡组成,那么怎么通过代码描述呢?

    class 键盘{}
    class 鼠标{}
    class CPU{}
    class 硬盘{}
    class 内存{}
    class 显示器{}
    class 主板{}
    class 主机{
    	private CPU 对象[];
    	private 硬盘 对象[];
    	private 主板 对象;
    	private 内存 对象[];
    }
    class 电脑{
    	private 主机 对象;
    	private 显示器 对象[];
    	private 键盘 对象;
    	private 鼠标 对象;
    }

    这样的设计思路在Java之中称为合成设计模式。

    面向对象的设计方式应该说所有的设计思路来源于现实。

    引用是实现两个不同类型之间互相关联的主要手段。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值