文章目录
- 一、类与对象的初步认知
-
- 1.面向过程和面向对象
-
- (1) 面向过程和面向对象的区别
- 2.类和对象
- 二、类和类的实例化
-
- 1.类的定义
- 2.实例化一个类
- 3.类在内存中的存储
- 4.访问类的成员
- 三、类的成员
-
- 1.成员变量的初始化
- 2.方法
- 3.toString方法
-
- (1)序列化和反序列化
- 4.匿名对象
- 四、static 关键字
-
- 1.静态成员变量
-
- (1) 静态成员变量在内存中的存储
- 2.静态成员方法
- 五、封装
-
- 1.private实现封装
- 2. getter和setter方法
-
- (1) 在 IDEA中快速生成 get 和 set 方法
- 五、构造方法
-
- 1.构造方法的基本使用
- 2.构造方法的重载
- 3.this关键字
- 六、代码块
-
- 1.本地代码块
- 2.静态代码块
- 3.实例代码块
- 4.执行顺序
- 总结
-
- 完!
一、类与对象的初步认知
1.面向过程和面向对象
在了解类和对象之前我们先了解一下什么是面向过程和面向对象。
面向过程编程:
C语言就是面向过程编程的,关注的是过程,分析出求解问题的步骤,通过函数调用逐步解决问题。
面向对象编程:
JAVA是基于面向对象的,关注的是对象,将一件事情拆分成不同的对象,靠对象之间的交互完成。
来举个例子,就比如洗衣服:

在这里洗衣机就是一个对象,所以只要操作洗衣机所具备的功能,都要定义在对象中。
(1) 面向过程和面向对象的区别
面向过程:注重的是过程,在整个过程中所涉及的行为,就是功能。
面向对象:注重的是对象,也就是参与过程所涉及到的主体。是通过逻辑将一个个功能实现连接起来
2.类和对象
这样说可能太过于抽象
上面说了java是面向对像编程,如果我们先要找对象编程,首先就得找对象而对象是通过类产生的。
我们来举个通俗易懂的例子:
就比如建房子,类就相当于一个模板也就是图纸

而对象就是房子,也就是一个实体。只有通过图纸才能建房子。

所以只有通过类才能产生对象,我们以后开发其实就是:
找对象,建对象,用对象,并维护对象之间的关系。
二、类和类的实例化
1.类的定义
在java当中我们用 class 关键字来创建一个新的类型,我们把它叫做类。
一个类是由方法和字段组成
这里我来举一个例子,我用class定义了一个 People 类,来描述一个人。
class为定义类的关键字,People是类的名字,{}中为类的主体。
类中的元素称为:成员变量也就字段或者叫做成员属性。 这里面的name、age、sex 都是字段。
类中的方法称为:成员方法
字段(成员变量):定义在类的内部,方法的外部
2.实例化一个类
用类类型创建对象的过程,称为类的实例化
我们已经知道通过class关键字来定义一个类了,而我们知道类只是相当于一个模板,所以我们要通过类来实例化对象,由类产生对象的过程叫做 实例化一个对象。
代码如下(示例):
讯享网
我们通过 new 关键字来实例化一个对象

一个类是可以实例化多个对象的,就比如我上面那个例子一个图纸是不是可以建很多房子。


通过 new 关键字我们是可以实例化多个对象的
3.类在内存中的存储
我们知道了如何定义类和通过类实例化对象,那么一个类在内存到底是如何存储的呢?
和数组一样类也属于于引用,而引用指向的是一个对象,p1和p2这些变量都是局部变量它们属于引用,我在前面数组的博客也讲到过局部变量是在栈上开辟内存的,引用里面存的是对象的地址,这些变量里存的都是引用每实例化一个对象就在堆区开辟一块内存。对象里面存的就是字段。
注意:类里面的方法并不是是存在堆区的 ,方法本身是不占内存的,方法是存在方法区里的方法表中,在每个对象 new 好之后前面有几个字节存的就是方法表的地址,只有在调用这个方法时,会通过方法表的地址找到这个这个方法,然后在栈上为这个方法开辟栈帧。当然这里只是简单介绍一下,到后面的博客中会详细讲解。

