面向对象详解
# 1、面向过程与面向对象
- 面向过程
面向过程编程(Procedural Programming)是一种以过程为中心的编程范式,它将程序看作是一系列的操作步骤,通过顺序执行和调用函数来实现任务。面向过程编程主要关注数据和函数的组织和处理,它将问题分解为一系列的步骤,每个步骤通过特定的函数实现。在面向过程编程中,数据和函数是分离的,函数通过传递参数来操作数据。常用的面向过程编程语言包括C和Fortran等。
- 面向对象
面向对象编程(Object-Oriented Programming)是一种以对象为中心的编程范式,它将程序看作是一组相互协作的对象集合,通过定义对象和对象之间的关系来实现任务。面向对象编程主要关注对象和对象之间的交互和封装,它将问题分解为一组对象和对象之间的交互。每个对象都有自己的属性和方法,方法是对象的行为,属性是对象的状态。面向对象编程强调对象之间的继承、封装和多态等特性。常用的面向对象编程语言包括Java、C++和Python等。
- 洗衣服案例
- 面向过程:放入衣服 -> 启动洗衣机 -> 洗衣服 -> 关闭洗衣机
- 面向对象:放入衣服 -> 洗衣机:启动、洗衣服、关闭
面向过程更注重实现的步骤,而面向对象更注重交互。有学过C语言可能更容易理解。
- 面向对象的三大核心特性
- 可重用性:代码重复使用,减少代码量,提高开发效率。面向对象的三大基本特征(继承、封装和多态)都围绕这个核心。
- 可扩展性:指新的功能可以很容易地加入到系统中来,便于软件的修改。
- 客观理性:能够将功能与数据结合,方便管理。
# 2、抽象
抽象思想的核心是将问题进行抽象和模型化。就是把同一类事物中共有的特征(属性)和行为(功能、方法)进行抽取,归纳,总结。
抽象的过程其实就是面向对象编程的核心思想。
抽象过程案例
- 鸟、猪、猫、狗都是动物
- 它们都有吃、跑、叫等行为,它们都有姓名、年龄、颜色等属性。
- 可以将这些动物进行抽象和模型化,比如我定义了一个类Animal,它有属性name、age、color,有行为eat、run、cry。
- Animal为类,name、age、color为属性,eat、run、cry为方法。都可以表示为鸟、猪、猫、狗。
- 这样就实现了对同一类事物进行抽象和模型化。
看看具体实现
- Animal类实现
public class Animal {
private String name;
private int age;
private String color;
public Animal(String name, int age, String color) {
this.name = name;
this.age = age;
this.color = color;
}
public void eat() {
System.out.println(name + " is eating.");
}
public void run() {
System.out.println(name + " is running.");
}
public void cry() {
System.out.println(name + " is crying.");
}
// Getters and setters
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
- 测试类
public class Main {
public static void main(String[] args) {
Animal bird = new Animal("Bird", 1, "Yellow");
System.out.println(bird.getName()); // Output: Bird
bird.eat(); // Output: Bird is eating.
Animal pig = new Animal("Pig", 2, "Pink");
System.out.println(pig.getName()); // Output: Pig
pig.run(); // Output: Pig is running.
}
}
2
3
4
5
6
7
8
9
10
11
可以看到,Animal可以表示多种动物,只要创建了对象,就可以调用对应的方法。并且每个对象都有自己独有的属性,不会相互影响。这就是抽象的过程。
# 3、类
用来描述一类具有相同特征(属性)和相同行为(方法)的模板。
详细可以查看:类
# 4、对象
对象(Object)是系统中用来描述客观事物的一个实体,它是构成系统的一个基本单位。也就是类的实例,类是描述一类的抽象,对象是描述一个具体事物。比如Animal类,可以表示多种动物,而鸟对象,只能表示一种鸟。
# 4.1、成员变量
- 定义在方法的外部,类的内部。使用范围是整个类
- 不需要初始值
- 存储在堆内存中(对象存在时才在存在)
# 4.2、局部变量
- 定义在方法的内部或者某一个语句块的内部,适用范围仅限于方法内或者语句块内
- 必须有初始值
- 存储在栈内存中
# 4.3、成员方法
定义在类内部,方法前没有static关键字的方法
语法
访问修饰符 返回值类型 方法名称(参数列表){
方法体
}
2
3
# 4.4、构造方法
对象一建立就会调用构造方法,可以创建对象,给成员变量(属性)初始化。
- 方法名和类名相同
- 没有返回值和void,没有return
- 不能被static等关键字修饰
- 可以方法重载(定义多个参数列表不同的构造方法)
- 当一个类中没有写构造方法时,系统会默认给该类一个默认的无参构造方法。当自己定义构造方法后默认的构造方法就不存在了。
public class Animal {
String name;
int age;
//构造方法
public Animal(){
System.out.println("------无参的构造方法------");
name = "动物";
age = 0;
}
public Animal(String name,int age){
System.out.println("------有参的构造方法------");
this.name = name;
this.age = age;
}
public static void main(String[] args) {
//创建对象
Animal a1 = new Animal();
System.out.println(a1.name+","+a1.age);
Animal a2 = new Animal("兔子",2);
System.out.println(a2.name+","+a2.age);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 4.5、this关键字
this代表它所在方法所属对象的引用。哪个对象调用的this所在的方法,this就代表哪个对象。
# 5、封装
封装是面向对象编程的一个重要原则。它指的是将对象的内部状态(属性)隐藏起来,并通过公共方法来访问和修改这些状态。这样做的好处是可以控制对对象的访问,防止不合法的状态修改,并提供了一种更加可控的方式来与对象交互。
# 6、继承
继承是面向对象编程中的另一个关键概念。它允许你创建一个新类,该类可以继承另一个类的属性和方法。继承使得代码重用更容易,并允许你创建一个类层次结构,其中一个类(子类)继承另一个类(父类)的特征和行为。
public class BankAccount {
// 共同的属性
private String ownerName;
private String accountNumber;
private double balance;
// 共同的方法
public void deposit(double amount) {
balance += amount;
}
public void withdraw(double amount) {
if (amount <= balance) {
balance -= amount;
} else {
System.out.println("余额不足!");
}
}
public double getBalance() {
return balance
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
继承BankAccount
public class SavingsAccount extends BankAccount {
private double interestRate;
public SavingsAccount(String ownerName, String accountNumber, double initialBalance, double interestRate) {
// 调用父类构造方法初始化共同属性
super(ownerName, accountNumber, initialBalance);
this.interestRate = interestRate;
}
public void applyInterest() {
double interest = getBalance() * interestRate;
deposit(interest);
}
}
public class CheckingAccount extends BankAccount {
private double overdraftLimit;
public CheckingAccount(String ownerName, String accountNumber, double initialBalance, double overdraftLimit) {
// 调用父类构造方法初始化共同属性
super(ownerName, accountNumber, initialBalance);
this.overdraftLimit = overdraftLimit;
}
public void withdrawWithOverdraft(double amount) {
if (amount <= getBalance() + overdraftLimit) {
withdraw(amount);
} else {
System.out.println("超出透支额度!");
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# 7、多态
多态是面向对象编程的另一个重要概念。它允许不同类型的对象对相同的消息(方法调用)做出不同的响应。多态使得代码更灵活和可扩展,能够处理不同类型的对象,而无需知道其具体类型。
定义方法
public void printAccountInfo(BankAccount account) {
System.out.println("账户信息:");
System.out.println("账户持有者:" + account.getOwnerName());
System.out.println("账户号码:" + account.getAccountNumber());
System.out.println("当前余额:" + account.getBalance());
}
2
3
4
5
6
这个方法接受一个BankAccount对象作为参数,但实际上可以传递任何继承自BankAccount的对象,如储蓄账户或支票账户。这是多态的体现,同一个方法可以适用于不同类型的对象。
SavingsAccount savingsAccount = new SavingsAccount("Alice", "SA123", 1000.0, 0.03);
CheckingAccount checkingAccount = new CheckingAccount("Bob", "CA456", 500.0, 100.0);
printAccountInfo(savingsAccount); // 打印储蓄账户信息
printAccountInfo(checkingAccount); // 打印支票账户信息
2
3
4
5
在上面的示例中,我们分别传递了储蓄账户和支票账户对象给printAccountInfo方法,它能够正确地打印不同类型账户的信息。
Java中多态的体现,以下的一些都是多态的一个体现方式:
- 方法重写(Method Overriding):子类可以重写父类的方法,通过使用父类引用变量访问子类重写的方法。这样可以实现基于父类引用调用子类的具体实现。
- 接口的多态性:接口定义了一组方法的规范,类实现了接口后,可以通过接口引用变量来实现对这些类对象的多态引用。
- 抽象类的多态性:抽象类可以包含抽象方法,子类可以重写这些方法,实现多态。
多态是一个形式的多样性体现,简单案例就是接口,通过new接口实例,来调用实现类的方法。