Java——引用传递实例分析(进阶分析、对象比较、类与类的关联实现)

举报
Winter_world 发表于 2021/09/29 00:13:11 2021/09/29
【摘要】 目录 1、引用传递进阶分析 2、对象比较 3、引用传递实际应用 4、总结   1、引用传递进阶分析 引用传递是Java的精髓所在,也是初学者比较难学的地方。下面通过三个程序进行分析。 【举例】:第一个,较简单 protected void onCreate(Bundle savedInstanceState...

目录

1、引用传递进阶分析

2、对象比较

3、引用传递实际应用

4、总结


 

1、引用传递进阶分析

引用传递是Java的精髓所在,也是初学者比较难学的地方。下面通过三个程序进行分析。

【举例】:第一个,较简单


  
  1. protected void onCreate(Bundle savedInstanceState) {
  2. super.onCreate(savedInstanceState);
  3. Demo demo = new Demo(100);
  4. fun(demo);
  5. System.out.println(demo.getNum());//输出30
  6. }
  7. private void fun(Demo temp) {
  8. temp.setNum(30);
  9. }
  10. class Demo{
  11. private int num =10;
  12. public Demo(int num){
  13. this.num = num;
  14. }
  15. public int getNum() {
  16. return num;
  17. }
  18. public void setNum(int num) {
  19. this.num = num;
  20. }
  21. }

【举例】:第二个


  
  1. protected void onCreate(Bundle savedInstanceState) {
  2. super.onCreate(savedInstanceState);
  3. String str = "hello";
  4. fun(str);
  5. System.out.println(str); //输出hello
  6. }
  7. public static void fun(String temp) {
  8. temp = "world";
  9. }

以上输出的是hello,注意字符串一旦声明则不可改变,字符串内容的改变依靠的是引用的改变实现,观察如下内存分析图:

【举例】:第三个


  
  1. protected void onCreate(Bundle savedInstanceState) {
  2. super.onCreate(savedInstanceState);
  3. Demo demo = new Demo("world");
  4. fun(demo);
  5. System.out.println(demo.getMsg());//输出MLDN
  6. }
  7. public static void fun(Demo temp){
  8. temp.setMsg("MLDN");
  9. }
  10. class Demo{
  11. private String msg = "Hello";
  12. public Demo(String msg) {
  13. this.msg = msg;
  14. }
  15. public String getMsg() {
  16. return msg;
  17. }
  18. public void setMsg(String msg) {
  19. this.msg = msg;
  20. }
  21. }

基于String是引用数据类型的认知,见如下内存分析图:

引用传递一定要耐心使用内存分析,String这种类型 数据需要进行特殊处理。

2、对象比较

对象的比较就是判断两个对象是否相等,目前对象是否相等只能依靠地址是否相同来完成,但存在地址不同,内容相同的情况,好比String种的==与equals()。

要实现对象比较,首先必须进行对象种每一个属性内容进行比较,若完全相同,则为同一个对象,否则不同。


  
  1. protected void onCreate(Bundle savedInstanceState) {
  2. super.onCreate(savedInstanceState);
  3. Person perA = new Person("张三",20);
  4. Person perB = new Person("李四",20);
  5. if(perA.getName().equals(perB.getName()) && perA.getAge()==perB.getAge()){
  6. System.out.println("是同一个人");
  7. }else {
  8. System.out.println("不是同一个人");
  9. }
  10. }
  11. class Person{
  12. private String name;
  13. private int age;
  14. public Person(String name, int age) {
  15. this.name = name;
  16. this.age = age;
  17. }
  18. public String getName() {
  19. return name;
  20. }
  21. public void setName(String name) {
  22. this.name = name;
  23. }
  24. public int getAge() {
  25. return age;
  26. }
  27. public void setAge(int age) {
  28. this.age = age;
  29. }
  30. }

以上代码虽然实现了功能,但是可以进一步优化,这种对象的比较操作应该是由自己完成,这时可以在Person类中增加compare方法。具体如下,注意要考虑null和自己与自己比较的场景。


  
  1. protected void onCreate(Bundle savedInstanceState) {
  2. super.onCreate(savedInstanceState);
  3. Person perA = new Person("张三",20);
  4. Person perB = new Person("李四",20);
  5. if(perA.compare(perB)){
  6. System.out.println("是同一个人");
  7. }else {
  8. System.out.println("不是同一个人");
  9. }
  10. }
  11. class Person{
  12. private String name;
  13. private int age;
  14. public Person(String name, int age) {
  15. this.name = name;
  16. this.age = age;
  17. }
  18. public String getName() {
  19. return name;
  20. }
  21. public void setName(String name) {
  22. this.name = name;
  23. }
  24. public int getAge() {
  25. return age;
  26. }
  27. public void setAge(int age) {
  28. this.age = age;
  29. }
  30. //接收要比较的对象,在本方法种有隐藏的对象this
  31. public boolean compare(Person person){
  32. if(person==null){ //避免null异常
  33. return false;
  34. }
  35. if(this == person){ //防止自己与自己比较
  36. return true;
  37. }
  38. if(this.name.equals(person.name) && this.age== person.age){
  39. return true;
  40. }
  41. return false;
  42. }
  43. }

对象比较一般是在分析层次上使用,而实际开发种,只有String应用的比较多。

3、引用传递实际应用

程序是生活的抽象,日常生活中的概念实际都可以用程序描述,eg:一个人有一辆车。

描述以上概念前,有这样一个对比,若现在进行数据库的设计,若描述以上操作形式,数据库表该如何设计?需要两个数据库表;以上进行类的设计,实际也需要两个类:Person、Car,可以发现两者的关联:

  • 表名称 = 类名称;
  • 表的字段 = 类属性;
  • 表的一行记录 = 一个实例化对象;
  • 表的多行记录 = 对象数组;
  • 表的外键关系 = 引用设置;

所以,正是因为有这样的匹配关系,所以在实际开发中,简单java类不是凭空设计的,往往要与数据表的结构一一对应。

【举例】:定义类


  
  1. class Person{
  2. private int pid;
  3. private String name;
  4. //car 为null表示没有车
  5. private Car car;//一个人有一个车
  6. public Person(int pid, String name) {
  7. this.pid = pid;
  8. this.name = name;
  9. }
  10. public String getPersonInfo(){
  11. return "编号:"+this.pid+",姓名:"+this.name;
  12. }
  13. public Car getCar() {
  14. return car;
  15. }
  16. public void setCar(Car car) {
  17. this.car = car;
  18. }
  19. }
  20. class Car{
  21. private String cname;
  22. private Person person; //一车属于一人
  23. public Car(String cname) {
  24. this.cname = cname;
  25. }
  26. public String getCarInfo(){
  27. return "汽车名称:"+this.cname;
  28. }
  29. public Person getPerson() {
  30. return person;
  31. }
  32. public void setPerson(Person person) {
  33. this.person = person;
  34. }
  35. }

以上程序中使用了自定义的数据类型,Person和Car都是类。随后进行测试:

  • (1)设置内容
  • (2)取出内容

  
  1. protected void onCreate(Bundle savedInstanceState) {
  2. super.onCreate(savedInstanceState);
  3. //(1)根据已有结构设置内容
  4. Person per = new Person(1,"张三");
  5. Car car = new Car("奔驰");
  6. per.setCar(car); //人有车了
  7. car.setPerson(per);//车属于一个人了
  8. //(2)根据关系取出数据
  9. System.out.println(per.getPersonInfo());
  10. System.out.println(per.getCar().getCarInfo());//代码链
  11. System.out.println(car.getPerson().getPersonInfo());//代码链
  12. }

以上就是典型的一对一关系实现,可以进一步扩展下,比如每个人还有孩子,每个孩子还有车。这里孩子也是人,具备跟人一样的属性信息,那么可以在Person中设置孩子的属性。


  
  1. protected void onCreate(Bundle savedInstanceState) {
  2. super.onCreate(savedInstanceState);
  3. //(1)根据已有结构设置内容
  4. Person per = new Person(1,"张三");
  5. Person child = new Person(2,"张小三");
  6. Car car = new Car("奔驰");
  7. Car car1 = new Car("奥迪");
  8. per.setCar(car); //人有车了
  9. per.setChild(child); //人有一个孩子
  10. child.setCar(car1);//孩子有一个车
  11. car.setPerson(per);//车属于一个人了
  12. //(2)根据关系取出数据
  13. //找到一个人的孩子信息
  14. System.out.println(per.getChild().getPersonInfo());
  15. //根据父亲的车-父亲的车-父亲孩子-孩子的车信息
  16. System.out.println(per.car.getPerson().getChild().getCar().getCarInfo());
  17. }
  18. class Person{
  19. private int pid;
  20. private String name;
  21. private Person child;
  22. //car 为null表示没有车
  23. private Car car;//一个人有一个车
  24. public Person(int pid, String name) {
  25. this.pid = pid;
  26. this.name = name;
  27. }
  28. public String getPersonInfo(){
  29. return "编号:"+this.pid+",姓名:"+this.name;
  30. }
  31. public Car getCar() {
  32. return car;
  33. }
  34. public void setCar(Car car) {
  35. this.car = car;
  36. }
  37. public Person getChild() {
  38. return child;
  39. }
  40. public void setChild(Person child) {
  41. this.child = child;
  42. }
  43. }
  44. class Car{
  45. private String cname;
  46. private Person person; //一车属于一人
  47. public Car(String cname) {
  48. this.cname = cname;
  49. }
  50. public String getCarInfo(){
  51. return "汽车名称:"+this.cname;
  52. }
  53. public Person getPerson() {
  54. return person;
  55. }
  56. public void setPerson(Person person) {
  57. this.person = person;
  58. }
  59. }

引用的关系,可以描述不同类之间的关联。现实生活中这样的设计实质上并不麻烦,理论上任何事物都可以进行抽象整合,比如一台电脑:


  
  1. class 内存{}
  2. class 硬盘{}
  3. class 显卡{}
  4. class CPU{}
  5. class 键盘{}
  6. class 鼠标{}
  7. class 主板{
  8. private CPU 对象;
  9. private 内存 对象{};
  10. private 硬盘 对象{};
  11. private 显卡 对象{};
  12. }
  13. class 电脑{
  14. private 主板 对象;
  15. private 鼠标 对象;
  16. private 键盘 对象
  17. }

以上同样属于引用,这样的方式在设计模式中属于合成设计模型。

4、总结

  • 不要把程序当成纯粹的程序;
  • 引用传递除了进行数据分析外,还要掌握类与类的联系使用;
  • 代码链的使用必须掌握

 

作于202004061250,已归档

———————————————————————————————————

本文为博主原创文章,转载请注明出处!

若本文对您有帮助,轻抬您发财的小手,关注/评论/点赞/收藏,就是对我最大的支持!

祝君升职加薪,鹏程万里!

文章来源: winter.blog.csdn.net,作者:Winter_world,版权归原作者所有,如需转载,请联系作者。

原文链接:winter.blog.csdn.net/article/details/105330131

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。