【Java】P7 面向对象(2)属性
创始人
2025-05-30 00:26:26
0

属性

  • 属性的分类
  • 局部变量 与 形参
  • 基本数据类型 与 引用数据类型
  • 实例化
  • 堆空间 与 栈空间
  • 附完整代码如下


属性的分类

在类中,我们有两个成员,一个是 属性,另一个是 方法

class Person {// 定义属性String name;int age;char gender;// 定义方法public void eat() {String food = "宫保鸡丁";   // 定义局部变量System.out.println("我喜欢吃" + food);}public void sleep(int hour) {    // 形参:属于局部变量System.out.println("人至少睡眠" + hour + "小时");}
}

属性中, 变量的定义可以分为:基本数据类型引用数据类型
方法中, 变量的定义可以分为:局部变量形参

即:

在这里插入图片描述

因为本文主要围绕的是 属性 部分,所以下文将首先介绍 方法 部分,然后详细介绍属性部分的 基本数据类型引用数据类型


局部变量 与 形参

// 定义方法
public void eat() {String food = "宫保鸡丁";   // 定义局部变量System.out.println("我喜欢吃" + food);
}
public void sleep(int hour) {    // 形参:属于局部变量System.out.println("人至少睡眠" + hour + "小时");
}

在定义方法部分,我们一共对 Person 类定义了两个方法:eatsleep;而在方法 eat 中,我们通过定义局部变量 food 并赋值,最后通过 sout 打印;

public void eat() {String food = "宫保鸡丁";   // 定义局部变量System.out.println("我喜欢吃" + food);
}

需要注意的是,在定义局部变量时,我们必须对其进行赋值,而不是仅仅初始化;

在方法 sleep 中,我们通过定义形参 hour,并且通过传参的方式将其值传入,最终通过 sout 打印;

public void sleep(int hour) {    // 形参:属于局部变量System.out.println("人至少睡眠" + hour + "小时");
}

需要注意的是,与局部变量对比,形参因为可以在被调用时候传入值,所以我们可以仅执行初始化操作,而不赋值;


基本数据类型 与 引用数据类型

我们定义一个类 Employee,并定义属性如下:

public class Employee {// 定义属性int id;     // 编号String name;        // 姓名int age;        // 年龄double salary;      // 薪资
}

其实通过观察不难发现,好像 String 与另外三个属性不太相同;仔细思考,其实是因为 String 不属于 基本数据类型,而是属于 引用数据类型

Java 的基本数据类型包括以下几种:整型:byte、short、int、long
浮点型:float、double
字符型:char
布尔型:boolean这些数据类型分别代表不同的数据类型,可以用于声明变量、函数参数、函数返回值等。
其中,整型用来表示整数,浮点型用来表示小数,字符型用来表示单个字符,布尔型用来表示真或假。
Java 的引用数据类型可以被理解为指向对象的指针
它们不存储实际的数据值,而是存储指向对象的内存地址。Java 中常见的引用数据类型包括以下几种:类类型(Class Type):包括所有的类、接口和数组类型。
接口类型(Interface Type):指的是所有的接口类型。
数组类型(Array Type):指的是所有的数组类型,无论是基本数据类型的数组还是对象类型的数组。这些引用数据类型都需要在使用前进行实例化,即通过 new 关键字创建对象并分配内存空间。
在实例化后,引用数据类型变量会存储对象的内存地址,从而允许程序通过引用来访问对象的属性和方法。

上述两段初学不会完全理解,结合下述的代码去理解就好;

public class Employee {// 定义属性int id;     // 编号String name;        // 姓名int age;        // 年龄double salary;      // 薪资MyDate birthday;       // 生日
}

我们在上述代码的基础上再加上一行 引用数据类型 变量,即 MyDate

MyDateString 不同的在于,其是我们自己定义的 引用数据类型

public class MyDate {int year;int month;int day;
}

创建一个名为 MyDate 的类;在类中,定义三个成员变量:yearmonthday,分别代表年月日;

然后我们将其实例化:


实例化

我们另创建一个名为 EmployeeTest 的类,在类中,我们创建两个实例:emp1 以及 emp2

