Java基础_04 | 正式进入Java的世界(类和对象、类和对象的内存分配详解、构造函数)
2021/7/10 7:10:20
本文主要是介绍Java基础_04 | 正式进入Java的世界(类和对象、类和对象的内存分配详解、构造函数),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
1.类和对象- 什么是
类
- 把一类事物的静态属性和动态操作组合在一起就形成了类;
- 类是抽象的,用来模拟一类事物;
- 类只是对象的设计模板,并不占用内存,在创建对象的时候根据类的设计分配内存;
- 什么是
对象
- 对象是类的一个实体;
- 对象是具体的,实际存在的;
- 对象具有生命周期;
比如,可以将类比作是一辆汽车的设计图纸,一辆辆汽车就是根据这个类生产出的对象:
2.1.如何定义类?
- 定义类使用
class
关键字; - 类中定义的变量称为这个类的属性;
- 类中定义的函数称为这个类的方法;
比如定义一个Car类:
class Car { //Car类的属性 int number; //车辆编号 //Car类的方法 void go() { //类中的方法访问类的属性 System.out.printf("My number is %d, go go go!", number); } }
2.2.如何创建一个对象?
在主方法中创建一个Car类的对象并访问其成员和方法:
class CarTest { public static void main(String[] args) { //创建一个动态对象 Car testCar = new Car(); //访问对象的属性并修改 testCar.number = 1; //调用对象的方法 testCar.go(); } }
编译运行:
javac CarTest java CarTest
运行结果:
!!!
这里说的内存指的是程序运行时占用的内存,可以理解为RAM空间。
!!!
- 编写好程序源代码后,执行
javac CarTest
,生成的CarTest.class
可执行程序保存在硬盘上;
- 当我们执行
java CarTest
命令后,操作系统将整个程序加载到内存中,准备运行; - 程序从main入口函数开始执行;
- 程序在执行过程中进行内存分配,接下来我们开始逐步解析:
3.1.类的内存空间如何分配?
类只是一个概念,是抽象的,用来模拟一个事物,这里用来模拟一个车辆,所以类不会占用任何内存空间。
3.2.对象的内存如何分配?
Car testCar = new Car();
Car()
函数称为Car类的构造函数,虽然我们并没有定义,但是这个函数是默认存在的,在创建一个该类对象时自动调用,在第4节具体讲述;new
关键字表明这个对象创建时内存空间要动态分配,所以一个new出来的对象其内存空间在堆中,new
关键字的作用和C语言中malloc
函数的作用相同,只不过更为简单,总结:系统按照类中的定义在堆中分配内存,然后将首地址返回;- 这个对象的首地址返回后,保存在testCar变量中,所以按照C语言来说是testCar指向堆中的Car对象,按照Java对象来说是testCar变量引用了堆中Car对象的地址。
- testCar是一个Car类型的变量,并且在主函数中定义,所以是一个局部变量,其内存分配在栈中。
3.3.堆中对象的属性和方法如何访问?
如上图所示,如果我们想要访问堆中Car对象的number属性和go方法,该如何访问呢?
显然,我们不可能直接去访问,车到山前必有路,testCar变量中保存着Car对象的首地址,所以,我们有了testCar变量后无所不能!
如上面的演示程序,直接通过testCar.nunber
就可以访问number属性,通过testCar.go()
就可以访问go方法。
4.1.构造函数的作用
在创建一个对象时,系统首先会为该对象分配内存,然后自动调用该类的构造函数。
4.2.默认无参构造函数
在创建对象时,我们调用了Car()
函数,但是这个函数在我们的类定义中并没有,那么这个函数是如何调用的呢?
Car testCar = new Car();
这里的Car()
就是Car类
的构造函数,在我们定义了Car类
后,系统会自动生成默认构造函数Car()
。
4.3.自定义构造函数
自定义构造函数的时候,需要注意构造函数有以下特点:
- 函数名和类名相同
- 参数可以没有,也可以有多个
- 无返回值
- 构造函数必须是public或者默认修饰符
- 可以有多个构造函数
- 一旦自定义构造函数,系统不会再自动生成默认无参构造函数
比如,这里我自定义一个无参构造函数和带参构造函数:
class Car { //Car类的属性 int number; //车辆编号 //无参构造函数 public Car() { System.out.printf("无参构造函数被调用.\n"); } //有参构造函数 public Car(int i) { number = i; System.out.printf("有参构造函数被调用.\n"); } //Car类的方法 void go() { //类中的方法访问类的属性 System.out.printf("My number is %d, go go go!\n", number); } }
使用无参构造函数和有参构造函数分别创建对象:
class CarTest { public static void main(String[] args) { //使用无参构造函数创建一个动态对象 Car testCar1 = new Car(); //访问对象的属性并修改 testCar1.number = 1; //调用对象的方法 testCar1.go(); //使用有参构造函数创建一个动态对象 Car testCar2 = new Car(2); //调用对象的方法 testCar2.go(); } }
运行结果如下:
为了验证“当我们自定义构造函数,系统是否会再自动生成默认构造函数?“”,我们将无参构造函数去掉,再次运行,系统报错,提示默认无参构造函数没有定义:
所以我们可以得出:
一旦自定义构造函数,系统不会再自动生成默认构造函数。
4.4.构造函数中数据成员的赋值问题
对于类中的数据成员(类的属性),系统先执行定义时赋的初值,然后再执行构造函数中赋的初值。
比如,我在定义时将number
属性赋值为1,构造函数中赋值为2,最后的结果为2:
class Car { //Car类的属性 int number = 1; //车辆编号 //无参构造函数 public Car() { System.out.printf("无参构造函数被调用.\n"); } //有参构造函数 public Car(int i) { number = i; System.out.printf("有参构造函数被调用.\n"); } //Car类的方法 void go() { //类中的方法访问类的属性 System.out.printf("My number is %d, go go go!\n", number); } } class CarTest { public static void main(String[] args) { //使用有参构造函数创建一个动态对象 Car testCar = new Car(2); //调用对象的方法 testCar.go(); } }
运行结果:
这篇关于Java基础_04 | 正式进入Java的世界(类和对象、类和对象的内存分配详解、构造函数)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-12-22项目:远程温湿度检测系统
- 2024-12-21《鸿蒙HarmonyOS应用开发从入门到精通(第2版)》简介
- 2024-12-21后台管理系统开发教程:新手入门全指南
- 2024-12-21后台开发教程:新手入门及实战指南
- 2024-12-21后台综合解决方案教程:新手入门指南
- 2024-12-21接口模块封装教程:新手必备指南
- 2024-12-21请求动作封装教程:新手必看指南
- 2024-12-21RBAC的权限教程:从入门到实践
- 2024-12-21登录鉴权实战:新手入门教程
- 2024-12-21动态权限实战入门指南