引用不一定是在栈上的!如果它是一个示例成员变量,那么它就是在堆上的,就比如这里的 name和 sex。
4.访问类的成员
我们知道了如何定义个和实例化一个对象,那么怎么访问这些成员变量呢?
讯享网
运行结果

注意:这里的成员变量并没有初始化,不同于局部变量不初始化会报错。成员变量不初始化是其类型对应的0值。

三、类的成员
1.成员变量的初始化
我们把定义在类的内部,方法的外部的变量叫“字段”或者叫它成员变量有时候也叫它“属性"。这三种叫法并没有严格区分。
运行结果

还有一种就是在定义成员变量的时候赋值,但并不建议这样写,因为在实例化后还是能初始化,没必要多此一举。而且这个类是一个模板,把模板初始化也是不合适的。
再来看一个代码,这个代码是什么意思呢?

这段代码的意思是 p2这个引用,引用了p1指向的这个对象
还有一个问题,一个类可以同时指向多个对象吗?
答案是不能,这里的p只会指向最后一个对象,前面的都被覆盖掉了。
所以一个引用只能同时指向一个对象
2.方法
就是我们曾经讲过的方法,用于描述一个对象的行为.
运行结果

成员方法也是通过 对象访问的!
3.toString方法
运行结果

我们发现这里打印的是一个地址,这里在打印的时候会默认调用Object 的 toString 方法来打印

默认调用Object 的 toString 方法,但是当前类如果重新实现 toString 这个方法后,就会调用当前类重新写的这个toString方法来打印。
IDEA快速生成Object的toString方法快捷键:alt+insert

再来看一段从写toString方法后的代码
运行结果

我们发现当我们重写toString方法后打印的就是我们重写的toString方法里的内容。
当然重写里双引号里面的内容是可以修改的
注意: 所以当我们没有重写toString方法的时候,就会默认调用Object 的 toString 方法来打印
@Override 在 Java 中称为 “注解”, 此处的 @Override 表示下面实现的 toString方法是重写了父类的方法.
(1)序列化和反序列化
4.匿名对象
没有引用的对象称为匿名对象.
匿名对象只能在创建对象时使用.
如果一个对象只是用一次, 后面不需要用了, 可以考虑使用匿名对象
用法如下
每使用一次就得 new 一次
四、static 关键字
1.静态成员变量
我们来看下这段代码,我们用 static 关建键字创建了一个静态成员变量cont,我分别用引用和类名来访问 cont ,发现通过对象来访问得时候编译器给了一个警告。

运行结果

运行发现并没有报错,但对于整体的一个规范我们还是建议用 类名来访问静态成员变量。
所以静态成员变量的访问方式为 类名.静态成员变量
(1) 静态成员变量在内存中的存储
来看一个代码:
运行结果

我们发现 age和cont的区别就是一个没有被 static修饰,一个被static 修饰,那是不是这cont就是同一个cont呢?

静态成员变量是存在方法区,所以它的访问是不依赖于对象的。
让我们再来看一个例子
运行结果

和普通成员变量不同的是这里我们并没有实例化一个对象,直接通过类名来访问了cont,而普通成员变量不实例化是会报错的。
同样来看这个例子,这段代码运行会报错吗?
运行结果

这是为什么呢?我们前面说过 null.任何东西都会出现空引用异常,那这里为什么没有呢?
这里的 p代表p不指向任何对象,而我们已经说过静态成员变量的访问时不依赖于对象的,所以这里并没有发生异常。但如果通过 p访问普通成员变量的话就会报错。
总结:

2.静态成员方法
通过 static 关键字来创建静态成员方法,且也是通过 类名来访问的
运行结果:

再来看一个例子:
为什么在普通成员方法里访问普通成员变量不报错,而在静态成员方法就报错呢?

同理可推到出,在静态的成员方法内部也是不可以调用普通成员方法的

