|
1 | 1 | # Python中的类详解 |
| 2 | +## python的类与面向对象: |
| 3 | + |
| 4 | +### 面向对象编程(OOP) |
| 5 | +程序 = 指令 + 数据 |
| 6 | + 代码可以选择以指令为核心或以数据为核心进行编写; |
| 7 | +两种泛型: |
| 8 | + 以指令为中心:围绕"正在发生什么"进行编写; |
| 9 | + 面向过程编程:程序具有一系列线性步骤;主体思想是代码作用于数据; |
| 10 | + 以数据为核心:围绕"将影响谁"进行编写; |
| 11 | + 面向对象编程(OOP):围绕数据及为数据严格定义的接口来组织程序,用数据控制对代码的访问; |
| 12 | +### 面向对象编程的核心概念: |
| 13 | +所有编程语言的最终目的都是提供一种抽象方法: |
| 14 | +在机器模型("解空间"或"方案空间")与实际解决的问题模型("问题空间")之间,程序员必须建立一种联系; |
| 15 | + 面向过程: 程序 = 算法 + 数据结构; |
| 16 | + 面向对象: 将问题空间中的元素以及它们在解空间中的表示物抽象为对象,并允许通过问题来描述问题而不是方案。 |
| 17 | + 可以把实例想象成一种新型变量,它保存着数据,但可以对自身的数据执行操作。 |
| 18 | +```python |
| 19 | +In [1]: l1 = [1,2,3] # 实例不仅包含数据本身,还包含能对数据施加的操作; |
| 20 | + |
| 21 | +In [2]: l1.pop() |
| 22 | +Out[2]: 3 |
| 23 | + |
| 24 | +In [3]: print(l1) |
| 25 | +[1, 2] |
| 26 | +``` |
| 27 | + |
| 28 | +类型由状态集合(数据)和转换这些状态的操作集合组成; |
| 29 | +类抽象: |
| 30 | + 类:定义了被多个同一类型对象共享的结构和行为(数据和代码) |
| 31 | + 类的数据和代码:即类的成员 |
| 32 | + 数据:成员变量或实例变量; |
| 33 | + 成员方法:简称为方法,是操作数据的代码,用于定义如何使用成员变量;因此一个类的行为和接口是通过方法来定义的。 |
| 34 | + 方法和变量: |
| 35 | + 私有:内部使用; |
| 36 | + 公共:外部可见; |
| 37 | + |
| 38 | +类未被实例化时,是不能对其执行操作的; |
| 39 | + |
| 40 | +### 面向对象的程序设计方法: |
| 41 | +- 所有的东西都是对象; |
| 42 | +- 程序是一大堆对象的组合; |
| 43 | + 通过消息传递,各对象知道自己该做什么; |
| 44 | + 消息:即调用请求,它调用的是从属于目标对象的一个方法; |
| 45 | +- 每个对象都有自己的存储空间,并可容纳其它对象; |
| 46 | + 通过封装现有类,可以制作成新型类; |
| 47 | +- 每个对象都属于某一类型: |
| 48 | + 类型,也即类; |
| 49 | + 对象是类的实例; |
| 50 | + 类的一个重要特性为"能发什么样的消息给它" |
| 51 | +- 同一个类的所有对象都能接收相同的消息; |
| 52 | +```python |
| 53 | +In [5]: s1 = 'abcd' |
| 54 | + |
| 55 | +In [6]: s1.pop() # 因为实例化对象s1并不支持pop这样的消息(方法) |
| 56 | +--------------------------------------------------------------------------- |
| 57 | +AttributeError Traceback (most recent call last) |
| 58 | +<ipython-input-6-da63ff21a00b> in <module>() |
| 59 | +----> 1 s1.pop() |
| 60 | + |
| 61 | +AttributeError: 'str' object has no attribute 'pop' |
| 62 | +``` |
| 63 | + |
| 64 | +### 对象的接口: |
| 65 | +定义一个类后,可以根据需要实例化多个对象; |
| 66 | +如何利用对象完成真正有用的工作? |
| 67 | + 必须有一种方法能向对象发出请求,令其做一些事情; |
| 68 | + 每个对象仅能接受特定的需求; |
| 69 | + 能像对象发送的请求由其"接口"进行定义; |
| 70 | + 对象的"类型"或"类"则规定了它的接口形式; |
| 71 | + |
| 72 | +例如: |
| 73 | +``` |
| 74 | +类型名: Light |
| 75 | +接口: |
| 76 | + on() |
| 77 | + off() |
| 78 | + brighten() |
| 79 | + dim() |
| 80 | +``` |
| 81 | + |
| 82 | +类:将同一种物事的共同特性抽象出来的表现; |
| 83 | + 状态和转换这些状态的操作; |
| 84 | + 数据:(在类被实例化时传递给类) |
| 85 | + 变量:就是类属性 |
| 86 | + 方法: |
| 87 | + 函数;操作变量引用的数据的代码; |
| 88 | + |
| 89 | +绑定方法:只能通过实例来调用; |
| 90 | + |
| 91 | + |
| 92 | +### 类间关系: |
| 93 | +- 依赖("uses-a") |
| 94 | + 一个类的方法操作另一个类的对象; |
| 95 | +- 聚合("has-a") |
| 96 | + 类A的对象包含类B的对象; |
| 97 | +- 继承("is-a") |
| 98 | + 描述特殊与一般关系;只要能被父类接受的操作,子类一定能接受; |
| 99 | + |
| 100 | +### 面向对象编程的元组: |
| 101 | + |
| 102 | +面向对象的模型机制有3个原则:封装、继承及多态; |
| 103 | + |
| 104 | +#### 封装(Encapsulation) |
| 105 | + 隐藏实现方案细节; |
| 106 | + 将代码及其处理的数据绑定在一起的一种编程机制,用于保证程序和数据不受外部干扰且不会被误用; |
| 107 | + |
| 108 | +#### 继承(Inheritance) |
| 109 | + 一个对象获得另一个对象属性的过程;用于实现按曾分类的概念; |
| 110 | + 一个深度继承的子类继承了类层次中它的每个祖先的所有属性; |
| 111 | + 超类、基类、父类 |
| 112 | + 子类、派生类; |
| 113 | + |
| 114 | +#### 多态性(Polymorphism) |
| 115 | +允许一个接口被多个通用的类动作使用的特性,具体使用哪个动作与应用场合相关; |
| 116 | +"一个接口,多个方法" |
| 117 | + 用于为一组相关的动作设计一个通用的接口,以降低程序复杂性; |
| 118 | +```python |
| 119 | +In [7]: def plus(x,y): |
| 120 | + ...: print(x+y) |
| 121 | + ...: |
| 122 | + |
| 123 | +In [8]: plus(1,3) |
| 124 | +4 |
| 125 | + |
| 126 | +In [9]: plus('a','b') |
| 127 | +ab |
| 128 | + |
| 129 | +In [10]: plus([1,2,3],['a','b','c']) |
| 130 | +[1, 2, 3, 'a', 'b', 'c'] |
| 131 | +``` |
| 132 | + |
| 133 | +### python类和实例: |
| 134 | +类是一种数据结构,可用于创建实例; |
| 135 | + 一般情况下,类封装类数据和可用于该数据的方法; |
| 136 | +python类是一个可调用对象,即类对象; |
| 137 | +python2.2之后,类是一种自定义类型,而实例则是声明某个自定义类型的变量; |
| 138 | + |
| 139 | +实例初始化: |
| 140 | + 通过调用类来创建实例; |
| 141 | + instance = ClassName(args...) |
| 142 | + 类在实例化时可以使用__init__ 和 __del__两个特殊的方法; |
| 143 | + |
| 144 | +class class_name 会在内存中生成一个class_name的对象,其后的语句在实例化时执行;类中的函数也是在调用实例的方法时执行; |
| 145 | + |
| 146 | +### Python中创建类: |
| 147 | +Python使用class关键字创建类,语法格式如下: |
| 148 | +class ClassName(bases): |
| 149 | + 'class document string' |
| 150 | + class_suite |
| 151 | + |
| 152 | +超类是一个或多个用于继承的父类的集合; |
| 153 | +类体可以包含:声明语句、类成员变定义、数据属性、方法 |
| 154 | + |
| 155 | +注意: |
| 156 | + 如果不存在继承关系,ClassName后面的"(bases)"可以不提供; |
| 157 | + 类文档为可选; |
| 158 | + |
| 159 | +class语句的一般形式: |
| 160 | +```python |
| 161 | +class ClassName(bases): |
| 162 | + data = value # 定义数据属性;类属性; |
| 163 | + def method(self,...): # 定义方法属性; |
| 164 | + self.member = value # 定义实例属性; |
| 165 | + |
| 166 | + # 类中的方法定义:第一个参数必须是self。 |
| 167 | +``` |
| 168 | + |
| 169 | +类名:所有单词的首字母大写; |
| 170 | + |
| 171 | +例子: |
| 172 | + 在python中,class语句类似def,是可执行代码;直到运行class语句后类才会存在: |
| 173 | + |
| 174 | + |
| 175 | +class语句内,任何赋值语句都会创建类属性; |
| 176 | +每个实例对象都会继承类的属性并会的自己的名称空间; |
| 177 | + |
| 178 | +```python |
| 179 | +In [1]: class FirstClass(): |
| 180 | + ...: data = 'hello class' |
| 181 | + ...: def printData(self): |
| 182 | + ...: print(self.data) |
| 183 | + ...: |
| 184 | + |
| 185 | +In [2]: ins1 = FirstClass() |
| 186 | + |
| 187 | +In [3]: ins1.data |
| 188 | +Out[3]: 'hello class' |
| 189 | + |
| 190 | +In [4]: ins1.printData() |
| 191 | +hello class |
| 192 | +``` |
| 193 | + |
| 194 | +```python |
| 195 | +In [5]: class SecClass(): |
| 196 | + ...: data = 'hello SecClass' |
| 197 | + ...: def printdata(self): |
| 198 | + ...: print("Content from method: %s" % self.data) |
| 199 | + ...: |
| 200 | + |
| 201 | +In [6]: ins2 = SecClass() |
| 202 | + |
| 203 | +In [7]: ins2.data |
| 204 | +Out[7]: 'hello SecClass' |
| 205 | + |
| 206 | +In [8]: ins2.printdata() |
| 207 | +Content from method: hello SecClass |
| 208 | + |
| 209 | +In [9]: ins3 = SecClass() |
| 210 | + |
| 211 | +In [10]: ins3.data |
| 212 | +Out[10]: 'hello SecClass' |
| 213 | + |
| 214 | +In [11]: ins3.printdata() |
| 215 | +Content from method: hello SecClass |
| 216 | +``` |
| 217 | + |
| 218 | +```python |
| 219 | +In [12]: class ThirdClass(): |
| 220 | + ...: data = 'hello ThirdClass' |
| 221 | + ...: def setdata(self,x): |
| 222 | + ...: self.str1 = x |
| 223 | + ...: def printdata(self): |
| 224 | + ...: print(self.str1) |
| 225 | + ...: |
| 226 | + |
| 227 | +In [13]: ins4 = ThirdClass() |
| 228 | + |
| 229 | +In [14]: ins4.data |
| 230 | +Out[14]: 'hello ThirdClass' |
| 231 | + |
| 232 | +In [15]: ins4.setdata('abcd') |
| 233 | + |
| 234 | +In [16]: ins4.printdata() |
| 235 | +abcd |
| 236 | + |
| 237 | +In [17]: ins5 = ThirdClass() |
| 238 | + |
| 239 | +In [18]: ins5.data # 类属性是供所有实例所共享的; |
| 240 | +Out[18]: 'hello ThirdClass' |
| 241 | + |
| 242 | +In [19]: ins5.setdata('xyz') |
| 243 | + |
| 244 | +In [20]: ins5.printdata() # 实例属性,是每个实例所私有的; |
| 245 | +xyz |
| 246 | + |
| 247 | +In [21]: ins4.printdata() |
| 248 | +abcd |
| 249 | +``` |
| 250 | + |
| 251 | +Python类方法及调用: |
| 252 | +实例(对象)通常包含属性; |
| 253 | + 可调用的属性:方法; |
| 254 | + object.method() |
| 255 | + 数据属性; |
| 256 | +在OOP中,实例就像是带有"数据"的记录,而类是处理这些记录的"程序" |
| 257 | + 通过实例调用方法相当于调用所属类的方法类处理当前实例; |
| 258 | + 类似instance.method(args...)会被自动转换为: |
| 259 | + class.method(instance,args...) |
| 260 | + 如前面的例子,x.display()会被自动转换为FirstClass.display(x),即调用类的方法来处理实例x; |
| 261 | + 因此,类中每个方法必须具有self参数,它隐含当前实例之意; |
| 262 | + 在方法内对self属性做赋值运算会产生每个实例自己的属性; |
| 263 | + python规定,没有实例,方法不允许被调用,此即为"绑定"。 |
| 264 | + |
| 265 | +### python类和实例的属性: |
| 266 | +class语句中的赋值语句会创建类属性,如前面例子中的spam; |
| 267 | +在类方法中对传给方法的特殊参数self进行赋值会创建实例属性; |
| 268 | +```python |
| 269 | +In [22]: class MyClass(): |
| 270 | + ...: gender = 'Male' |
| 271 | + ...: def setName(self,who): |
| 272 | + ...: self.name = who |
| 273 | +``` |
| 274 | + |
| 275 | + |
2 | 276 |
|
0 commit comments