目录
第一阶段第一周
内容
第一天:类、对象、属性和方法的理论学习
阅读相关资料或教程,理解类是一种抽象的数据类型,它定义了对象的特征(属性)和行为(方法)。
了解对象是类的实例,是具有实际意义和值的实体。
学习属性是对象的特征,可以是各种数据类型,如整数、字符串、列表等。
深入理解方法是对象可以执行的操作,类似于函数,但与对象的属性相关联。
第二天 - 第三天:面向过程与面向对象编程对比
通过实际案例分析面向过程编程和面向对象编程的区别。例如,以计算一个班级学生的平均成绩为例:
- 在面向过程编程中,可能会使用函数来读取学生成绩数据、计算总和、计算平均数等步骤,数据和操作是分离的。
- 在面向对象编程中,可以创建一个 “学生班级” 类,其中有学生成绩列表作为属性,有计算总和、平均数的方法,数据和操作都封装在类中。
总结面向对象编程在代码组织、可维护性、可扩展性等方面的优势,如代码的模块化更好,便于复用和修改。
第四天 - 第五天:类、对象、属性和方法的详细理解
学习如何在代码中定义类的语法,包括类名的命名规范(通常采用大写字母开头的驼峰命名法)。
深入学习属性的定义方式,可以在类的内部通过变量来定义属性,也可以通过特殊的方法(如构造函数)来初始化属性。
详细学习方法的定义,包括方法的参数传递、返回值等,理解方法内部如何访问和操作属性。
第一天:类、对象、属性和方法的理论学习
1.类(Class)
定义
- 类是一种抽象的数据类型,它是对具有相同属性和行为的一组对象的抽象描述。可以把类看作是一个蓝图或者模板,用来创建具体的对象。例如,“汽车” 类就是对所有汽车的一个抽象,它包含了汽车共有的一些特性和行为。
作用
- 类提供了一种代码组织和复用的方式。通过定义类,可以将相关的数据(属性)和操作(方法)封装在一起,使得代码结构更加清晰。在大型项目中,不同的类可以分别负责不同的功能模块,方便开发人员进行分工协作和维护。
语法(以 Python 为例)
- 类的定义使用
class
关键字。例如,定义一个简单的Person
类:
class Person:
pass
- 这里
pass
表示暂时没有定义任何属性和方法,但这个类已经可以用来创建对象了。
2.对象(Object)
定义
- 对象是类的一个具体实例。它是根据类的定义创建出来的,具有类所描述的属性和方法。比如,“汽车” 类是抽象的,但一辆具体的 “宝马汽车” 就是 “汽车” 类的一个对象,它有自己的颜色、型号等属性,也可以执行启动、行驶等行为。
创建对象(以 Python 为例)
- 可以使用类名后面跟括号的方式来创建对象。对于上面定义的
Person
类,可以这样创建一个对象:
person1 = Person()
- 这里
person1
就是Person
类的一个对象。
3.属性(Attribute)
定义
- 属性是对象的特征或状态,用于描述对象的一些数据信息。属性可以是各种数据类型,如整数、字符串、列表等。在 “汽车” 类中,汽车的颜色、品牌、价格等都是属性。
分类
- 类属性:是属于类本身的属性,所有该类的对象共享这个属性。例如,“汽车” 类的 “轮子数量” 属性,一般情况下所有汽车的轮子数量是固定的(如 4 个),可以将其定义为类属性。
- 实例属性:是每个对象独有的属性,不同对象的实例属性可以有不同的值。例如,每辆汽车的颜色和品牌都可能不同,这些就是实例属性。
定义属性(以 Python 为例)
- 类属性:在类的内部,但不在任何方法内定义的变量就是类属性。例如:
class Car:
wheels = 4
- 这里
wheels
就是类属性。 - 实例属性:通常在类的构造方法(
__init__
方法)中定义。例如:
class Car:
def __init__(self, brand, color):
self.brand = brand
self.color = color
- 这里
brand
和color
就是实例属性,self
表示对象本身,通过self
来访问和定义实例属性。
4.方法(Method)
定义
- 方法是对象可以执行的操作或行为,它类似于函数,但与对象的属性紧密相关。在 “汽车” 类中,启动汽车、加速、刹车等行为都可以定义为方法。
语法(以 Python 为例)
- 方法的定义和函数类似,但它必须有一个参数
self
(在 Python 中),用于表示对象本身。例如:
class Car:
def start(self):
print("The car is starting.")
- 这里
start
方法用于启动汽车,通过self
可以在方法中访问和操作对象的属性。
调用方法(以 Python 为例)
- 可以通过对象来调用方法。例如,对于上面定义的
Car
类和start
方法:
my_car = Car()
my_car.start()
- 这样就调用了
my_car
对象的start
方法。
第二天 - 第三天:面向过程与面向对象编程对比
1.编程范式简介
-
面向过程编程(Procedural Programming)
- 是一种以过程(函数)为中心的编程范式。它将程序看作是一系列的步骤或操作,重点关注如何完成一个任务的具体过程。数据通常在函数之间传递,程序的执行顺序是按照函数的调用顺序来进行的。
-
面向对象编程(Object - Oriented Programming,OOP)
- 以对象为中心,将数据(属性)和操作数据的函数(方法)封装在一起形成对象。对象之间通过消息传递进行交互,程序的设计围绕对象的创建、使用和销毁展开。
2.代码结构对比
-
面向过程编程
- 代码通常按照功能模块划分成多个函数。例如,在一个简单的学生成绩管理程序中,可能会有以下函数:
read_scores()
:用于读取学生成绩数据,可能从文件或者用户输入获取数据。calculate_average(scores)
:接收成绩列表scores
作为参数,计算平均成绩。print_result(average)
:接收平均成绩average
作为参数,将结果打印输出。- 主程序部分会按照顺序调用这些函数来完成任务:
- 代码通常按照功能模块划分成多个函数。例如,在一个简单的学生成绩管理程序中,可能会有以下函数:
def read_scores():
# 假设从用户输入获取成绩数据
scores_str = input("请输入学生成绩,以空格分隔:")
scores = [int(i) for i in scores_str.split()]
return scores
def calculate_average(scores):
return sum(scores) / len(scores)
def print_result(average):
print("平均成绩是:", average)
scores = read_scores()
average = calculate_average(scores)
print_result(average)
- 可以看到,数据在函数之间传递,每个函数负责一个具体的操作步骤,程序的逻辑是通过函数的调用顺序体现的。
-
面向对象编程
- 首先会创建一个
StudentScores
类,将相关的数据和操作封装在类中:
- 首先会创建一个
class StudentScores:
def __init__(self):
self.scores_str = input("请输入学生成绩,以空格分隔:")
self.scores = [int(i) for i in self.scores_str.split()]
def calculate_average(self):
return sum(self.scores) / len(self.scores)
def print_result(self):
print("平均成绩是:", self.calculate_average())
- 然后在主程序中创建对象并调用对象的方法来完成任务:
student_scores = StudentScores()
student_scores.print_result()
- 在面向对象编程中,
StudentScores
类包含了数据(scores
和scores_str
)和操作这些数据的方法(calculate_average
和print_result
)。对象student_scores
是程序操作的核心,通过对象的方法来完成功能,数据和操作紧密结合在一起。
3.可维护性和可扩展性对比
-
面向过程编程
-
可维护性:
- 当程序规模较小、功能简单时,维护相对容易。但随着功能的增加和代码的膨胀,由于数据和操作分离,可能会导致函数之间的依赖关系复杂。例如,如果要修改成绩数据的存储格式,可能需要在多个读取和处理成绩数据的函数中进行修改。
-
可扩展性:
- 扩展性相对较差。如果要添加新的功能,如统计成绩的中位数,可能需要新增函数,并且要注意新函数与已有函数之间的调用关系和数据传递,容易影响到现有代码的稳定性。
-
-
面向对象编程
-
可维护性:
- 由于数据和操作封装在类中,只要类的接口(方法)不变,内部的实现细节可以修改而不影响其他部分的代码。例如,在
StudentScores
类中,如果要修改成绩数据的存储格式,只需要在类内部修改__init__
方法和相关的操作方法,外部使用这个类的代码基本不受影响。
- 由于数据和操作封装在类中,只要类的接口(方法)不变,内部的实现细节可以修改而不影响其他部分的代码。例如,在
-
可扩展性:
- 更容易扩展。如果要添加新的功能,比如添加成绩的标准差计算功能,可以在
StudentScores
类中添加新的方法,如calculate_standard_deviation
,这个新方法可以方便地访问和操作类内部的数据,对现有代码的影响较小。
- 更容易扩展。如果要添加新的功能,比如添加成绩的标准差计算功能,可以在
-
4.代码复用性对比
-
面向过程编程
- 函数可以被复用,但复用程度可能有限。例如,
calculate_average
函数在计算其他类型的数据平均值时可能需要修改参数类型和内部逻辑。而且,由于数据和操作分离,复用函数时可能需要重新考虑数据的来源和传递方式。
- 函数可以被复用,但复用程度可能有限。例如,
-
面向对象编程
- 类的复用性较强。一个设计良好的类可以在不同的项目或程序部分中被复用。例如,
StudentScores
类可以在不同的学生成绩管理场景中使用,只要成绩数据的处理逻辑相似。通过继承和多态等特性,还可以进一步增强代码的复用性,创建具有不同行为的子类来适应更多的需求。
- 类的复用性较强。一个设计良好的类可以在不同的项目或程序部分中被复用。例如,
第四天 - 第五天:类、对象、属性和方法的详细理解
1.类(Class)的深入理解
-
类的本质与作用
- 类是一种抽象的概念模型,它定义了对象的 “蓝图”。就像建筑蓝图一样,类规定了对象应该具有什么样的结构和行为。从软件工程的角度看,类是一种代码组织和封装的工具,它将相关的数据和操作组合在一起,使得代码更加模块化和易于理解。
-
类的层次结构与继承
- 类可以形成层次结构。通过继承,子类可以继承父类的属性和方法,并且可以添加自己特有的属性和方法或者重写父类的方法。例如,定义一个 “交通工具” 类作为父类,它有 “速度”“行驶” 等属性和方法。然后可以定义 “汽车” 类和 “自行车” 类作为子类,它们继承了 “交通工具” 类的基本属性和方法,同时 “汽车” 类可以添加 “引擎” 属性,“自行车” 类可以添加 “踏板” 属性等。
-
类的访问控制(以部分编程语言为例)
- 在一些编程语言(如 Java、C++)中有访问控制修饰符,用于控制类内部的成员(属性和方法)在外部的可见性。例如,在 Java 中,
private
修饰的成员只能在类内部访问,public
修饰的成员可以在任何地方访问,protected
修饰的成员可以在子类和同一包中的类访问。这种访问控制机制有助于保护类的内部数据和实现细节,提高代码的安全性和可维护性。
- 在一些编程语言(如 Java、C++)中有访问控制修饰符,用于控制类内部的成员(属性和方法)在外部的可见性。例如,在 Java 中,
2.对象(Object)的深入理解
-
对象的生命周期
- 对象的生命周期包括创建、使用和销毁三个阶段。在创建阶段,对象从类的定义中实例化出来,内存被分配给对象的属性。在使用阶段,对象的方法被调用,对象与其他对象或外部环境进行交互。在销毁阶段,对象占用的资源被释放。例如,在 Python 中,当一个对象的引用计数为 0 时(没有任何变量引用这个对象),对象会被垃圾回收机制销毁。
-
对象的标识与比较
- 每个对象在内存中有一个唯一的标识。在大多数编程语言中,可以通过某种方式获取对象的标识(如 Python 中的
id()
函数)。对象之间的比较有两种方式:一种是比较对象的标识(是否是同一个对象),另一种是比较对象的内容(如两个对象的属性值是否相同)。例如,在 Python 中,is
关键字用于比较对象的标识,==
运算符通常用于比较对象的内容。
- 每个对象在内存中有一个唯一的标识。在大多数编程语言中,可以通过某种方式获取对象的标识(如 Python 中的
-
对象之间的关系
- 对象之间可以存在多种关系。最常见的是关联关系,例如,一个 “学生” 对象和一个 “学校” 对象之间存在关联,因为学生在学校上学。还有聚合关系,比如一个 “班级” 对象是由多个 “学生” 对象组成的,班级对象可以管理和操作这些学生对象。组合关系是一种更强的聚合关系,部分对象不能脱离整体对象而单独存在,例如,一个 “汽车” 对象由发动机、车身等部件组成,这些部件对象在汽车对象销毁时也会随之销毁。
3.属性(Attribute)的深入理解
-
属性的类型与用途
- 属性可以分为基本数据类型(如整数、浮点数、布尔值等)和复杂数据类型(如数组、列表、对象等)。基本数据类型的属性用于存储简单的信息,如 “学生” 对象的年龄可以是一个整数属性。复杂数据类型的属性可以用于存储更复杂的信息,如 “班级” 对象的学生列表是一个复杂属性,它可以存储多个 “学生” 对象。
-
属性的初始化与更新
- 属性的初始化通常在对象创建时进行。在类的构造函数(如 Python 中的
__init__
方法)中,可以为属性赋初始值。属性的值可以在对象的生命周期内通过方法进行更新。例如,在一个 “银行账户” 对象中,账户余额属性可以在开户时初始化,然后通过存款和取款方法进行更新。
- 属性的初始化通常在对象创建时进行。在类的构造函数(如 Python 中的
-
属性的访问权限与封装
- 为了保护对象的内部数据,属性的访问权限可以被限制。在一些编程语言中,可以通过访问控制修饰符来实现。封装是一种将对象的属性隐藏在类内部,只通过公共方法来访问和修改属性的技术。这样可以防止外部代码直接访问和修改属性,从而提高代码的健壮性。例如,在一个 “员工” 对象中,工资属性可能是私有的,通过提供 “获取工资” 和 “设置工资” 的公共方法来间接访问和修改工资属性。
4.方法(Method)的深入理解
-
方法的参数传递与返回值
- 方法可以接受参数,这些参数用于向方法内部传递数据。参数的类型可以是基本数据类型或者对象。方法执行完后可以返回一个值,返回值的类型也可以是多种多样的。例如,在一个 “数学计算” 对象中,有一个 “加法” 方法,它接受两个整数参数,执行加法运算后返回结果。
-
方法的重载与重写(以部分编程语言为例)
- 方法重载是指在同一个类中定义多个同名方法,但参数列表不同(参数的数量、类型或顺序不同)。这样可以根据不同的参数情况执行不同的操作。方法重写是指在子类中重新定义父类中已经存在的方法,以改变方法的行为。例如,在 Java 中,子类可以重写父类的
toString
方法来提供自己特有的字符串表示形式。
- 方法重载是指在同一个类中定义多个同名方法,但参数列表不同(参数的数量、类型或顺序不同)。这样可以根据不同的参数情况执行不同的操作。方法重写是指在子类中重新定义父类中已经存在的方法,以改变方法的行为。例如,在 Java 中,子类可以重写父类的
-
方法与对象状态的改变
- 方法是改变对象状态的主要手段。通过调用方法,可以修改对象的属性值,从而改变对象的状态。例如,在一个 “游戏角色” 对象中,有一个 “移动” 方法,当调用这个方法时,角色的位置属性会被修改,从而改变了游戏角色的状态。