行业知识
JavaSE:类和对象
1、引言
其实像Java、C++、C#等语言都是面向对象语言,而我们之前学习的C语言是一门面向过程语言,而我们现在需要做的,就是将我们的编程思想从面向过程转向面向对象,这确实不是一件易事~
在Java(面向对象语言)当中,一切皆对象!!!
读到这里,相信大家心中都有着疑问:什么是类?什么是对象?让我们心存疑问,一起来探索这个面向对象的世界。
2、类的定义和使用
2.1 什么是类
简单来说,类就是用来描述一个对象的,我们可以把类当做一张建筑图纸,利用这一张图纸,我们可以建造出多个房子,这张图纸就是一个类,而建造出来的实体(房子)就是一个对象,一个类可以创建多个对象。
2.2 类的语法定义
在Java中,class是定义类的关键字,
类中包含的内容称为类的成员。
属性主要是用来描述类的,称为:属性、成员变量、字段。
方法主要说明类具有哪些功能,称为:行为、成员方法。
代码演示:
我们便定义出了一个学生类。
OK,现在我们已经知道了什么是类以及如何去定义一个类,那么如何去使用这个类呢?如何去创建一个对象呢?我们继续。
2.3 对象的实例化
由类创建对象的过程,就叫做对象的实例化。通过new关键字,来实例出一个对象。
我们就很好的实例出一个对象(成员变量在堆中开辟内存空间,成员方法在栈上开辟栈帧),而student1为一个引用类型的变量,指向堆中的对象。
内存图如下:
接着,我们可以通过 . 点操作符来访问对象中的成员,来完成对成员变量的赋值和对成员方法的调用:
===============================分割线====================================
观察:
我们发现,在类中,当我们没有初识化成员变量的时候,成员变量会有一个默认值,而不同类型的成员变量遵循以下规则:
1.引用类型,默认值为null
2.基本数据类型,默认值为对应零值
我们可以通过关键字new来实例化多个对象:
2.4 this引用
我们可以通过调用成员方法来完成对某一对象属性赋值:
目前代码是没有问题的,我们很好的将成员变量进行了初始化,可是当setData方法的形参名与字段名称相同时,麻烦就出现了:
我们发现,我们对成员变量的赋值失败了,这是因为:此时在方法内部,name、age、sex都是局部变量,并不是类中的成员变量,此时成员变量优先使用。(形参自己给自己赋值,并没有修改到成员变量中)
这时,就轮到this引用出场了:
这时,我们对成员变量的赋值又成功了,这是因为this引用引用的是当前对象,this.访问的就是当前的成员,这样,便成功赋值。
相信大家到这里都会有一个疑问->"传参时也没有看见有穿this这个引用啊?哪里来的呢?"
答:this是方法中隐藏的第一个参数。(是系统默认提供的)
如图:
而谁调用的这个方法,谁就是this
所以,为了避免一些不必要的麻烦,我们要养成使用this的编程习惯。
通过这个例子,我们引出了this这个引用,那this到底可以做什么呢?我们继续。
2.4.1 this访问对象的成员变量
就如我们上面所讨论的,this可以访问成员变量:
2.4.2 this访问对象的成员方法
this是一个引用,除了可以访问成员变量外,当然也是可以访问成员方法了:
2.4.3 this访问对象的构造方法
到这里,我们又很好的抛出了一个问题:什么是构造方法?
2.4.3.1 构造方法
构造方法(也称为构造器)是一个特殊的成员方法,名字必须与类名相同,在创建对象时,由编译器自动调用,并且 在整个对象的生命周期内只调用一次。
如图所示,这便是一个不带参数的构造方法。:
也就是说,当我们实例化对象的时候,系统会调用构造方法,我们也可以借用构造方法来完成对成员的初始化。
换句话说,对象的实例化必须调用构造方法。 在这里,就有人发出疑问了,那刚才我们实例化对象的时候,也没有写构造方法啊,为啥也正常运行了呢?这是因为,当我们没有显式调用任何构造方法时,Java会帮我们自动调用不带参数的构造方法。
我们需要注意以下两点:
1.构造方法是用来初识化成员的
2.构造方法不止一个(构造方法可以不带参数也可以带多个参数,发生重载)
我们继续往下看,当我们只调用带三个参数的构造方法时:
我们发现,idea出现了报错,这是因为,一旦我们有了其他的构造方法,Java便不再提供不带参数的构造方法!!!
这时,我们需要显式的写出不带参数的构造方法:
便会正常运行。
结论:
1.对象的实例化必须调用构造方法。
2.当我们没有写任何的构造方法的时候,Java会默认帮我们提供不带参数的构造方法。
3.一旦我们自己写了构造方法,Java便不再提供不带参数的构造方法。
2.4.3.2 this调用构造方法
到这里,我们理解了构造方法后,我们可以讲this的第三个用法------在构造方法中调用其它构造方法。
代码演示:
我们可以看到,在不带参数的构造方法中,我们通过this来调用了带三个参数的构造方法,完成了对成员变量的初识化。
但是!!!
我们需要注意以下几点:
1.利用this调用其他构造方法,必须放在本构造方法的第一行,否则编译出错:
2.不能在多个构造方法中利用this再来调用其他构造方法使之形成环,如图:
因为这样编译器就懵了,编译器内心OS:“你到底要调用哪个构造方法嘛!!!”
3、默认初始化
我们在上文也提到了,当我们实例化好对象后,我们发现,成员变量已经完成了默认初始化
,而对于局部变量来说,不进行初始化是会编译报错的:
那么这是为什么呢?
要搞清楚这个过程,就需要知道 new 关键字背后所发生的一些事情:
在程序层面只是简单的一条语句,在JVM层面需要做好多事情,下面简单介绍下:
1. 检测对象对应的类是否加载了,如果没有加载则加载(优点:类只加载一次)
我们可以通过下图简单了解加载:
2. 为对象分配内存空间
3. 处理并发安全问题 比如:多个线程同时申请对象,JVM要保证给对象分配的空间不冲突
4. 初始化所分配的空间(即:对象空间被申请好之后,对象中包含的成员已经设置好了初始值)
5. 设置对象头信息
6.调用构造方法,给对象中各个成员赋值
4.就地初始化
就地初始化,其实就是在定义成员变量时就给出了初始值。
代码编译完成后,编译器会将所有给成员初始化的这些语句添加到各个构造函数中。
OK~本次博客到这里就结束了,
感谢大家的阅读~欢迎大家在评论区交流问题~
如果博客出现错误可以提在评论区~
创作不易,请大家多多支持~