【JavaSe】想学好Java,怎么可以不懂类和对象(巨详细)--> 第②篇

上篇我们了解了什么是面向对象以及this引用,本篇将继续介绍类和对象中剩余的部分,从这里开始难度也逐渐上升啦,但我相信本篇文章能让你很轻松地搞定它~(小小臭美一下)👊

5. 对象的构造及初始化


🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇

5.1 如何初始化对象

在这里插入图片描述在定义成员变量的时候直接赋值,这就叫就地初始化。

通过前面知识点的学习知道,在java方法内部定义一个局部变量时,必须要初始化,否则会编译失败。
在这里插入图片描述
要让上述代码通过编译,非常简单,只需在正式使用a之前,给a设置一个初始值即可。

如果是对象,即使不初始化,正式使用时也不会报错,因为其会自动设置为对应的0值(上篇中介绍过各类型变量对应的零值)。

(这里回顾一下上篇中写过的代码)
在这里插入图片描述

在这里插入图片描述
需要调用之前写的setDate方法(具体看上篇中的代码)才可以将具体的日期设置到对象中。通过上述例子发现两个问题:
1、每次对象创建好后调用setDate方法设置具体日期,比较麻烦,那对象该如何初始化?
2、局部变量必须要初始化才能使用,为什么字段(成员变量)声明之后没有给值依然可以使用?


🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇

5.2 构造方法(重要)

5.2.1概念

构造方法(也称为构造器)是一个特殊的成员方法,名字必须与类名相同,在创建对象时,由编译器自动调用,并且在整个对象的生命周期内只调用一次。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

注意:即使自己构造了一个不带参数的构造方法,编译器也不会再默认帮你生成一个构造方法。如果自己构造了一个带参数的构造方法,则在调用构造方法(即创建对象)时也要传对应的参数,否则会报错。


🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇

5.2.1 构造方法的特性

  1. 名字必须与类名相同2
  2. 没有返回值类型,设置为void也不行
  3. 创建对象时由编译器自动调用,并且在对象的生命周期内只调用一次(相当于人的出生,每个人只能出生一次)
  4. 构造方法可以重载(用户根据自己的需求提供不同参数)

在这里插入图片描述
上述两个构造方法:名字相同,参数列表不同,因此构成了方法重载

  1. 如果用户没有显式定义,编译器会生成一份默认的构造方法,生成的默认构造方法一定是无参的。

注意:一旦用户定义,编译器则不再生成。

在这里插入图片描述
IDEA中生成构造方法的快捷键:可以自己选择生成几个参数(按住shift再用鼠标多选)

在这里插入图片描述
在这里插入图片描述

  1. 构造方法中,可以通过this调用其他构造方法来简化代码(只能在构造方法中使用)

在这里插入图片描述
运行结果:
在这里插入图片描述

注意: this(…)必须是构造方法中第一条语句(注释不算)
通过this调用构造方法不能形成环(即不能让this调用的构造方法形成一个圈,从而无休止的调用)

形成环的例子:
在这里插入图片描述

总结:

  1. 构造方法是没有返回值的方法,方法名和类名是一样的
  2. 构造方法不止一个,可以有多个,多个构造方法之间构成了重载
  3. 当我们写了一个类之后,没有写构造方法的时候,编译器会帮我们默认生成一个不带参数的构造方法
  4. 当我们写了任何一个构造方法之后,编译器不再为我们提供不带参的构造方法
  5. 一个类至少会有1个构造方法,即使你自己没有写
  6. 构造方法本质就是来实例化对象的时候调用
    实例化对象时:(1) 分配内存 (2) 调用合适的构造方法
  7. this可以用来调用本类中其他的构造方法【只能在构造方法当中使用】,this(…)必须放到构造方法的第一行,所以在当前构造方法当中只能调用一个this(…)
  8. this的三种用法:
    a. this . data 访问属性
    b. this . func() 访问方法
    c. this() 调用本类中其他的构造方法
  9. this不能形成环

🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇

5.3 默认初始化

在这里插入图片描述

在程序层面只是简单的一条语句,在JVM层面需要做好多事情,下面简单介绍下:

  1. 检测对象对应的类是否加载了,如果没有加载则加载
  2. 为对象分配内存空间
  3. 处理并发安全问题
    比如:多个线程同时申请对象,JVM要保证给对象分配的空间不冲突
  4. 初始化所分配的空间
    即:对象空间被申请好之后,对象中包含的成员已经设置好了初始化,比如:

在这里插入图片描述
5. 设置对象头信息(关于对象内存模型后面会介绍)
6. 调用构造方法,给对象中各个成员赋值


🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇

5.4 就地初始化

在声明成员变量时,就直接给出了初始值

在这里插入图片描述

注意:就地初始化时,代码编译完成后,编译器会将所有给成员初始化的这些语句添加到各个构造函数中。


🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇

5.5 打印成员变量的值

我们每次都要自己手动写一个打印的方法,然后来打印变量,这样很麻烦。

在这里插入图片描述

在这里插入图片描述
这里涉及到了重写,因为还没有学到重写,所以只需要简单了解下,知道能在IDEA中用快捷键自动生成打印的方法就可以了。

当不生成toString时,直接打印cat1打印出来的是对象的地址,写了toString后打印出来的是成员变量的内容。

注意:toString中的字符串内容和变量是可以自己修改的,但是方法名部分不能修改,否则会报错。

快捷键生成toString

在这里插入图片描述
在这里插入图片描述
生成toString方法后,只要直接打印对象的引用,就可以打印出成员变量的内容了。


🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇

6. 封装

6.1 封装的概念

面向对象程序三大特性:封装、继承、多态。而类和对象阶段,主要研究的就是封装特性。何为封装呢?简单来说就是套壳屏蔽细节。

比如:对于电脑这样一个复杂的设备,提供给用户的就只是:开关机、通过键盘输入,显示器,USB插孔等,让用户来和计算机进行交互,完成日常事务。但实际上:电脑真正工作的却是CPU、显卡、内存等一些硬件元件。

对于计算机使用者而言,不用关心内部核心部件,比如主板上线路是如何布局的,CPU内部是如何设计的等,用户只需要知道,怎么开机、怎么通过键盘和鼠标与计算机进行交互即可。因此计算机厂商在出厂时,在外部套上壳子,将内部实现细节隐藏起来,仅仅对外提供开关机、鼠标以及键盘插孔等,让用户可以与计算机进行交互即可。

封装:将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行 交互


🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇

6.2 访问限定符

Java中主要通过类和访问权限来实现封装:**类可以将数据以及封装数据的方法结合在一起,更符合人类对事物的认知,而访问权限用来控制方法或者字段能否直接在类外使用。**Java中提供了四种访问限定符:

在这里插入图片描述
比如:
public:可以理解为一个人的外貌特征,谁都可以看得到
default(什么都不写,不是写一个default): 对于自己家族中(同一个包中)不是什么秘密,对于其他人来说就是隐私了
private:只有自己知道,其他人都不知道

  • public:在任何地方都能使用
  • default(默认,不写修饰限定符):只能在当前包中使用(下面就会介绍包的概念)
  • private:只能在当前类中使用

【说明】

  • protected主要是用在继承中,继承部分详细介绍
  • default权限指:什么都不写时的默认权限
  • 访问权限除了可以限定类中成员的可见性,也可以控制类的可见性

在这里插入图片描述


🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇

6.3 包

6.3.1 包的概念

在面向对象体系中,提出了一个软件包的概念,即:为了更好的管理类,把多个类收集在一起成为一组,称为软件包。有点类似于目录。比如:为了更好的管理电脑中的歌曲,一种好的方式就是将相同属性的歌曲放在相同文件下,也可以对某个文件夹下的音乐进行更详细的分类。

