1.面向对象的初步认识
1.1 什么是面向对象
Java是一门纯面向对象的语言(Object Oriented Program,简称OOP),在面向对象的世界里,一切皆为对象。面向对象是解决问题的一种思想,主要依靠对象之间的交互完成一件事情。用面向对象的思想来涉及程序,更符合人 们对事物的认知,对于大型程序的设计、扩展以及维护都非常友好。
类 和 对象 是 面向对象中,最关键的两个要点
1.2面向对象和面向过程
用面向过程的方式制作一杯咖啡:
- 准备材料:咖啡粉、热水、咖啡杯、搅拌棒等。
- 量取适量的咖啡粉,加入咖啡杯中。
- 烧开适量的水,待水温降至约90°C时倒入咖啡杯中。
- 用搅拌棒搅拌咖啡粉和热水,确保咖啡充分溶解。
- 等待几分钟,让咖啡充分浸泡。
- 用搅拌棒再次搅拌咖啡杯中的咖啡。
在这个过程中,每个步骤都是按照一定顺序执行的,没有使用任何特定的对象或类。整个过程都是围绕着完成某个目标——制作一杯咖啡——而进行的。这就是一个面向过程的例子。
用面向对象的方式制作一杯咖啡:
先定义两个类来分别存储有关咖啡机和咖啡的信息,如咖啡的品种、浓度,咖啡机的功率、容量等等....
在主程序中,通过类创建一个咖啡机对象和咖啡对象,并设置好参数,调用咖啡机的方法来操作咖啡,比如打开咖啡机、加水、加糖等。调用咖啡的方法来完成泡咖啡的过程,比如添加咖啡豆、研磨咖啡豆、调节温度等。
通过面向对象的方式,我们可以将泡咖啡的过程抽象为一个咖啡机对象和一个咖啡对象,通过对象之间的交互来完成的。
这种方式可以更好地封装和组织代码,使代码更加可读、可维护和可扩展。
面向过程和面相对象并不是一门语言,而是解决问题的方法,没有那个好坏之分,都有其专门的应用场景。
2.类定义和使用
2.1简单认识类
类是用来对一个实体(对象)进行描述的,主要描述该对象有哪些属性(外观尺寸),哪些功能。
2.2类的定义格式
在java中定义类时需要用到class关键字,具体语法如下
//创建类
class 类名{
field //属性 or 成员变量
method //行为 or 成员方法
}
举例:定义一个学生类,用来表示学生的相关信息
public class Student {
//属性
public int id; //学生的学号
public String name; //学生的姓名
public int age; //学生的年龄
//这里还有非常多的信息,应该有哪些属性,取决于要解决的问题
//方法
public void DoClass(){
System.out.println(name +"同学在上课");
} //上课
public void DoHomework(){
System.out.println(name + "同学在做作业");
} //做作业
public void Exam(){
System.out.println(name + "同学在考试");
} //考试
}
注意事项:
- 一般一个文件当中只定义一个类
- main方法所在的类一般要使用public修饰
- public修饰的类必须要和文件名相同
- 不要轻易去修改public修饰的类的名称
3.类的实例化
3.1 什么是实例化
定义好了一个类,就相当于在计算机中定义了一个新的类型。与 int、double 类似,只不过 int、double 是Java自带的内置类型,而类是用户自定义了一个新的类型。
用类型创建对象的过程,称为类的实例化
在Java中采用关键字 new 来配合类名实例化对象
public static void main(String[] args) {
Student student = new Student();
}
当实例化创建完后就可以使用对象的成员(属性和方法)
通过 . 成员访问运算符来进行调用
public static void main(String[] args) {
Student student = new Student();
student.name = "清清";
System.out.println(student.name);
student.DoHomework();
Student student2 = new Student();
student.name = "风风";
System.out.println(student.name);
student.DoClass();
}
3.2 类中属性和方法的说明
一个类可以实例化出多个对象
属性是每创建一个对象就有一个新的属性
类中也有方法,JVM中有一个专门的内存空间,称为 “方法区”
一个类中的方法,都是只在内存中有一份的,被所有的对象共用
4.this引用
4.1 为什么要有this引用
先看一个日期类的例子
public class Date {
public int year;
public int mouth;
public int day;
public void setDate(int y,int m ,int d){
year = y;
mouth = m;
day = d;
}
public void printDate(){
System.out.println(year + "/" + mouth + "/" + day);
}
public static void main(String[] args) {
Date date = new Date();
date.setDate(2024,12,12);
date.printDate();
}
}
在这段代码中定义了三个成员变量,分别是 year ,mouth,day,再定义一个setDate方法来进行传参,打印。
在setDate中我们将形参的变量名字特地跟成员变量名区分开,如果将形参名写成和成员变量名一样呢?
当我们修改完后,所有的变量名都变成灰色了
这是因为编译器会优先把year理解成形参,而不是成员变量
这里就需要通过 this 关键字来区分哪些是成员变量
public void setDate(int year,int mouth ,int day){
this.year = year;
this.mouth = mouth;
this.day = day;
}
4.2 什么是this引用
this引用指向当前对象(成员方法运行时调用该成员方法的对象),在成员方法中所有成员变量的操作,都是通过该 引用去访问。
4.3 this引用的特性
1. this的类型:对应类类型引用,即哪个对象调用就是哪个对象的引用类型;
2. this只能在"成员方法"中使用 (如果给方法加上static,就无法使用this);
3. 在"成员方法"中,this只能引用当前对象,不能再引用其他对象;
4. this是“成员方法”第一个隐藏的参数,编译器会自动传递,在成员方法执行时,编译器会负责将调用成员方法 对象的引用传递给该成员方法,this负责来接收。
5.对象的构造和初始化
5.1如何初始化对象
在这段代码中,只是给 date 这个引用初始化了,并没有将成员变量初始化
我们可以通过在类中赋值的方式初始化,这里主要介绍类的另一个语法机制,构造方法
5.2构造方法
构造方法是初始化对象的最核心方式
语法格式:
public Date(){
}
在里面就可以执行对成员变量的初始化
//第一个构造方法
public Date(){
year = 2024;
mouth = 10;
day = 20;
}
这是第一种无参的构造方法
还可以写一个带有三个参数的构造方法
//带有三个参数的构造方法
public Date(int year,int mouth ,int day){
this.year = year;
this.mouth = mouth;
this.day = day;
}
上述两个构造方法:名字相同,参数列表不同,因此构成了方法重载
构造方法中,可以通过 this 调用其他构造方法来简化代码
代码示例:
public Date(){
this(2024,12,12);
}
public Date(int year,int mouth ,int day){
this.year = year;
this.mouth = mouth;
this.day = day;
}
this(...)必须是构造方法中第一条语句
这段代码中我们就通过 this 调取了有参数的构造方法,这个时候代码就可以复用了。
注意事项:
- 构造方法的方法名,必须和类名一致,并且不能有返回值;
- 构造方法一般不需要手动调用,new 对象时,由编译器自动调用,并且在对象的生命周期内只调用一次;
- 构造方法可以重载(用户根据自己的需求提供不同参数的构造方法);
- 如果用户没有显式定义,编译器会生成一份默认的构造方法,生成的默认构造方法一定是无参的;
- 如果没有定义构造方法,编译器会默认生成一个不带参数的构造方法,确保 new 操作能够正常运行
构造方法虽然很好用,但是随着语法的发展进化,还演化出了一些其他的 初始化 的方式
5.3就地初始化
回到我们最开始定义成员变量时
public class Date {
public int year = 2024;
public int mouth = 12;
public int day = 23;
}
在声明成员变量时就进行赋值就叫做就地初始化
5.4代码块初始化
使用一个大括号,将要初始化的变量括起来,就叫做代码块初始化
{
year = 2024;
mouth = 11;
day = 22;
}
注意这三种初始化的执行顺序
- 就地初始化
- 代码块初始化
- 构造方法
5.5 IDEA 快速生成构造方法
操作方法:
按住 alt + insert
在弹出的对话框选择第一个
在这选择需要初始化的变量
public Date(int year, int mouth, int day) {
this.year = year;
this.mouth = mouth;
this.day = day;
}
IDEA 就会自动帮我们初始化完所选择的变量
6.对象的打印
Date date = new Date();
System.out.println(date);
当我们直接打印变量时,会得到下面这个结果
这并非是对象的地址,而是hashCode,之后涉及到数据结构在细讲
在数组中我们可以使用 Arrays.toString() 将数组转为字符串,然后进行打印输出
对于类来说,也可以 toString
首先添加一个toString方法
//注意这里的写法,方法名字固定toString,返回值是String,无参数
public String toString(){
//在返回的地方写上要打印的格式
return year + "/" + mouth + "/" + day;
}
toString 是一个特殊的方法
当打印对象的时候,编译器会自动调用 toString,把对象转成 String
同样可以使用IDEA快速生成的方法。
方法与5.5一样
可以看到最上方有一个 @Override
这是Java内置的一个注解,相对于对这个类/方法进行了一些“补充说明”
不加这个功能也是可以正常完成的,加了之后,编译器会做更多的工作(例如更严格的语法检查.....)
小试牛刀:
1.下列哪些说法是错误的?为什么?
A.一个类只能实例化一个对象
B,一个引用可以同时指向多个对象
C.Person p = null;表示p这个引用指向一个空对象
D.当一个类没有定义构造方法的时候,该类中不会默认生成构造方法