Skip to content

Commit 0333203

Browse files
committed
update oop
1 parent 2a71b69 commit 0333203

File tree

11 files changed

+867
-49
lines changed

11 files changed

+867
-49
lines changed

oop/Polymorphic.java

Lines changed: 0 additions & 49 deletions
This file was deleted.

oop/README.md

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
# 面向对象概述
2+
3+
面向对象编程(Object-Oriented Programming,简称 OOP)是一种基于"对象"概念的编程范式。在面向对象编程中,程序由各种对象组成,每个对象都包含数据和方法。
4+
5+
# 面向对象编程的相关概念
6+
7+
## 对象(Object)
8+
9+
对象是类的一个实例,也是面向对象编程的基本单位。对象包含数据(称为属性)和行为(称为方法)
10+
11+
## 类(Class)
12+
13+
万物以类聚,通过分类可以将万事万物归纳起来。类可看作是创建对象的蓝图或模板,它定义了对象的数据属性和行为方法。
14+
15+
## 接口(Interface)
16+
17+
接口是一种抽象方法的集合,与类属于不同的概念。类描述对象的属性和方法,接口则定义类需要实现的方法。
18+
接口和抽象类有点像,都是一种抽象类型,但两者很大不同。抽象类是对一种事物整体的抽象,即对类抽象,包括属性、行为等,子类和抽象类是一种"is-a"的关系。而接口是对行为的抽象,是对类局部(行为)进行抽象,接口表示一种"can-do"的关系。
19+
抽象类作为子类的父类,它是一种模板式设计。接口是一种行为规范,它是一种辐射式设计。
20+
21+
## 封装(Encapsulation)
22+
23+
即隐藏对象的属性和实现细节,只对外公开必要的接口,控制属性的读写访问级别。封装有助于保持代码的模块化和减少代码复杂性。
24+
25+
## 继承(Inheritance)
26+
27+
即子类继承父类的特征和行为,使得子类对象(实例)具有父类的属性和方法。继承的类被称为子类,提供继承的类被称为父类或基类,通过继承可以实现代码复用。在面向对象编程中,只在必须的时候使用继承,其他时候尽量使用组合。
28+
29+
## 组合(Composition)
30+
31+
部分与整体的关系。将一个对象是另一个对象的属性,从而实现对象之间的关联。与继承不同,组合强调的是一种“has-a”(拥有)关系,而不是“is-a”(是)的关系。组合通常用于建立复杂对象的内部结构,使得对象的构成更加灵活,并有助于代码的模块化和重用。
32+
33+
## 聚合(Aggregation)
34+
35+
也是部分和整体的关系,一个对象(整体)包含或引用其他对象(部分),但这些部分对象在逻辑上可以独立于整体对象。与组合不同,聚合中的部分对象不一定是整体对象的严格组成部分,它们可以在整体对象销毁后继续存在。聚合关系松散,组合关系严密。
36+
37+
## 多态(Polymorphism)
38+
39+
即同一个行为具有多个不同表现形式或形态的能力。表现形式为,子类重写父类方法,实现类实现接口方法,子类重写抽象类方法等。多态三个必要条件:继承、重写、父类引用指向子类对象。多态有效消除类型之间的耦合,并提供灵活的可扩展方案。
40+
41+
## 抽象(Abstraction)
42+
43+
是一种简化复杂系统的方法,在更高层次上进行建模。在面向对象编程中,抽象意味着关注对象的模型架构而非具体实现。抽象包括两个方面,一是过程抽象,二是数据抽象。过程抽象,关注于目标的功能是什么,而不是功能是怎么实现的。数据抽象,关注数据的特性、用途和行为,而不是底层实现。
44+
45+
# 例子
46+
47+
```java
48+
/**
49+
* 体现了面向对象编程的以下概念:
50+
* 类和对象:Animal是基类,Dog和Cat是从Animal继承的子类。通过创建类的实例,可以生成不同的对象。
51+
* 继承:Dog和Cat继承了Animal类的属性和方法,同时也可以覆写父类的方法,实现自己特有的行为。
52+
* 多态:通过父类引用子类对象,代码可以在运行时根据对象的类型调用相应的覆写方法。这允许更灵活的代码复用和扩展。
53+
* 封装:类的属性被保护级别封装,确保只有子类和自身可以访问。这有助于保持对象的状态和行为的安全。
54+
*/
55+
// 定义一个Animal的基类
56+
class Animal {
57+
protected String name; // 封装,保护级别的属性,子类可以访问
58+
59+
public Animal(String name) {
60+
this.name = name; // 初始化动物的名字
61+
}
62+
63+
public void speak() {
64+
System.out.println(name + " makes a sound."); // 通用的说话方法
65+
}
66+
}
67+
68+
// 定义一个Dog的子类,继承自Animal
69+
class Dog extends Animal {
70+
public Dog(String name) {
71+
super(name); // 调用父类的构造方法
72+
}
73+
74+
@Override // 覆写父类的方法
75+
public void speak() {
76+
System.out.println(name + " barks."); // 狗特有的说话方式
77+
}
78+
}
79+
80+
// 定义一个猫的子类,继承自Animal
81+
class Cat extends Animal {
82+
public Cat(String name) {
83+
super(name); // 调用父类的构造方法
84+
}
85+
86+
@Override // 覆写父类的方法
87+
public void speak() {
88+
System.out.println(name + " meows."); // 猫特有的说话方式
89+
}
90+
}
91+
92+
// 演示多态和继承
93+
public class Test {
94+
public static void main(String[] args) {
95+
// 创建一个动物的对象
96+
Animal genericAnimal = new Animal("Generic Animal");
97+
genericAnimal.speak(); // 输出:Generic Animal makes a sound.
98+
99+
// 创建一个狗的对象
100+
Dog dog = new Dog("Buddy");
101+
dog.speak(); // 输出:Buddy barks.
102+
103+
// 创建一个猫的对象
104+
Cat cat = new Cat("Whiskers");
105+
cat.speak(); // 输出:Whiskers meows.
106+
107+
// 演示多态
108+
Animal polymorphicAnimal;
109+
// 父类声明子类Dog
110+
polymorphicAnimal = new Dog("Rover");
111+
polymorphicAnimal.speak(); // 输出:Rover barks.
112+
113+
// 对象改为Cat
114+
polymorphicAnimal = new Cat("Fluffy");
115+
polymorphicAnimal.speak(); // 输出:Fluffy meows.
116+
}
117+
}
118+
```
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/*
2+
抽象是一种简化复杂系统的方法,在更高层次上进行建模。抽象包括两个方面,一是过程抽象,二是数据抽象。
3+
抽象类:Shape是一个抽象类,它包含一个抽象方法calculateArea()。抽象类通过abstract关键字进行声明,不能被实例化。
4+
抽象类(Abstract Class)和接口(Interface)是不同的机制,用于实现多态性和代码组织。两者都可以用于定义抽象方法,但又有区别。
5+
抽象类用于表示一种"is-a"关系,而接口用于表示一种"can-do"关系。
6+
本示例:
7+
- 抽象方法:calculateArea()是一个抽象方法,它没有具体的实现。子类必须实现这个方法,否则它们也必须声明为抽象类。
8+
- 子类实现:Circle和Rectangle是Shape的具体子类,它们分别实现了calculateArea()方法。在这些子类中,我们提供了具体的面积计算逻辑。
9+
- 多态性:通过抽象类和多态性,我们可以使用相同的接口来处理不同的子类对象。在测试中,创建了圆形和矩形对象,并分别计算了它们的面积,而不需要关心它们的具体类型。
10+
*/
11+
12+
// 抽象类:形状
13+
// 这里计算面积使用抽象类,如果是移动、缩放等行为,则可以采用接口
14+
abstract class Shape {
15+
// 抽象方法:计算形状的面积。由子类具体实现
16+
public abstract double calculateArea();
17+
}
18+
19+
// 子类:圆形
20+
class Circle extends Shape {
21+
private double radius; // 圆的半径
22+
23+
// 构造方法
24+
public Circle(double radius) {
25+
this.radius = radius;
26+
}
27+
28+
// 实现抽象方法:计算圆的面积
29+
@Override
30+
public double calculateArea() {
31+
return Math.PI * radius * radius;
32+
}
33+
}
34+
35+
// 子类:矩形
36+
class Rectangle extends Shape {
37+
private double width; // 矩形的宽度
38+
private double height; // 矩形的高度
39+
40+
// 构造方法
41+
public Rectangle(double width, double height) {
42+
this.width = width;
43+
this.height = height;
44+
}
45+
46+
// 实现抽象方法:计算矩形的面积
47+
@Override
48+
public double calculateArea() {
49+
return width * height;
50+
}
51+
}
52+
53+
// 子类:三角形
54+
class Triangle extends Shape {
55+
private double base; // 三角形的底边长
56+
private double height; // 三角形的高
57+
58+
// 构造方法
59+
public Triangle(double base, double height) {
60+
this.base = base;
61+
this.height = height;
62+
}
63+
64+
// 实现抽象方法:计算三角形的面积
65+
@Override
66+
public double calculateArea() {
67+
return 0.5 * base * height;
68+
}
69+
}
70+
71+
// 测试验证
72+
public class AbstractionExample {
73+
public static void main(String[] args) {
74+
// 创建圆形对象并计算面积
75+
Circle circle = new Circle(5);
76+
double circleArea = circle.calculateArea();
77+
System.out.println("圆形面积: " + circleArea); // 输出:Circle Area: 78.53981633974483
78+
79+
// 创建矩形对象并计算面积
80+
Rectangle rectangle = new Rectangle(4, 6);
81+
double rectangleArea = rectangle.calculateArea();
82+
System.out.println("矩形面积: " + rectangleArea); // 输出:Rectangle Area: 24.0
83+
84+
// 创建三角形对象并计算面积
85+
Triangle triangle = new Triangle(3, 4);
86+
double triangleArea = triangle.calculateArea();
87+
System.out.println("三角形面积: " + triangleArea); // 输出:Triangle Area: 6.0
88+
}
89+
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*
2+
聚合是一个对象(整体)包含或引用其他对象(部分),但这些部分对象在逻辑上可以独立于整体对象。
3+
本示例:
4+
- 聚合关系:Department类聚合了Employee。Department类包含一个Employee列表,但这些员工的生命周期不依赖于部门。如果部门被销毁,员工对象仍然可以继续存在。这种关系是典型的聚合关系。
5+
- 松散耦合:聚合允许整体和部分对象之间具有较低的耦合度,这使得系统更易于维护和扩展。部分对象可以独立存在,整体对象只是引用它们。
6+
- 部分-整体关系:部门包含员工,但员工可以属于多个部门,也可以独立存在。这种关系使得代码更加灵活,并允许部分对象在整体对象之外被重用。
7+
*/
8+
9+
import java.util.ArrayList;
10+
import java.util.List;
11+
12+
// 定义一个员工类
13+
class Employee {
14+
private String name;
15+
16+
public Employee(String name) {
17+
this.name = name; // 初始化员工名字
18+
}
19+
20+
public String getName() {
21+
return name; // 获取员工名字
22+
}
23+
}
24+
25+
// 定义一个部门类
26+
class Department {
27+
private String departmentName; // 部门名称
28+
private List<Employee> employees; // 部门包含的员工列表
29+
30+
public Department(String departmentName) {
31+
this.departmentName = departmentName; // 初始化部门名称
32+
this.employees = new ArrayList<>(); // 初始化员工列表
33+
}
34+
35+
// 添加员工到部门
36+
public void addEmployee(Employee employee) {
37+
employees.add(employee); // 将员工添加到列表
38+
}
39+
40+
// 获取部门的所有员工名字
41+
public void listEmployees() {
42+
System.out.println("Employees in " + departmentName + ":");
43+
for (Employee employee : employees) {
44+
System.out.println(employee.getName()); // 输出员工名字
45+
}
46+
}
47+
}
48+
49+
// 测试验证
50+
public class AggregationExample {
51+
public static void main(String[] args) {
52+
// 创建几个员工对象
53+
Employee tom = new Employee("Tom");
54+
Employee jerry = new Employee("Jerry");
55+
56+
// 创建一个部门,并将员工添加到部门
57+
Department itDepartment = new Department("IT Resources");
58+
itDepartment.addEmployee(tom);
59+
itDepartment.addEmployee(jerry);
60+
61+
// 列出部门中的员工
62+
itDepartment.listEmployees(); // 输出:Employees in IT Resources: Tom, Jerry
63+
64+
// 即使部门被销毁,员工对象仍然可以继续存在
65+
itDepartment = null; // 删除部门对象
66+
67+
System.out.println("Employee Tom still exists: " + tom.getName()); // 输出:Tom
68+
}
69+
}

0 commit comments

Comments
 (0)