java8面向对象编程:引用传递实例分析
2、知识点
2.1、上次课程的主要知识点
对象比较。
2.2、本次预计讲解的知识点
将生活与程序联系在一起。
3、具体内容(★★★★★)
一直以来我一直强调:程序是生活的浓缩。生活的抽象,也就是说日常生活中的一切概念都可以通过程序来进行描述,那么下面描述这样的一个程序:一个人有一辆车。
在描述以上概念之前,希望可以有一个对比,如果说现在你进行数据库的设计,要描述以上的操作形式,你的数据表该如何设计呢?
|
CREATE TABLE person (
pid NUMBER ,
name VARCHAR2(50) ,
CONSTRAINT pk_pid PRIMARY KEY(pid)
) ;
CREATE TABLE car(
pid NUMBER ,
cname VARCHAR2(50) ,
CONSTRAINT pk_pid2 PRIMARY KEY(pid) ,
CONSTRAINT fk_pid2 FOREIGN KEY(pid) REFERENCES person(pid)
) ;
|
如果说现在要是进行类的设计,也需要两个类:Person、Car,那么就可以发现两者的关联:
· 表名称 = 类名称;
· 表的字段 = 类属性;
· 表的一行记录 = 一个实例化对象;
· 表的多行记录 = 对象数组;
· 表的外键关系 = 引用设置。
正是因为有这样的匹配关系,所以在实际的开发过程之中,简单Java类不是凭空设计的,往往都要与数据表的结构一一对应。
范例:定义类
|
class Person {
private int pid ;
private String name ;
// car == null表示这个人没有车
private Car car ; // 一个人有一辆车
public Person(int pid,String name) {
this.pid = pid ;
this.name = name ;
}
public String getPersonInfo() {
return "编号:" + this.pid + ",姓名:" + this.name;
}
public void setCar(Car car) {
this.car = car ;
}
public Car getCar() {
return this.car ;
}
}
class Car {
private String cname ;
// 如果人有车了,那么必须同时修改车与人的关系
private Person person ; // 一辆车属于一个人
public Car(String cname) {
this.cname = cname ;
}
public void setPerson(Person person) {
this.person = person ;
}
public Person getPerson() {
return this.person ;
}
public String getCarInfo() {
return "汽车名称:" + this.cname ;
}
}
|
此时程序中使用了自定义的数据类型,Person、Car都是类。那么随后的操作主要是进行代码的测试,但是测试要分为两步:第一步设置内容,第二步取出内容。
|
public class TestDemo {
public static void main(String args[]) {
// 第一步:根据已有的结构设置内容
Person per = new Person(1,"陶摔跤") ;
Car car = new Car("BYD F3") ;
per.setCar(car) ; // 现在人有车了
car.setPerson(per) ; // 现在车属于一个人了
// 第二步:根据关系取出数据
System.out.println(per.getPersonInfo()) ;
System.out.println(per.getCar().getCarInfo()) ; // 代码链
System.out.println(car.getPerson().getPersonInfo()) ;
}
}
|
[图片上传失败...(image-1ff85f-1552140916956)]
代码链别看单词,就看每一个方法的返回值是什么东西。如果是一个类的对象则可以继续调用该类的方法。
那么也可以针对于此代码进行进一步的扩展。每个人还有孩子,每个孩子也可能有车。实际上这里面需要注意的是,每一个人的孩子一定还是人,并且具备有跟人同样的属性信息,那么就可以在Person里面设计一个孩子的属性。
|
class Person {
private int pid ;
private String name ;
private Person child ; // 孩子
// car == null表示这个人没有车
private Car car ; // 一个人有一辆车
public Person(int pid,String name) {
this.pid = pid ;
this.name = name ;
}
public void setChild(Person child) {
this.child = child ;
}
public Person getChild() {
return this.child ;
}
public String getPersonInfo() {
return "编号:" + this.pid + ",姓名:" + this.name;
}
public void setCar(Car car) {
this.car = car ;
}
public Car getCar() {
return this.car ;
}
}
class Car {
private String cname ;
// 如果人有车了,那么必须同时修改车与人的关系
private Person person ; // 一辆车属于一个人
public Car(String cname) {
this.cname = cname ;
}
public void setPerson(Person person) {
this.person = person ;
}
public Person getPerson() {
return this.person ;
}
public String getCarInfo() {
return "汽车名称:" + this.cname ;
}
}
public class TestDemo {
public static void main(String args[]) {
// 第一步:根据已有的结构设置内容
Person per = new Person(1,"陶摔跤") ;
Person chd = new Person(2,"陶五") ; // 有了孩子
Car car = new Car("BYD F3") ;
Car c = new Car("法屁利 M3") ;
per.setCar(car) ; // 现在人有车了
car.setPerson(per) ; // 现在车属于一个人了
per.setChild(chd) ; // 一个人有一个孩子
chd.setCar(c) ; // 孩子有车
// 第二步:根据关系取出数据
// 找到一个人的孩子的信息
System.out.println(per.getChild().getPersonInfo()) ;
// 通过父亲的车找到父亲的信息,找到父亲的孩子的车的信息
System.out.println(car.getPerson().getChild().getCar().getCarInfo()) ;
}
}
|
[图片上传失败...(image-931203-1552140916956)]
引用的关系可以描述出不同类之间的引用关系。
在现实生活中这样的设计实质上并不麻烦了。理论上任何的事物都可以进行这样的整合。
范例:抽象出衣服
|
class 袖子 {}
class 衣领 {}
class 衣服 {
private 袖子 左 ;
private 袖子 右 ;
private 衣领 对象 ;
}
|
范例:电脑抽象
|
class 内存 {}
class 硬盘 {}
class 显卡 {}
class 主板 {
private CPU 对象 ;
private 内存 对象 [] ;
private 硬盘 对象 [] ;
private 显卡 对象 [] ;
}
class CPU {}
class 键盘 {}
class 鼠标 {}
class 电脑 {
private 主板 对象 ;
private 鼠标 对象 ;
private 键盘 对象 ;
}
|
此处也同样属于引用。这样的形式的代码在设计模式上讲称为合成设计模式。
4、总结
1、 不要把程序只当程序;
2、 引用传递除了进行数据的分析之外,还需要掌握类与类的联系使用;
3、 代码链的使用必须熟练。
5、总结
1、请写出Java的数据类型划分以及默认值。
• 基本数据类型:是进行内容的操作,而不是内存的操作;
|- 数值型:
|- 整型:byte、short、int、long; 默认值:0
|- 浮点型:float、double; 默认值:0.0
|- 字符型:char; 默认值:'\u0000'
|- 布尔型:boolean; 默认值:false。
• 引用数据类型:在数据交互过程之中会占用内存空间指向
|- 分为:数组、类、接口; 默认值:null。
2、请写出“&”和“&&”、“|”和“||”的区别?
· 在逻辑运算中:
|- 与操作表示判断的若干条件要同时返回true,结果才是true,分为两种:
|- “&”:所有的判断条件都要进行判断,不管前面的判断结果是什么;
|- “&&”:在进行条件判断时,如果前面的条件返回了false,后面的判断不再进行,属于短路与;
|- 或操作表示判断的若干条件返回一个true,结果就是true,全为false,结果才是false,分为两种:
|- “|”:所有的判断条件都要进行判断;
|- “||”:在进行若干个条件判断时,如果前面有条件返回了true,后面的判断将不再进行,直接返回true;
· 在位运算中:
|- “&”:表示进行位与操作,位与操作中有两个内容都为1结果才是1,有一个为0计算结果为0;
|- “|”:表示进行位与操作,位与操作中有两个内容有一个为1结果就是1,全为0时结果才为0;
3、请解释CLASSPATH的作用;
使用java命令解释程序的时候,JVM会自动的根据CLASSPATH所指定的路径加载所需要的类,一般都会设置一个当前所在路径加载为CLASSPATH,内容是“.”, 设置方式“SET CLASSPATH=路径”;
4、【SQL】查询出每个雇员的编号、姓名、职位、工资、领导姓名、工资等级、部门名称;
SELECT e.empno,e.ename,e.job,e.sal,m.ename,s.grade,d.dname
FROM emp e,emp m,salgrade s,dept d
WHERE e.mgr=m.empno(+)
AND e.sal BETWEEN s.losal AND s.hisal
AND e.deptno=d.deptno ;
5、【SQL】请查询出公司每个工资等级的人数、平均工资、平均雇佣年限。
SELECT s.grade ,COUNT(e.empno),AVG(e.sal),AVG(MONTHS_BETWEEN(SYSDATE,hiredate)/12)
FROM emp e,salgrade s
WHERE e.sal BETWEEN s.losal AND s.hisal
GROUP BY s.grade ;