一、面向对象和面向过程的认识
面向对象:是解决问题的一种思想,主要依靠对象之间的交互完成一件事情。Java是一门纯面向对象的语言(Object Oriented Program,简称OOP)。
举个栗子:
我们现在洗衣服基本都是用洗衣机,整个洗衣服的过程就是:人将衣服放进洗衣机里,倒入洗衣粉,启动洗衣机。
整个过程共有4个对象:人、衣服、洗衣粉、洗衣机。
整个洗衣粉的过程主要是通过上述4个对象之间的交互完成的,我们不需要关心洗衣机是如何洗衣粉、如何甩干衣服的。
面向过程:是一种以过程为中心的编程思想,就是分析出解决问题所需要的步骤,然后用代码把这些步骤一步一步实现(Procedure Oriented Program,简称POP)。
我们继续以洗衣粉为例:
传统的洗衣服过程:拿个盆接一盆水 → 把衣服放入盆中 → 倒入洗衣粉 → 用手搓衣服 → 换盆水 → 再搓一遍 → 拧干 → 晾衣服。
传统的洗衣服方式注重的是洗衣服的过程,少了一个环节,衣服可能都洗不干净。
注意:面向对象和面向过程都是一种解决问题的思想,各有各的应用场景,没有好坏之分。
二、类的定义和使用
1、简单认识类
类是用来描述一个对象的,主要描述该对象有哪些属性或者功能。
比如:我们可以用一个类来描述一个洗衣机。
洗衣机的属性:品牌、型号、重量、长、宽、高、颜色等等。
洗衣机的功能:洗衣服、烘干衣服、定时等等。
接下来,我们就可以用Java代码创造一个洗衣机了:
class WashMachine{
//1、字段/属性 (成员变量)
public String brand; // 品牌
public String type; // 型号
public double weight; // 重量
public double length; // 长
public double width; // 宽
public double height; // 高
public String color; // 颜色
//2、行为/方法(成员方法)
public void washClothes(){
System.out.println("洗衣功能");
}
public void dryClothes(){
System.out.println("甩干功能");
}
public void setTime(){
System.out.println("定时功能");
}
}
注意:
(1)在Java中,定义类需要用到关键字class;
(2)类名采用大驼峰定义;
(3)一个类由成员变量和成员方法组成,但不一定是二者都有;
(4)成员前的public规定了变量的权限,后面会详细解释;
(5)现在创建的类的方法中不带static关键字,后面会详细解释;
(6)建议一个java文件中写一个类。
2、类的实例化
定义了一个类,就相当于在计算机中定义了一种新类型,类似于int、short、double啊,用自定义的类类型创建对象的过程,就被称为类的实例化。
//定义一个狗类
class Dog{
public String name;
public int age;
public String color;
public void bark(){
System.out.println(name + "汪汪叫");
}
public void wag(){
System.out.println(name + "摇尾巴");
}
}
public class Test {
public static void main(String[] args) {
Dog dog1 = new Dog();//通过关键字:new实例化对象
Dog dog2 = new Dog();//一个类可以实例化多个对象
dog1.name = "炫炫";//使用.来访问对象中的成员变量
dog1.age = 5;
dog1.color = "白色";
dog1.wag(); //使用.来访问对象中的成员方法
dog1.bark();
dog2.name = "碗碗";
dog2.age = 6;
dog2.color = "黑色";
dog2.wag();
dog2.bark();
}
}
注意:
(1)实例化一个对象,需要使用new关键字;
(2)使用 . 来访问对象中的成员变量和方法;
(3)一个类可以创建多个实例;
(4)类创建的对象的成员如果没有初始化的话,会默认初始化为0,布尔类型默认为false,引用类型是null。
三、this引用
为什么要引入this引用呢?先看下面这段代码:
上面代码中创建了一个Date类,类中setDay方法中的形参名和Date类的成员变量名称相同,那么在运行这行代码时一定会出问题:
本该设置的2021年5月9日和2022年5月9日却都变成了0年0月0日?
因为形参中的变量是局部变量,当局部变量和成员变量名称一样时,局部变量优先,所以setDay方法改变的是局部变量的值,并没有改变成员变量的值,因此成员变量的值都默认为0。
为了规避这类问题,就需要引入this引用。
this引用指向当前对象(成员方法调用时指向该成员方法的对象),在成员方法中所有成员变量的操作,都是通过该引用去访问。
加上this引用之后,这段代码就可以正常运行了:
this引用的是调用成员方法的对象,比如date1调用setDay方法,那么this引用的就是date1的对象:
当我们进行调试的时候,可以发现date1和this的地址相同。
注意:
(1)this的类型:对应类类型引用,即哪个对象调用就是哪个对象的引用类型;
(2)this只能在成员方法中使用;
在其他位置写就会报错 ;
(3)在成员方法中,this只能引用当前对象,不能再引用其他对象;
(4)建议大家在成员方法中使用this,使用this一定没错,但不使用this可能出错。
四、对象的构造及初始化
刚才我们了解到两种初始化对象的方法,一种是通过.访问成员变量来初始化,一种是通过成员方法来初始化,但是每次创建对象都要这样初始化会比较麻烦,此时我们就需要引入构造方法。
1、构造方法
构造方法(又叫构造器)是一个特殊的成员方法,它的名称必须与类名相同,没有返回值(void也不需要),在创建对象时,由编译器自动调用,并且在整个对象的生命周期内只调用一次。
代码运行结果:
有了构造方法,我们在实例化对象时就可以进行传参初始化对象了。
注意:构造方法的作用是对对象的成员进行初始化,并不负责给对象开辟空间。
2、构造方法的特点
(1)构造方法的名字必须与类名相同;
(2)构造方法没有返回值,void也不行;
当我们把返回值设置为void时,这个构造方法就会被识别为一个和类名同名的成员方法,因此代码就会报错。
(3)构造方法在创建对象时由编译器自动调用,并且在对象的生命周期内只调用一次;
(4)构造方法可以重载;
(5)如果用户没有定义构造方法,那么编译器就会默认生成一个无参的构造方法(一旦用户定义,编译器就不再生成);
(6)在一个构造方法中,可以通过this来调用其他的构造方法(语法支持,但感觉没有必要);
注意:this()必须是构造方法中的第一条语句。
不能形成环:第一个构造方法调用第二个,第二个调用第三个,第三个又调用第一个...
7、构造方法一般都是用public修饰,特殊场景会被private修饰。
3、就地初始化
就是在创建成员变量时,直接给出了初始值。
但是我们一般不使用就地初始化,因为这样会使new的每一个对象的初始值都是一样的,更改起来不方便。