前言
从这篇文章开始,我们就进入到了JavaSE的核心部分。这篇文章是Java类和对象的第一篇,主要介绍类和对象的概念,this关键字以及构造方法~~
什么是类?什么是对象?
学过C语言的老铁们,可以类比struct自定义一个结构体,类就类似结构体,对象就类似使用结构体关键字来创建结构体变量(结构体普通变量,结构体指针,结构体数组),但是类里面可以定义方法(也就是C语言中的函数)
没有学过C语言的老铁们,可以这样理解,假设你是一个建筑工程师,类就是你画出来的建筑图纸,而对象就是用图纸实际建造出来的房子,图纸就是用来描述这个房子具体的细节(长,宽,高,材料等等)
类是用来对一个实体(对象)来进行描述的,主要描述该实体(对象)具有哪些属性(外观尺寸等),哪些功能(用来干啥),描述完成后计算机就可以识别了。
类的创建
我们可以使用 class 关键字来定义一个类
一个类里面包含字段/属性/成员变量,也可以包含成员方法~~
class 类名{
字段、属性、成员变量;(定义在类里面,方法外面)
成员方法;
}
下面我们来定义一个学生类:
class Student{
//字段、属性、成员变量
public String name;
public int age;
public String stuNum;
//成员方法
public void sleep(){
System.out.println(name + "睡觉");
}
public void haveClass(){
System.out.println(name + "上课");
}
public void doHomework(){
System.out.println(name + "做作业");
}
}
对象的实例化
什么是对象的实例化,简单来说就是创建一个对象,我们需要使用类名和 new 关键字来进行创建~~
创建格式:
类名 对象 = new 类名()
代码示例:
Student student1 = new Student();
对象的使用
我们可以通过对象来访问对象里面的成员变量和成员方法~~
使用格式:对象后面加一个点号再加相应的成员方法或者成员变量即可。
我们来试着使用一下,还是上面的学生类为例子:
public static void main(String[] args) {
Student student1 = new Student();
student1.name = "张三";
student1.age = 10;
student1.stuNum = "32";
student1.sleep();
student1.haveClass();
student1.doHomework();
}
面向过程和面向对象的区别
面向过程和面向对象本质上都是解决问题的方法,面向过程注重的是过程,而面向对象就是需要对象与对象之间的联系,面向对象的关键就是(找到对象,创建对象和使用对象),例如你上网购物,如果你是面向过程,你就会这样子,下单,工厂制作商品,工人发货,物流人员进行运输,快递员将快递送到指定地点,你去那个地方取件,最后确认收货,这就是面向过程。
如果你是面向对象,那么就是你和快递这两个对象之间的联系,你只需要关心为这个对象(商品)付款然后取件,就没了。
C语言就是典型的面向过程的编程语言,而Java是一门纯面向对象的语言(Object Oriented Program,简称OOP),在面向对象的世界里,一切皆为对象。面向对象是解决问题的一种思想,主要依靠对象之间的交互完成一件事情。
this 关键字介绍
现在我以下面的代码为例子:
class Date{
public int year;
public int month;
public int day;
public void initDate1(int year, int month, int day){
year = year;
month = month;
day = day;
}
public void initDate2(int y, int m, int d){
year = y;
month = m;
day = d;
}
public void printDate(){
System.out.println(year + "年 " + month + "月 " + day + "日 ");
}
}
public class Test{
public static void main(String[] args) {
Date d1 = new Date();
Date d2 = new Date();
Date d3 = new Date();
d1.initDate1(2024,5,13);
d1.printDate();
System.out.println("=====================");
d1.initDate2(2024,5,13);
d1.printDate();
}
}
思考一下输出结果是什么?
再谈对象中成员变量
对象中的成员变量和神奇,一旦对象创建好,对象里面的成员变量其实会被赋值成默认值,所以上面才会出现0年0月0日~~
根据上一篇的JVM内画图,我们来看一下对象的分布:
对象在堆里是只包含成员变量,没有成员方法的~~
来现在解决一下为什么下面的代码不行~~
public void initDate1(int year, int month, int day){
year = year;
month = month;
day = day;
}
因为程序遵循局部变量优先使用原则,所以上面的代码相当于是局部变量自己给自己赋值~~
如何解决?
添加 this 关键字就可以了
public void initDate1(int year, int month, int day){
this.year = year;
this.month = month;
this.day = day;
}
this 关键字能让编译器识别这是成员变量而不是局部变量~~
因此建议大家习惯性地使用this关键字~~
再理解this
public class Test{
public static void main(String[] args) {
Date d1 = new Date();
Date d2 = new Date();
Date d3 = new Date();
d1.initDate1(2024,5,13);
d1.printDate();
System.out.println("=====================");
d2.initDate2(2024,5,14);
d2.printDate();
System.out.println("=====================");
d3.initDate2(2024,5,15);
d3.printDate();
}
}
问题来了,上面创建了三个对象,都调用了printDate()方法,这些方法是如何区分这是哪个对象的呢?
在Java中,调用成员方法时会发生隐式传参:
public void initDate1(Date this, int year, int month, int day){
this.year = year;
this.month = month;
this.day = day;
}
public void initDate2(Date this, int y, int m, int d){
year = y;
month = m;
day = d;
}
public void printDate(Date this){
System.out.println(year + "年 " + month + "月 " + day + "日 ");
}
大家看到上面的 Date this(这个是可以不用写的,写了你会发现没有报错) 这个就是因为Java 自动帮你传递了这个对象,所以 this 其实就是可以指代这个对象时谁。
当你调用某个对象的成员方法时,Java会自动帮你把对象传递过去,并且使用 this 来接收这个对象,所以上面我们可以使用 this.year = year 来避免局部变量自我赋值,而是将局部变量赋值给对象的成员变量。
this与成员方法
由于this 就是指向对象的,所以我们可以在非静态的成员方法中进行使用来调用其他的成员方法~~
静态与非静态会在下一篇文章中讲解~~
构造方法
构造方法的作用是给成员变量进行初始化的
创建格式:
修饰符 类名(形参列表){
方法体
}
注意构造方法没有返回值,并且和普通的方法一样是可以发生方法的重载的~~
名字必须与类名相同,在创建对象时,由编译器自动调用,并且在整个对象的生命周期内只调用一次。
再谈对象的实例化
对象的示例化简单来说可以分为两步,第一步是分配内存空间,第二步是调用构造方法
一旦new 类名(参数) 的时候就会调用构造方法~
可是上面的代码中,我们没有写过构造方法,代码为什么会正常执行并且没有报错呢?
因为在Java中,如果你没有写过任何的构造方法的话,Java会给你自动提供一个空的构造方法(这个方法是空的,没有任何效果)
但是如果你写了构造方法的话,Java是不会帮你提供一个空的构造方法~~
例如下面的代码:
class Dog{
public String name;
public Dog(int year){
System.out.println(year + "出生了");
}
}
public class Test{
public static void main(String[] args) {
Dog dog = new Dog(2024);
Dog dog2 = new Dog();
}
}
dog2 是无法进行创建的,因为Dog的构造方法只有public Dog(int year),而没有Dog()这个构造方法!!!
this与构造方法
在构造方法中是可以使用this关键字来调用构造方法的~
调用格式比较特殊,this(参数)
在构造方法中可以调用其他构造方法,但必须放在第一行!!!
并且使用 this 调用构造方法的时候不能形成环!!!
下面代码就是成环的表现~~
这是不被允许的!!!
public Dog(){
this(2024);
}
public Dog(int year){
this();
System.out.println(year + "出生了");
}
总结
this 关键字:
- this.当前对象的成员变量
- this.当前对象的非静态的成员方法
- this() 调用其他的构造方法