面向对象的基础篇_02
来源:互联网 发布:php编写新闻发布系统 编辑:程序博客网 时间:2024/06/03 20:18
基础篇_02的主要内容
- 1、引用传递和值传递
- 2、链表
一丶引用传递和值传递
1、基本类型和引用类型在内存中的保存
|- Java中数据类型分为两大类,【基本类型】和【对象类型】。
基本类型的变量保存原始值,即它代表的值就是数值本身;
这里的基本类型包括:byte,short,int,long,char,float,double,Boolean,returnAddress,etc...
引用类型的变量保存引用值。
"引用值"指向内存空间的地址,代表了某个对象的引用,而不是对象本身,对象本身存放在这个引用值所表示的地址的位置。
引用类型包括:类类型,接口类型和数组。
2、变量的基本类型和引用类型的区别
|- 变量也有两种类型:【基本类型】和【引用类型】。
基本数据类型在声明时系统就给它分配空间:
int a;
a=10;//正确,因为声明a时就分配了空间引用就不相同了,它声明时只给变量分配了引用空间,而不分配数据空间:
Date date;date=new Date();date.getDate();//执行实例化,开辟数据空间存放Date对象,然后把空间的首地址传给“今天到的日期”变量 System.out.println(date.getDate());//输出今天的日期/* *如果注释掉date=new Date();就会有异常抛出 *NullPointerException,意思就是说一个空的变量,一个空的栈内存。 *The local variable date may not have been initialized *也就是说对象的数据空间没有分配 */
3、引用传递和值传递
引用传递是Java的核心问题,引用传递的操作的核心就是内存地址的传递。
这里要用 【实际参数】 和 【形式参数】的概念来帮助理解,
值传递:
方法调用时,实际参数把它的值传递给对应的形式参数,函数接收的是原始值的一个copy,此时内存中存在两个相等的基本类型,即实际参数和形式参数,后面方法中的操作都是对形参这个值的修改,不影响实际参数的值。
-
范例:
-
public class Test01 { public static void change(int a){ a=10000; } public static void main(String[] args) { int a=10; System.out.println(a);//10 change(a); System.out.println(a);//10 } }
改变的是形式参数的值,结果不影响实际参数。
引用传递:也称为传地址。
方法调用时,实际参数的引用(地址,而不是参数的值)被传递给方法中相对应的形式参数,函数接收的是原始值的内存地址;在方法执行中,形参和实参内容相同,指向同一块内存地址,方法执行中对引用的操作将会影响到实际对象。
-
范例:
-
public class Test02 { public static void change(int []a){ a[0]=50; } public static void main(String[] args) { int []a={10,20}; System.out.println(a[0]);//10 change(a); System.out.println(a[0]);//50 } }
这里传来的是地址,形式参数和实际参数有一样的地址,改变了地址中的内容
通过以下三个Demo来说明作用
class Demo{ private int count = 10 ; public void setCount(int count){ this.count = count ; } public int getCount(){ return this.count ; }};public class Demo01 { public static void main(String args[]){ Demo d1 = new Demo() ; d1.setCount(100) ; fun(d1) ; System.out.println(d1.getCount()) ; //输出的结果为30 } public static void fun(Demo d2){ d2.setCount(30) ; }};
public class Demo02 { public static void main(String args[]){ String str = "hello" ; fun(str) ; System.out.println(str) ; //输出的结果是hello } public static void fun(String temp){ temp = "world" ; }};
字符串的内容无法改变,改变的只是内存地址的指向。
class Demo{ private String str = "hello" ; public void setStr(String str){ this.str = str ; } public String getStr(){ return this.str ; }};public class Demo03 { public static void main(String args[]){ Demo d1 = new Demo() ; d1.setStr("world") ; fun(d1) ; System.out.println(d1.getStr()) ; //最后的输出结果是!!! } public static void fun(Demo d2){ d2.setStr("!!!") ; }};
二丶链表的认识(这里是说一个指针域的)
1、链表是一个个结点连接起来的长链。
链表包括两个部分
|-数据域:存放数据的区域。例如:姓名、地址、学号etc...
|-指针域:存放一个指针的区域。这个指针
class Node { private String name ; // 保留节点名称 private Node next ; // 保存下一个节点的引用 public Node(String name){ //含有参数的构造器来保存结点名称 this.name = name ; //this.name中的name是Node类中的name //= name 是传过来参数name } public String getName(){ return this.name ; } public void setNext(Node next){ this.next = next ; } public Node getNext(){ return this.next ; }}public class Demo04 { public static void main(String args[]){ Node na = new Node("A") ; Node nb = new Node("B") ; Node nc = new Node("C") ; na.setNext(nb) ;//a的指针域指向b nb.setNext(nc) ;//b的指针域指向c }}
在栈内存中存放的是na,nb,nc
在堆内存中存放的是name:A、B、C 和next:nb、nc、null
第一个结点A的指针域na指向的是nb,所以堆内存中存放的是结点A到的name和nb。同理可得。
在设置好了关系之后,只能通过递归的方式完成全部输出。
public class Demo05 { public static void main(String args[]){ Node na = new Node("车厢 A") ; Node nb = new Node("车厢 B") ; Node nc = new Node("车厢 C") ; na.setNext(nb) ; nb.setNext(nc) ; print(na) ; } public static void print(Node node){ if(node != null){ // 避免空指向异常 System.out.println(node.getName()) ; if(node.getNext() != null){ print(node.getNext()) ; } } }}
自动的完成增加和输出的功能
需要考虑到以下的几个问题:
每一个结点都要保存起来。设置一个可以保存节点关系的类:Node
需要一个添加结点,并按照结点次序连接起来的类:Link
第一个结点是头结点,必须保留好根节点,private封装起来
下面是一个链表的基本数据模型。
class Node { private String name ; // 保留节点名称 private Node next ; // 保存下一个节点的引用 public Node(String name){ this.name = name ; } public String getName(){ return this.name ; } public void setNext(Node next){ this.next = next ; } public Node getNext(){ return this.next ; } public void addNode(Node newNode){//添加结点 if(this.next == null){ this.next = newNode ; } else { this.next.addNode(newNode) ; // 当前节点的下一个继续往下判断 } } public void printNode(){//输出结点 System.out.println(this.name) ; if(this.next != null){ this.next.printNode() ; } }}class Link { // 表示的是一个节点的操作类 private Node root ; // 表示根节点 public void add(String name){ // 增加新节点 Node newNode = new Node(name) ; // 新节点 if(this.root == null){ // 现在没有根节点 this.root = newNode ; // 第一个节点是根节点 } else { // 应该排在最后 this.root.addNode(newNode) ; // 向后面排队 } } public void print(){ this.root.printNode() ;//从根结点开始调用,这个函数的方法在类Node中 }}public class Test { public static void main(String args[]){ Link link = new Link() ; link.add("车厢 A") ; link.add("车厢 B") ; link.add("车厢 C") ; link.add("车厢 D") ; link.add("车厢 E") ; link.print() ; }}
阅读全文
0 0
- 面向对象的基础篇_02
- Js_面向对象_02
- 黑马程序员_java基础_面向对象_02
- 面向对象的基础
- 面向对象的基础
- 面向对象的基础
- 面向对象的基础
- java学习之旅32--面向对象_05_程序执行过程的内存分析_02
- 32_面向对象_05_程序执行过程的内存分析_02
- 面向对象的 Javascript 面向对象基础
- 面向对象(基础篇)
- 面向对象的基础篇_01
- 面向对象的基础篇_03
- 面向对象的基础结构设计
- 面向对象的基础结构设计
- c++的面向对象基础
- 面向对象的基础概念
- php面向对象的基础
- HAProx+Mycat+MySQL(单服务器版)
- Ionic3项目开发——环境安装
- 学习《python编程从入门到实践》一些数据资料
- c#基础之集合 类型总结
- html5游戏制作(2)
- 面向对象的基础篇_02
- ResNet学习笔记
- 数据库视频总结(二)
- 引用数据类型
- 【云星数据---Apache Flink实战系列(精品版)】:Apache Flink高级特性与高级应用017-Flink中参数传递和容错设定001
- CodeForces
- windows10和kali双系统(从uefi启动)
- php 中字符串一样但长度不等的问题
- Tensorflow + Caffe + Torch 的详细安装指南(GPU版本)