所以在静态的成员方法内是不可以访问普通的成员变量的,也不能调用普通成员方法
注意:我们曾经写的方法为了简单, 都统一加上了 static. 但实际上一个方法具体要不要带 static, 都需要是情形而定.
静态的在类加载的时候就已经定义好了,具体在后面的JVM中会讲解到。
再来看一个final修饰的成员变量,这里的存储和final没关系,主要还是看static修饰。

五、封装
OOP 语言:面向对象编程,有一些重要的特征:继承 封装 多态
封装:在我们写代码的时候经常会涉及两种角色: 类的实现者和类的调用者
那类的调用者调用这个类的时候发现这个类被修改,那么它就要大量修改代码。所以 这样的代码非常不安全。

为了避免这样的情况就得使用封装
1.private实现封装
private/ public 这两个关键字表示 “访问权限控制” .
这里我用private修饰了name,它只能在当前类里使用

2. getter和setter方法
当我们用private修饰字段后,这个字段就无法被直接使用了。
这个时候就用到了 get 和 set 方法了
getName 即为 getter 方法, 表示获取这个成员的值.
setName 即为 setter 方法, 表示设置这个成员的值
不是所有的字段都一定要提供 setter / getter 方法, 而是要根据实际情况决定提供哪种方法.
运行结果

总结:封装其实就是将一些需要的字段或者方法,使用private关键字进行修饰,同时提供对应的get和set方法提供给外部
(1) 在 IDEA中快速生成 get 和 set 方法
Alt+Insert 键

五、构造方法
构造方法是一种特殊方法, 使用关键字new实例化新对象时会被自动调用, 用于完成初始化操作
构造方法没有返回值,且方法名和类名是相同的
构造方法是用来构造对象的(实例化对象)
new 执行过程
1.为对象分配内存空间
2.调用合适的构造方法
1.构造方法的基本使用
运行结果:

那么为什么我们前面示例化对象时为什么没有构造方法呢?
如果我们没有写构造方法,系统默认会有一个没有参数且没有任何内容的构造方法

2.构造方法的重载
构造方法和方法一样是可以实现重载的,前面的博客中我们也讲到过重载
重载:
1.方法名要相同
2.参数列表不同(类型和个数)
3.返回值不做要求
代码如下:
运行结果:

3.this关键字
this的三种用法:
1.this.data (访问当前对象的成员变量)
2.this.func() (访问当前对象的成员方法)
3.this.() (访问当前对象自己的构造方法)
在前面说封装的时候我们讲到 get 和 set 方法,当我们自己写构造方法的时候和编译器生成的构造方法有一个不一样的地方。

来看一段代码:
我们把形参的名字改成了name
运行结果:
这是为什么呢?这里传过去的明明是张三
其实这里是局部变量优先了,相当于自己给自己赋值。

我们只需要加一个 this
运行结果

有的书上说 this 代表当前对象,其实这样的说法并不准确。
正确的说法应该是:this表示当前对象引用
注意:
1.this 是不可以访问静态的成员变量的
2.同样的静态方法的内部也是不能使用 this 的
3.我们以后要习惯使用 this ,避免出现上面的那种情况发生
同样 this 也可以访问成员方法
运行结果:

最后就是通过 this()访问当前对象自己的构造方法
1.只能在构造方法内使用
2.只能使用一个this()
3.只能放在构造方法的第一行
代码如下:
运行结果

六、代码块
1.本地代码块
方法内部的代码块,没什么意义了解即可。
2.静态代码块
创建静态代码块
注意:静态代码块只执行一次

注意:在静态代码块里也是一样的,不可以使用非静态的数据
。
3.实例代码块
实例代码块也叫构造代码块,在示例代码块中可以对属性进行赋值
4.执行顺序
如果静态代码块、示例代码块和构造方法同时存在,它们的执行顺序是什么呢?
1.静态代码块—>2.实例代码块—>3.构造方法
来看例子:
执行结果:

我们再来看一种情况:
我们知道 静态代码块是最先执行的,那我在定义静态成员变量的时候同时赋值。
运行结果:

我们再把静态代码交换顺序
运行结果:

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/2952.html