三大特征
封装
数据角度讲
- 定义:将一些基本数据类型复合成一个自定义类型。
- 优势:
- 将数据与对数据的操作相关联。
- 代码可读性更高(类是对象的模板)。
行为角度讲
- 定义:类外提供必要的功能,隐藏实现的细节(保护数据)。
- 优势:简化编程,使用者不必了解具体的实现细节,只需要调用对外提供的功能。
- 核心思想:私有化数据,提供两个读写方法。
- 私有成员:
- 作用:无需向类外提供的成员,可以通过私有化进行屏蔽。
- 做法:命名使用双下划线开头。
- 本质:障眼法,实际也可以访问。
- 私有成员的名称被修改为:
_类名__成员名
,可以通过__dict__
属性或dir
函数查看。
- 属性:
-
定义:
@property def 属性名(self): return self.__属性名 @属性名.setter def 属性名(self, value): self.__属性名= value
-
调用:
- 对象.属性名 = 数据
- 变量 = 对象.属性名
-
说明:通常两个公开的属性,保护一个私有的变量。
- @property 负责读取,@属性名.setter 负责写入
- 只写:属性名= property(None, 写入方法名)
设计角度讲
- 定义:
(1) 分而治之:将一个大的需求分解为许多类,每个类处理一个独立的功能。
(2) 变则疏之:变化的地方独立封装,避免影响其他类。
(3) 高 内 聚:类中各个方法都在完成一项任务(单一职责的类)。
(4) 低 耦 合 :类与类的关联性与依赖度要低(每个类独立),让一个类的改变,尽少影响其他类。 - 优势:便于分工,便于复用,可扩展性强。
继承
语法角度讲
继承方法
-
代码:
class 父类: def 父类方法(self): 方法体 class 子类(父类): def 子类方法(self): 方法体 儿子 = 子类() 儿子.子类方法() 儿子.父类方法()
-
说明:子类直接拥有父类的方法。
-
抽象:从许多个事物中,舍弃个性、非本质的属性,抽出共性、本质的过程。
内置函数
- isinstance(对象, 类型) :返回指定对象是否是某个类的对象。
- issubclass(类型,类型):返回指定类型是否属于某个类型。
继承数据
-
代码
class 子类(父类): def __init__(self,参数列表): super().__init__(参数列表) self.自身实例变量 = 参数
-
说明
(1) 子类如果没有构造函数,将自动执行父类的。
(2) 如果有构造函数将覆盖父类的。
(3) 必须通过super()
函数调用父类的构造函数,以确保父类实例变量被正常创建。
(4) 执行的是子类构造函数。 -
定义
(1) 重用现有类的功能,并在此基础上进行扩展。
(2) 说明:子类直接具有父类的成员(共性),还可以扩展新功能。 -
优点:一种代码复用的方式,隔离变化。
-
缺点:耦合度高,父类的变化,直接影响子类。
设计角度讲
- 定义:将相关类的共性进行抽象,统一概念,隔离变化。
- 适用性:多个类在概念上是一致的,且需要进行统一的处理。
相关概念
- 父类(基类、超类)、子类(派生类)。
- 父类相对于子类更抽象,范围更宽泛;子类相对于父类更具体,范围更狭小。
- 单继承:父类只有一个(例如 Java,C#)。
- 多继承:父类有多个(例如C++,Python)。
- Object类:任何类都直接或间接继承自 object 类。
C++--→python--|-→java--→C# 多继承 | 单继承
多继承
- 被多个变化所隔离,不是代码的复用。
- 一个子类继承两个或两个以上的基类,父类中的属性和方法同时被子类继承下来。
- 同名方法的解析顺序(MRO, Method Resolution Order):
类自身 --> 父类继承列表(由左至右)–> 再上层父类A / \ / \ B C \ / \ / D
多态
设计角度讲
- 定义:父类的同一种动作或者行为,在不同的子类上有不同的实现。
- 作用
(1) 在继承的基础上,体现类型的个性化(一个行为有不同的实现)。
(2) 增强程序扩展性,体现开闭原则。
语法角度讲
重写
- 子类实现了父类中相同的方法(方法名、参数)。
- 在调用该方法时,实际执行的是子类的方法。
内置可重写函数
Python中,以双下划线开头、双下划线结尾的是系统定义的成员。我们可以在自定义类中进行重写,从而改变其行为。
__str__
函数:将对象转换为字符串(对人友好的)__repr__
函数:将对象转换为字符串(解释器可识别的)
六大原则
开-闭原则(目标、总的指导思想)
Open Closed Principle
- 对扩展开放,对修改关闭。
- 增加新功能,不改变原有代码。
类的单一职责(一个类的定义)
Single Responsibility Principle
- 一个类有且只有一个改变它的原因。
依赖倒置(依赖抽象)
Dependency Inversion Principle
- 客户端代码(调用的类)尽量依赖(使用)抽象。
- 抽象不应该依赖细节,细节应该依赖抽象。
组合复用原则(复用的最佳实践)
Composite Reuse Principle
- 如果仅仅为了代码复用优先选择组合复用,而非继承复用。
- 组合的耦合性相对继承低。
里氏替换(继承后的重写,指导继承的设计)
Liskov Substitution Principle
- 父类出现的地方可以被子类替换,在替换后依然保持原功能。
- 子类要拥有父类的所有功能。
- 子类在重写父类方法时,尽量选择扩展重写,防止改变了功能。
迪米特法则(类与类交互的原则)
Law of Demeter
- 不要和陌生人说话。
- 类与类交互时,在满足功能要求的基础上,传递的数据量越少越好,因为这样可能降低耦合度。