1. 面向对象的初步认知
1.1 什么是面向对象
面向对象编程(OOP)是一种程序设计范式,它将程序中的数据和操作数据的方法封装到对象中。在面向对象的世界里,一切都被视为对象,这些对象可以拥有数据(成员变量)和行为(方法)。Java 是一门纯粹的面向对象编程语言,几乎所有的代码都是以类和对象的形式存在的。
1.2 面向对象与面向过程
在面向对象编程的思想中,解决问题主要依靠对象之间的交互完成一项任务。
相较之下,面向过程编程更侧重于一系列步骤或操作,通过过程调用来完成任务。
面向对象的优势在于更好地组织和抽象复杂系统,使代码更易扩展、维护和理解。
设计一个简单的图形计算程序,计算不同形状的面积。样设计:
面向过程:
double calculateCircleArea(double radius) { return 3.14 * radius * radius; } double calculateRectangleArea(double length, double width) { return length * width; } void main() { double circleArea = calculateCircleArea(5.0); double rectangleArea = calculateRectangleArea(4.0, 6.0); // 进行其他操作... } ```
定义了两个函数分别用于计算圆和矩形的面积。
在 `main` 函数中调用这些函数来进行计算。
面向对象:
class Circle { double radius; Circle(double radius) { this.radius = radius; } double calculateArea() { return 3.14 * radius * radius; } } class Rectangle { double length; double width; Rectangle(double length, double width) { this.length = length; this.width = width; } double calculateArea() { return length * width; } } void main() { Circle circle = new Circle(5.0); Rectangle rectangle = new Rectangle(4.0, 6.0); double circleArea = circle.calculateArea(); double rectangleArea = rectangle.calculateArea(); // 进行其他操作... }
定义了两个类 `Circle` 和 `Rectangle`,每个类都有自己的属性和方法。
通过创建对象,调用对象的方法来进行计算。这种方式更加面向对象,将数据和相关操作封装在对象内部。
面向对象的设计使得代码更易扩展和维护,特别是在处理复杂系统时表现出更大的优势。
2. 类定义和使用
向对象程序设计(Object-Oriented Programming,OOP)关注的是对象,而对象通常是现实生活中的实体或概念的抽象。在面向对象的思想中,问题的解决主要通过对现实世界中的事物进行建模,将其抽象为程序中的对象。
2.1 简单认识类
类是用来对一个实体(对象)来进行描述的,主要描述该实体(对象)具有哪些属性(外观尺寸等),哪些功能(用来干嘛)
2.2 类的定义格式
在 Java 中,定义一个类需要使用 class
关键字,具体的语法如下所示:
// 创建类
class ClassName {
// 字段(属性)或者成员变量
type fieldName;
// 行为或者成员方法
returnType methodName(parameters) {
// 方法体
}
// 其他字段和方法...
}
2.3 定义一个狗类
class Dogg { int age; String color; String name; public void bark() { System.out.println(name+"汪汪汪"); } public void wag() { System.out.println(name+"摇尾巴"); } }
通过对象的引用.访问属性进行赋值
实例化对象
public static void main(String[] args) { Dogg dog1 = new Dogg(); dog1.age = 9; dog1.name = "小白"; dog1.color = "黑色"; System.out.println(dog1.name); dog1.bark(); dog1.wag(); }
只要new 就会产生 新的对象, 只要是新的对象, 就是有新的内存
Dogg dog2 = new Dogg();
只需要通过对象的引用 去访问对象的成员变量即可或者是成员方法
可以通过new关键字 实例化多个对象
同一个类可以创建多个实例
dog1, dog都属于引用类型(存储的是对象的地址)
这里在啰嗦一下java中的数据类型
分为两种
- 基本数据类型(共八种)
- 引用类型 String 数组 类 接口
这里我提出两个问题
其一是: 引用可以指向 引用吗?
dog1 = dog2;
dog2这个引用指向了 dog1?
类似于
int[] arr1 = {1,2,3}; int[] arr2; arr2 = arr1;
类似于复制粘贴
因此这句话有语病错误 引用是不能指向对象的 引用只能指向对象
这两个引用同时指向的是一个对象
dog1
和dog2
都指向相同的对象这是因为引用存储的是对象的地址,所以它们都引用了相同的对象。
另一个问题是 一个引用可不可以指向多个对象?
不可以 一个引用只能指向一个对象
只能存储一个对象的地址
还有一个问题是以下代码能否代表dog2这个引用指向null对象?
Dogg dog2 = null;
dog2这个引用 不执行任何对象
3. 类的实例化
3.1 什么是实例化
实例化是将一个类作为模板,创建该类的具体对象的过程。通过实例化,我们可以在内存中分配空间,并初始化该对象的属性。实例化的结果就是我们所说的对象或实例。
3.2 类和对象的说明
类是一个模型: 类是对一个实体进行描述的模型,它定义了这个实体的属性(成员变量)和行为(方法)。类就像是一个蓝图或设计图,规定了实体应该有哪些特征和功能。
类是一种自定义类型: 类是用户自定义的数据类型,可以用来定义变量。通过类,我们可以创建属于该类型的对象。
多个对象的实例化: 一个类可以实例化出多个对象。每个对象都是该类的一个实例,拥有相同的属性和方法,但是它们是相互独立的。例如:
// 定义一个Person类 public class Person { String name; int age; } // 实例化两个Person对象 Person person1 = new Person(); Person person2 = new Person();
这里,person1和person2都是Person类的实例,但它们是两个独立的对象。
类和对象的比喻: 比方说,可以将类比为建筑设计图,它规定了房子应该有哪些特征和结构,但并不是实际的房子。只有当我们使用设计图实例化出具体的房子对象时,才会占用实际的物理空间,存储房子的具体信息。
class MyValue { int value; } public class Main4 { public static void swap(MyValue v1, MyValue v2) { int tmp = v1.value; v1.value = v2.value; v2.value = tmp; } public static void main(String[] args) { MyValue value1 = new MyValue(); MyValue value2 = new MyValue(); value1.value = 10; value2.value = 20; swap(value1, value2); System.out.println(value1.value); System.out.println(value2.value); } }
基本类型是无法完成交换的, 只有引用类型才能完成交换
4. this引用
4.1 为什么要有this引用:
在Java中,
this
是一个关键字,表示当前对象的引用。它主要用于解决类成员变量与方法参数之间的命名冲突。形参名与成员变量名相同,这时可以使用this
引用来明确指定操作的是成员变量而不是方法参数。
public class Date { public int year; public int month; public int date; public void setDate(int y, int m, int d){ year = y; month = m; date = d; } public void printDate() { System.out.println(year+"年"+month+"月"+date+"日"); } public static void main(String[] args) { Date date1 = new Date(); date1.setDate(2021, 12,21); date1.printDate(); } }
这里代码正常执行输出结果
2021年12月21日 Process finished with exit code 0
那我们把
public void setDate(int y, int m, int d){ year = y; month = m; date = d; }
改为
public void setDate(int year, int month, int date){ year = year; month = month; date = date; }
这时的输出
0年0月0日
因为这里的year month date都是局部变量, 形参名与成员变量名相同
这时可以使用
this
引用来明确指定操作的是成员变量public void setDate(int year, int month, int date){ this.year = year; this.month = month; this.date = date; }
改为以上代码就可以正常运行了
Date date1 = new Date(); date1.setDate(2021, 12,21); date1.printDate(); Date date2 = new Date(); date2.setDate(1234,1,23);
那怎么区分this是哪个呢
局部变量优先使用 谁调用这个方法 谁就是this
this
关键字主要用于引用当前对象的实例。当存在局部变量与实例变量同名时,使用
this
关键字可以明确指定操作的是实例变量而不是局部变量。当调用
date1.setDate(2021, 12, 21);
时,this
指向的是date1
对象的实例。而在
date2.setDate(1234, 1, 23);
中,this
指向的是date2
对象的实例。this指的是调用它的方法所属的对象。
4.2 什么是this引用
区分实例变量和局部变量: 当方法的参数名和实例变量名相同时,使用
this
关键字可以明确指定操作的是实例变量。例如,在setDay
方法中,this.year
表示实例变量,而year
表示方法的参数。在构造函数中调用其他构造函数: 在一个类的构造函数中,可以使用
this
来调用同一类的其他构造函数。public class Example { private int x; private int y; // 构造函数1 public Example(int x) { this.x = x; this.y = 0; } // 构造函数2,调用构造函数1 public Example(int x, int y) { this(x); // 调用构造函数1 this.y = y; } }
作为返回当前对象的引用: 在方法中可以使用
this
作为返回当前对象的引用,以支持方法的链式调用。public class Example { private int x; private int y; public Example setX(int x) { this.x = x; return this; } public Example setY(int y) { this.y = y; return this; } }
4.3 this引用的特性:
this的类型: this引用的类型是对应类类型的引用。即,this指向的是哪个对象调用,就是哪个对象的引用类型。
this只能在成员方法中使用: this关键字只能在类的成员方法中使用。它不能在静态方法(用
static
修饰的方法)中使用,因为静态方法与任何实例对象无关。this只能引用当前对象: 在成员方法中,this关键字只能引用当前对象,不能引用其他对象。它代表调用该成员方法的当前对象。
this是“成员方法”第一个隐藏的参数: 在成员方法中,this被视为第一个隐藏的参数。编译器会自动传递this作为参数给成员方法。当成员方法被调用时,编译器会负责将调用成员方法的对象的引用传递给该成员方法,而this负责接收这个引用。
5. 对象的构造及初始化
5.1 如何初始化对象
在Java方法内部定义一个局部变量时,必须要初始化,否则会编译失败。
要让上述代码通过编译,非常简单,只需在正式使用a之前,给a设置一个初始值即可。如果是对象:
需要调用之前写的SetDate方法才可以将具体的日期设置到对象中。通过上述例子发现两个问题:
1. 每次对象创建好后调用SetDate方法设置具体日期,比较麻烦,那对象该如何初始化?
2. 局部变量必须要初始化才能使用,为什么字段声明之后没有给值依然可以使用?