1. 面向对象编程(OOP,Object-Oriented Programming)
所谓的面向对象编程,想要学好它,唯一的捷径就是像造物者一样去思考问题。
因为,面向对象最初的灵感就是来源于真实世界:
对象 = 属性(对象的静态特征)+ 方法(所能做的事情)
2.类和对象
对象诞生之前,需要先创建一个类,再通过类来创造实际的对象。
创建一个类需要用到 class 关键字:
class Turtle:
head = 1
eyes = 2
legs = 4
shell = True
def crawl(self):
print("人们总抱怨我动作慢吞吞的,殊不知如不积硅步,无以至千里的道理。")
def run(self):
print("虽然我行动很慢,但如果遇到危险,还是会夺命狂奔的T_T")
def bite(self):
print("人善被人欺,龟善被人骑,我可是会咬人的!")
def eat(self):
print("谁知盘中餐粒粒皆辛苦,吃得好,不如吃得饱~")
def sleep(self):
print("Zzzz...")
类名的命名方式有一个约定俗成的标准,那就是使用大写字母开头,比如我们这里的 Turtle。
其实所谓的属性,就是写在类里面的变量,方法就是写在类里面的函数(实际上会有一点区别,后面我们会有仔细讲解)。
使用类名搭配上一对小括号,就像调用函数那样,就可以生成一个基于这个类的对象。
t1 就是一个 Turtle 类的对象,也叫实例对象(instance object),它就拥有了这个类所定义的属性和方法:
>>> t1 = Turtle()
>>> t1.head
1
>>> t1.legs
4
>>> t1.crawl()
人们总抱怨我动作慢吞吞的,殊不知如不积硅步,无以至千里的道理。
>>> t1.bite()
人善被人欺,龟善被人骑,我可是会咬人的!
>>> t1.sleep()
Zzzz...
>>> t2 = Turtle()
>>> t2.head
1
>>> t2.legs
4
>>> t2.crawl()
人们总抱怨我动作慢吞吞的,殊不知如不积硅步,无以至千里的道理。
>>> t2.bite()
人善被人欺,龟善被人骑,我可是会咬人的!
当对象创建出来之后,我们可以随意修改它的属性值:
>>> t2.legs = 3
>>> t2.legs
3
>>> t1.legs
4
我们也可以动态的创建一个属性,这跟在字典中添加一个新的键值对一样:
>>> t1.mouth = 1
>>> t1.mouth
1
使用 dir() 函数,可以看到,t1 比 t2 多出了一个 mouth 的属性:
>>> dir(t1)
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'bite', 'crawl', 'eat', 'eyes', 'head', 'legs', 'mouth', 'run', 'shell', 'sleep']
>>> dir(t2)
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'bite', 'crawl', 'eat', 'eyes', 'head', 'legs', 'run', 'shell', 'sleep']
3.封装
封装,是面向对象编程的三个基本特征之一,另外两个是继承和多态,我们在后续的课程会给大家讲解。
像前面我们定义的 Turtle 类,它就把一个甲鱼的特征属性和行为能力封装到了一起。
当然,只要有时间,我们还可以添加更多的细节,使得这个 Turtle 更像一只真正意义上的甲鱼。
4. self 是什么?
我们编写一段代码,把 self 给打印出来:
>>> class C:
... def get_self(self):
... print(self)
...
>>> c = C()
>>> c.get_self()
<__main__.C object at 0x0000020C981BF0D0>
这是什么?
这就是类 [backcolor=#eee]C[/backcolor] 的实例对象小 [backcolor=#eee]c[/backcolor]:
>>> c
<__main__.C object at 0x0000020C981BF0D0>
原来传递给方法的是对象本身,那为什么要这么做呢?
我们知道,同一个类可以生成无数多个对象,那么当我们在调用类里面的一个方法的时候,Python 如何知道到底是哪个对象在调用呢?
没错,就是通过这个 self 参数传递的信息。
所以,类中的每一个方法,默认的第一个参数都是 self。