在这里插入图片描述
在Java中也引入了包,包是对类、接口等的封装机制的体现,是一种对类或者接口等的很好的组织方式,比如:一个包中的类不想被其他包中的类使用。包还有一个重要的作用:在同一个工程中允许存在相同名称的类,只要处在不同的包中即可。


🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇

6.3.2 导入包中的类

Java中已经提供了很多现成的类供我们使用,例如Date类:可以使用 java.util.Date 导入java.util这个包中的Date类。

在这里插入图片描述
但是这种写法比较麻烦一点,可以使用import语句导入包

在这里插入图片描述
如果需要使用 java.util 中的其他类,可以使用 import.java.util.* ,这时就可以使用这个包中的所有类(使用哪个类时就会导入哪个类)(.*不能省略)

在这里插入图片描述
但是我们更建议显式的指定要导入的类名,否则还是容易出现冲突的情况。

在这里插入图片描述
在这种情况下需要使用完整的类名

在这里插入图片描述
可以使用 import static 导入包中的静态的方法和字段。(不推荐使用)

在这里插入图片描述

注意事项:
import和C++的 #include 差别很大,C++必须 #include来引入其他文件内容,但是Java不需要,import 只是为了写代码的时候更方便,import 更类似于 C++ 的 namespace 和using。


🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇

6.3.3 自定义包

基本规则

  • 在文件的最上方加上一个 package 语句指定该代码在哪个包中.
  • 包名需要尽量指定成唯一的名字, 通常会用公司的域名的颠倒形式(例如 com.bit.demo1 ).
  • 包名要和代码路径相匹配. 例如创建 com.bit.demo1 的包, 那么会存在一个对应的路径 com/bit/demo1 来存储代码.
  • 如果一个类没有 package 语句, 则该类被放到一个默认包中.

操作步骤

  1. 在 IDEA 中先新建一个包: 右键 src -> 新建 -> 包
    在这里插入图片描述
  2. 在弹出的对话框中输入包名, 例如 com.bit.demo1
    在这里插入图片描述
  3. 在包中创建类, 右键包名 -> 新建 -> 类, 然后输入类名即可
    在这里插入图片描述
  4. 此时可以看到我们的磁盘上的目录结构已经被 IDEA 自动创建出来了在这里插入图片描述
  5. 同时我们也看到了, 在新创建的 Test.java 文件的最上方, 就出现了一个 package 语句
    在这里插入图片描述

创建一个包其实就是创建文件夹,只是Java给了一个高大上的名字而已。

之前所说的不加修饰限定符时,对应的就是包权限,也就是只能在当前包中访问,这个包就是上文中介绍的包。


🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇

6.3.4 常见的包

  1. java.lang:系统常用基础类(String、Object),此包从JDK1.1后自动导入。
  2. java.lang.reflect:java 反射编程包;
  3. java.net:进行网络编程开发包。
  4. java.sql:进行数据库开发的支持包。
  5. java.util:是java提供的工具程序包。(集合类等) 非常重要
  6. java.io:I/O编程开发包

🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇

总结:

本篇介绍了对象的初始化方式及构造方法,还介绍了封装以及引出了包的概念,补充了this的三种用法。如果对于概念还感觉很模糊,后面的篇章中会有更详细的介绍,当把类和对象都学完后我相信你就会有一种醍醐灌顶、茅塞顿开的感觉,不要纠结于这些变量在内存中到底存储在哪,也不要纠结方法是怎么创建的,这些都是JVM去实现的,在后面学习JVM中这些都会详细学习。

前两篇其实并不算很难,接下来一篇会介绍static和代码块,等你弄明白了static后就会知道为什么写主函数时要写public static void,也会明白为什么平常写方法时都会默认写上static,下篇会非常精彩,同时难度也会有所增长,如果你想详细了解一定要关注我哟~~!!💪💪

  • 21
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 16
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夏.冬

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值