文章目录
1 概述
类(Class)和对象(Object)是面向对象的核心概念
- 类是对一类事物的描述,是抽象的、概念上的定义
- 对象是实际存在的该类事物的每个个体,因而也称为实例(instance)。
- 可以理解为:类 = 抽象概念的人;对象 = 实实在在的某个人
1.1 面向过程和面向对象
- 面向过程
强调的是功能行为,以函数为最小单位 - 面向对象
将功能封装进对象,强调具备了功能的对象,以类/对象为最小单位,考虑谁来做。面向对象更加强调运用人类在日常的思维逻辑中采用的思想方法与原则,如抽象、分类、继承、聚合、多态等。 - 面向对象的三大特征
封装、继承、多态
1.2 类的成员
面向对象程序设计的重点是类的设计,而类的设计其实就是类的成员的设计。
常见的类的成员有:
- 属性:对应类中的成员变量
- 行为:对应类中的成员方法
1.3 内存分析
- 堆(Heap),此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存。这一点在Java虚拟机规范中的描述是:所有的对象实例以及数组都要在堆上分配。
- 通常所说的栈(Stack),是指虚拟机栈。虚拟机栈用于存储局部变量等。局部变量表存放了编译期可知长度的各种基本数据类型(boolean、byte、char 、 short 、 int 、 float 、 long 、double)、对象引用(reference类型,它不等同于对象本身,是对象在堆内存的首地址)。 方法执行完,自动释放。
- 方法区(Method Area),用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
以下代码内存分析如图所示:
1.4 属性
- 在方法体外,类体内声明的变量称为成员变量。成员变量是属于对象的,具有对象级别的生命周期和访问权限。
- 在方法体内部声明的变量称为局部变量。只在所在范围内可见,有着较短的生命周期。
1.5 方法
- 方法是类或对象行为特征的抽象,用来完成某个功能操作。在某些语言中也称为函数或过程。
- 将功能封装为方法的目的是,可以实现代码重用,简化代码
- Java里的方法不能独立存在,所有的方法必须定义在类里。
- 格式:
修饰符 返回值类型 方法名(参数类型 形参1, 参数类型 形参2, ….){
方法体程序代码
return 返回值;
}
1.5.1 方法的重载
- 在同一个类中,允许存在一个以上的同名方法,只要它们的参数个数或者参数类型不同即可。
- 特点:与返回值类型无关,只看参数列表,且参数列表必须不同。(参数个数或参数类型)。调用时,根据方法参数列表的不同来区别。
//返回两个整数的和
int add(int x,int y){return x+y;}
//返回三个整数的和
int add(int x,int y,int z){return x+y+z;}
//返回两个小数的和
double add(double x,double y){return x+y;}
1.5.2 可变参数
- 可变参数:方法参数部分指定类型的参数个数是可变多个:0个,1个或多个
- 可变个数形参的方法与同名的方法之间,彼此构成重载
- 可变参数方法的使用与方法参数部分使用数组是一致的
- 方法的参数部分有可变形参,需要放在形参声明的最后
- 在一个方法的形参位置,最多只能声明一个可变个数形参
格式:方法名(参数的类型名 …参数名)
public static void test(int a ,String… books);
1.5.2 参数传递
- 形参是基本数据类型:将实参基本数据类型变量的“数据值”传递给形参
- 形参是引用数据类型:将实参引用数据类型变量的“地址值”传递给形参
1.值传递
在方法调用时,传递的是变量的值,而不是变量本身。对于基本类型,传递的是变量的值。例如,如果你将一个int类型的变量作为参数传递给方法,实际上传递的是该变量的值。如果方法内部修改了参数的值,不会影响原始的变量。
2.引用传递
对于引用类型(如数组和对象),传递的是该对象在内存中的地址(引用),而不是对象本身。如果你将一个数组或对象作为参数传递给方法,实际上传递的是该数组或对象在内存中的引用的副本。如果方法内部修改了引用所指向的对象的内容,会影响原始的数组或对象。
1.5.3 递归方法
- 一个方法体内调用它自身。
- 方法递归包含了一种隐式的循环,它会重复执行某段代码,但这种重复执行无须循环控制。
- 递归一定要向已知方向递归,否则这种递归就变成了无穷递归,类似于死循环。
// 例:计算1-n之间所有自然数的和
public int getSum(int n) {// 3
if (n == 1) {
return 1;
} else {
return n + getSum(n - 1);
}
}
2 基础
2.1 封装
- 封装就是隐藏对象内部的复杂性,只对外公开简单的接口。便于外界调用,从而提高系统的可扩展性、可维护性。
public class Person {
// 封装私有属性
private String name;
private int age;
private String gender;
// 封装公有方法用于设置属性值
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public void setGender(String gender) {
this.gender = gender;
}
// 封装公有方法用于获取属性值
public String getName() {
return name;
}
public int getAge() {
return age;
}
public String getGender() {
return gender;
}
// 封装其他方法
public void introduce() {
System.out.println("My name is " + name + ". I am " + age + " years old. I am a " + gender + ".");
}
}
在这个例子中,我们创建了一个Person
类,并在类中封装了三个私有属性:name
、age
和gender
,以及对应的公有方法用于设置和获取这些属性的值。私有属性被封装起来,外部无法直接访问,只能通过公有的方法来访问和修改。
2.2 构造函数
用于在创建对象时进行初始化操作。
特点:
- 它具有与类相同的名称
- 它不声明返回值类型。(与声明为void不同)
- 不能被static、final、synchronized、abstract、native修饰,不能有return语句返回值
- 在创建对象时只会被调用一次
作用:
- 创建对象
- 给对象进行初始化
示例:
public class Person {
// 成员变量
private String name;
private int age;
// 构造函数(无参构造函数)
public Person() {
name = "kdx";
age = 0;
}
// 构造函数(带参数的构造函数)
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// Getter和Setter方法省略...
}
2.3 this关键字
this关键字是一个特殊的引用,用于表示当前对象的实例。它可以在类的方法中使用,用于引用当前正在调用方法的对象。this关键字的主要作用是消除歧义,帮助区分成员变量和局部变量或方法参数之间的命名冲突。
- 它在方法内部使用,即这个方法所属对象的引用
- 它在构造器内部使用,表示该构造器正在初始化的对象
示例:
public class Person {
// 成员变量
private String name;
private int age;
// 构造函数(带参数的构造函数)
public Person(String name, int age) {
this.name = name; // 使用this引用成员变量name
this.age = age; // 使用this引用成员变量age
}
// Getter和Setter方法省略...
// 方法1:打印当前对象的属性
public void printInfo() {
System.out.println("Name: " + this.name + ", Age: " + this.age);
}
// 方法2:返回当前对象的引用,支持链式调用
public Person setName(String name) {
this.name = name;
return this;
}
}
在上面的示例中,构造函数中使用this
关键字引用了成员变量name
和age
,以区分方法参数和成员变量之间的同名冲突。方法printInfo()
中也使用this
关键字引用了成员变量,用于打印当前对象的属性。而方法setName()
则返回了当前对象的引用this
,支持链式调用,方便连续对同一个对象的多个属性进行设置。