文章目录
- 一 . 面向过程的初步认知
- 二 . 如何创建一个类
- 三 . 如何创建一个对象
- 四 . this引用
- 五 . 构造方法
- 六 . 初始化
一 . 面向过程的初步认知
Java是一门纯面向对象的语言(Object Oriented Program,简称OOP),在面向对象的世界里,一切皆为对象。面向对象是解决问题的一种思想,主要依靠对象之间的交互完成一件事情。用面向对象的思想来涉及程序,更符合人
们对事物的认知,对于大型程序的设计、扩展以及维护都非常友好。
其实从我们开始学习编程到现在,我们一直都是在面向过程在编程,而从今天开始我们就要学会去面向对象来编程,在java的世界里面,一切皆是对象…
面向对象与面向过程的区别
我们拿洗衣服举例子
传统的洗衣服的过程,注重的是洗衣服的各种步骤,也就是注重的过程,中间少一个环节都可能完成不了工作,假设我们把这种映射到计算机,也就是每次处理一个问题都要有不同的方案,代码的可维护性大幅度下降
线代洗衣服的过程
总结一下
其实面向对象和面向过程的区别就是,面向对象解决问题的方式是通过多个对象之间的相互协作来对一个系统性的信息进行处理,这样就会更加的高效,代码的可维护性及其可复用性将会大幅度上升
二 . 如何创建一个类
类与对象的关系就好像设计图与房子,类就是一个设计图,但是不是一个实体,房子就是根据设计图创造出来的实体,也就是有实际的存储空间
创建类
class ClassName{
field; // 字段(属性) 或者 成员变量
method; // 行为 或者 成员方法
}
其实class前面还可以加上一些修饰符进行修饰,但是我们不明确这个修饰符的具体含义到底是什么,但是目前可以确定的是,一个文件中只能有一个public修饰的类,而且类名必须与文件名保持一致,但是也可以没有public修饰的类
一个文件中最好只有一个类,其实也可以有多个类,而且每一个类都有其各自的main方法,鼠标右击进行运行的时候在哪个类运行哪个类的main方法
下面我们创建一个洗衣机类
class WashMachine {
/**
* 下面其实也就是这个洗衣机类的成员变量,也可以称之为字段/属性
* 在现阶段修饰符你就只管写public,后续再说
* 成员变量是定义在方法外部,但是在类的内部,声明周期与局部变量是不一样的
*/
public String brand;
public String type;
public double length;
public double width;
public double height;
public double weight;
/**
* 这其实是这个类的成员方法,也可以称之为实例方法/行为
* 在现阶段我们所有的类的实例方法修饰符都加上public 请记住,我们暂时不去加上static
* 在方法内部定义的变量我们称之为局部变量,比如我们在下面定义的 a = 10
* 与实例变量不同,该局部变量的生命周期从方法调用创建,调用结束后销毁
*/
public void wash(){
int a = 10;
System.out.println("洗衣机正在洗衣服");
}
public void dry(){
System.out.println("洗衣机正在甩干衣服");
}
public void setTime(){
System.out.println("洗衣机的定时功能");
}
}
如何在idea里面修改我们类的名称
找到rename修改就行
三 . 如何创建一个对象
刚刚的分析中,我们已经学会了如何写一个类,也就是相当于我们现在有了图纸,那下一步就是盖我们的房子了,在java中我们是通过new关键词来创建一个对象
并通过我们的**" . "**操作符来访问其中的成员变量或者是成员方法
具体代码如下参考
public static void main(String[] args) {
//创建一个对象
WashMachine washMachine = new WashMachine();
//通过.操作符来访问成员变量
washMachine.brand = "西门子";
washMachine.type = "w3045";
washMachine.height = 134.3;
washMachine.width = 134.4;
washMachine.weight = 45.75;
washMachine.length = 121.3;
//通过.操作符来访问成员方法
washMachine.wash();
washMachine.dry();
washMachine.setTime();
}
用new操作符创建对象时的内存分析
以上面的代码举例子,当用new操作符的时候,我们的jvm会在堆空间分配一块内存用来管理我们的对象数据
请注意此时我们在堆上产生了一个对象,但是这个空间中只有对象的属性,没有成员方法,具体实现机制在以后再说吧…
所以我们假设打印washMachine的值,打印出来的其实就是它里面保存的地址
上面的WashMachine@4eec7777其实就是我们的地址,其实我们java中的地址都是经过处理过的地址,这里其实显示的hashcode码
截至到这里,你应该已经完成了三项事情
1.学会创建类
2.学会创建对象
3.学会初始化对象
四 . this引用
this说白了就是一个当前对象的引用,或者说,就是当前对象
this的使用原则**,任何情况都别省略…**免得以后事多
假设这里的形式参数不是brand,那其实就可以不加this,但是我们的原则就是this都加上
那编译器怎么就知道this是啥呢,其实我们的方法在传参的时候默认传了一个this,但是程序员是不知道的
其实真实的情况就是像下面这样,显示传递之后是不会报错的
this先懂这么些就行,下面的构造方法里面我们详细说一下this,插一张我们学this时候的分析图(我自己看的)
五 . 构造方法
所谓构造方法其实就是一种特殊的方法,构造方法的作用其实是对对象进行创建和初始化
构造方法与普通方法的不同之处就在于定义不一样,构造方法的定义一般是
(访问修饰符) 方法名称 (形式参数列表){
方法体
}
与普通方法的不同之处就是构造方法没有返回值(void)也不行,其次就是构造方法的方法名称必须与类名保持一致
构造方法的特性如下
- 名字必须与类名相同
- 没有返回值类型,设置为void也不行
- 创建对象时由编译器自动调用,并且在对象的生命周期内只调用一次(相当于人的出生,每个人只能出生一次)
- 构造方法可以重载(用户根据自己的需求提供不同参数的构造方法)
下面我们演示一下构造方法的定义
class Student {
public String name;
public int age;
public double height;
public double weight;
下面是无参数的构造方法
请注意系统会默认提供一个无参数的构造方法,如果你已经进行构造方法的定义,那就不会默认提供
public Student(){
System.out.println("正在调用无参数的构造方法...");
}
四个参数的构造方法
public Student(String name,int age,double height,double weight){
在上文我们已经说了这里隐式传递了一个this(是真的么)
this.name = name;
this.age = age;
this.height = height;
this.weight = weight;
System.out.println("现在正在调用四个参数的构造方法");
}
}
其实在构造方法的时候,并没有隐式传递我们的this,解释如下
这其实是非常合理的,首先this是当前的对象的引用,而构造方法是为了构造当前的对象而产生的,你都没对象,怎么会传递的this啊…但是这里以我们目前的水平还是有点蒙圈…
在我们的构造方法种,也可以使用this(),来简化我们的代码
示例如下:
class Student {
public String name;
public int age;
public double height;
public double weight;
public Student(){
请你要注意这个this()一定要在所在语句的第一行
this("ljh",19,183.1,75.3);
System.out.println("调用了无参的构造方法");
}
public Student(String name,int age,double height,double weight){
this.name = name;
this.age = age;
this.height = height;
this.weight = weight;
System.out.println("正在调用四个参数的构造方法");
}
}
注意this()的这种写法,不可以形成环
这里构成我们的递归构造器调用,所以是不合理的…
六 . 初始化
默认初始化:
现在我们来解释一下上面的问题,临时变量如果不进行初始化就会报错,那为什么成员变量不会有这样的问题,下面我们来分析一下,在创建对象的时候,都发生了什么事情
要搞清楚这个过程,就需要知道 new 关键字背后所发生的一些事情:
Date d = new Date(2021,6,9);
在程序层面只是简单的一条语句,在JVM层面需要做好多事情,下面简单介绍下:
- 检测对象对应的类是否加载了,如果没有加载则加载
- 为对象分配内存空间
- 处理并发安全问题
比如:多个线程同时申请对象,JVM要保证给对象分配的空间不冲突
数据类型 默认值
byte 0
char ‘\u0000’
short 0
int 0
long 0L
boolean false
float 0.0f
double 0.0
reference null - 初始化所分配的空间
即:对象空间被申请好之后,对象中包含的成员已经设置好了初始值,比如: - 设置对象头信息(关于对象内存模型后面会介绍)
- 调用构造方法,给对象中各个成员赋值
总结一句话,在调用我们的构造方法之前,就已经对成员变量进行了初始化操作
就地初始化:
就是在定义实例变量的同时进行我们的初始化操作
class Student {
private String name = "ljh";
private int age = 19;
private char gender = '男';
public static String classroom = "zzu112Java";
}
总结一下,初始化的方式有 代码块初始化,构造方法初始化,就地初始化,默认初始化
下面的几种初始化我们在后面的章节进行介绍…