public class EmployeeTest {public static void main(String[] args) {// 创建类的实例,类的实例化Employee emp1 = new Employee();System.out.println(emp1);      // 类型@地址// 创建实例变量emp1.id = 1001;emp1.name = "Tom";emp1.age = 21;emp1.salary = 7800;emp1.birthday = new MyDate();emp1.birthday.year = 1999;emp1.birthday.month = 1;emp1.birthday.day = 15;System.out.println("id = " + emp1.id + ",name = " + emp1.name + ",age = " + emp1.age + ",salary = " + emp1.salary + ",birthday = " + emp1.birthday.year + "年  " + emp1.birthday.month + "月" + emp1.birthday.day + "日");// 创建第二个对象Employee emp2 = new Employee();     // 开辟空间给第二个对象System.out.println(emp2);//        emp2.id = ;
//        emp2.name = ;
//        emp2.age = ;
//        emp2.salary = ;System.out.println("id = " + emp2.id + ",name = " + emp2.name + ",age = " + emp2.age + ",salary = " + emp2.salary);}
}

观察第一个实例化部分:emp1

Employee emp1 = new Employee();// System.out.println(emp1);      // 类型@地址// 实例变量赋值
emp1.id = 1001;
emp1.name = "Tom";
emp1.age = 21;
emp1.salary = 7800;
emp1.birthday = new MyDate();
emp1.birthday.year = 1999;
emp1.birthday.month = 1;
emp1.birthday.day = 15;System.out.println("id = " + emp1.id + ",name = " + emp1.name + ",age = " + emp1.age + ",salary = " + emp1.salary + ",birthday = " + emp1.birthday.year + "年  " + emp1.birthday.month + "月" + emp1.birthday.day + "日");

首先我们通过 new 方法给实例 emp1 开辟 堆空间

Employee emp1 = new Employee();

然后我们对实例变量进行赋值:

emp1.id = 1001;
emp1.name = "Tom";
emp1.age = 21;
emp1.salary = 7800;
emp1.birthday = new MyDate();
emp1.birthday.year = 1999;
emp1.birthday.month = 1;
emp1.birthday.day = 15;

需要注意的是,在 emp1.birthday 开始,我们首先又一次执行了 new,即:

emp1.birthday = new MyDate();

即,我们给 emp1.birthday 开辟 堆空间 ;并且把地址信息给 emp1.birthday 属性;然后给属性赋值:

emp1.birthday.year = 1999;
emp1.birthday.month = 1;
emp1.birthday.day = 15;

在这里读者应该产生困惑有两点,第一点是 堆空间,第二点是 地址信息;下一个部分的内容将阐述这两个点;

我们在赋值给引用数据类型 emp1.birthday 赋值后,可以打印内容如下:

System.out.println("id = " + emp1.id + ",name = " + emp1.name + ",age = " + emp1.age + ",salary = " + emp1.salary + ",birthday = " + emp1.birthday.year + "年  " + emp1.birthday.month + "月" + emp1.birthday.day + "日");

堆空间 与 栈空间

在 Java 中,堆空间和栈空间都是用来存储程序中的数据的内存区域,但是它们有着不同的特点和用途。

堆空间(Heap Space): 堆空间是用于存储对象的内存区域。所有通过 new 关键字创建的对象都存储在堆空间中,而且这些对象的生命周期由垃圾收集器来管理。堆空间的大小一般由 JVM 参数进行设置,可以动态扩展,因此它可以存储任意数量的对象。

栈空间(Stack Space): 栈空间是用于存储方法调用的内存区域。每个线程都有自己的栈空间,用于存储方法调用的参数、局部变量和方法返回值等数据。栈空间的大小是由 JVM 预设的,不能动态扩展,因此它的空间较小,只能存储相对较小的数据。

需要注意的是,基本数据类型的变量也可以存储在栈空间中,但是它们和对象的引用不同,基本数据类型的变量存储的是数据本身而不是内存地址。此外,在方法调用结束后,方法的栈帧会被弹出并释放相应的内存空间,因此栈空间中的数据只有在方法执行期间才是有效的。

在这里插入图片描述
在该程序中,我们有两次 new,第一次开辟 堆空间emp1 实例,第二次开辟 堆空间emp1.birthday 引用数据类型属性;而如果我们将 emp1 以及 emp1.birthday 打印可以发现,其存储的都是 类型@地址 的地址信息:

System.out.println(emp1);      			// 类型@地址
System.out.println(emp1.birthday);      // 类型@地址

附完整代码如下

MyDate.java

package com.athongduo.idea;/*** ClassName: MyDate* Description:** @Author: XU Hongduo* @Create 2023/3/17 14:28* @Version 1.0*/
public class MyDate {int year;int month;int day;
}

Employee.java

package com.athongduo.idea;/*** ClassName: Employee* Description:** @Author: XU Hongduo* @Create 2023/3/17 14:16* @Version 1.0*/
public class Employee {// 定义属性int id;     // 编号String name;        // 姓名int age;        // 年龄double salary;      // 薪资MyDate birthday;       // 生日
}

EmployeeTest.java

package com.athongduo.idea;/*** ClassName: EmployeeTest* Description:** @Author: XU Hongduo* @Create 2023/3/17 14:18* @Version 1.0*/
public class EmployeeTest {public static void main(String[] args) {// 创建类的实例,类的实例化Employee emp1 = new Employee();System.out.println(emp1);      // 类型@地址// 创建实例变量emp1.id = 1001;emp1.name = "Tom";emp1.age = 21;emp1.salary = 7800;emp1.birthday = new MyDate();emp1.birthday.year = 1999;emp1.birthday.month = 1;emp1.birthday.day = 15;System.out.println("id = " + emp1.id + ",name = " + emp1.name + ",age = " + emp1.age + ",salary = " + emp1.salary + ",birthday = " +emp1.birthday.year + "年  " + emp1.birthday.month + "月" + emp1.birthday.day + "日");// 创建第二个对象Employee emp2 = new Employee();     // 开辟空间给第二个对象System.out.println(emp2);//        emp2.id = ;
//        emp2.name = ;
//        emp2.age = ;
//        emp2.salary = ;System.out.println("id = " + emp2.id + ",name = " + emp2.name + ",age = " + emp2.age + ",salary = " + emp2.salary);}
}

相关内容

热门资讯

台州最新学区划分,最新或202... 台州公办小学招生范围按照义务教育免试就近入学原则,市区公办小学实行依街道划片招生。本文为您介绍台州小...
衢州最新学区划分,最新或202... 柯城区最新或2023(历届)学区划分衢江区最新或2023(历届)学区划分
舟山最新学区划分,最新或202... 临城新区】1、南海实验小学片区:新城沈白线以南、千岛路以西区域,以及长峙社区居民子女。2、舟山第二小...
④电子产品拆解分析-太阳能自动... ④电子产品拆解分析-太阳能自动感应灯一、功能介绍二、电路分析以及器件作用1、太阳能控制电路分析2、优...
丽水最新学区划分,最新或202... 根据“就近入学,统筹安排”为原则,公办小学学区划分也已出炉。  市实验学校:丽阳门居委、高井弄居委。...
海南最新学区划分,最新或202... 1.市直属学校招生范围划分小 学招 生 范 围海口市滨海第九小学滨海大道北侧(至海边),港进路和港集...
从ChatGPT到AGI还有多... 1.引子 21年开始在公司负责一个全链路语音的项目,支持公司的Iot设备,...
海口最新学区划分,最新或202... 海口公办小学招生范围按照义务教育免试就近入学原则,市区公办小学实行依街道划片招生。本文为您介绍海口小...
青海最新学区划分,最新或202... 为方便家长和学生们了解自己孩子所就读的小学或是自己孩子的户口究竟在不在想要入读的中学的学区范围内,小...
西宁最新学区划分,最新或202... 西宁公办小学招生范围按照义务教育免试就近入学原则,市区公办小学实行依街道划片招生。本文为您介绍西宁小...
三亚最新学区划分,最新或202... 三亚公办小学招生范围按照义务教育免试就近入学原则,市区公办小学实行依街道划片招生。本文为您介绍三亚小...
贵州最新学区划分,最新或202... 为方便家长和学生们了解自己孩子所就读的小学或是自己孩子的户口究竟在不在想要入读的中学的学区范围内,小...
21- 神经网络模型_超参数搜... 知识要点 fetch_california_housing:加利福尼亚的房价数据&#...
一文了解GPU并行计算CUDA 了解GPU并行计算CUDA一、CUDA和GPU简介二、GPU工作原理与结构2.1、基础GPU架构2....
贵阳最新学区划分,最新或202... 贵阳公办小学招生范围按照义务教育免试就近入学原则,市区公办小学实行依街道划片招生。本文为您介绍贵阳小...
遵义最新学区划分,最新或202... 遵义公办小学招生范围按照义务教育免试就近入学原则,市区公办小学实行依街道划片招生。本文为您介绍遵义小...
安顺最新学区划分,最新或202... 安顺公办小学招生范围按照义务教育免试就近入学原则,市区公办小学实行依街道划片招生。本文为您介绍安顺小...
六盘水最新学区划分,最新或20... 百年教育网小编为您整理了关于六盘水市幼升小学区划分详情的相关信息,希望对您有帮助,想了解更多请继续关...
遍历二叉树线索二叉树 遍历二叉树 遍历定义 顺着某一条搜索路径寻访二叉树中的每一个结点,使得每个节点均被依次...
springboot简介和项目... Java知识点总结:想看的可以从这里进入 目录SpringBoot1、简介和原理1....