1. 通过关键字class定义类:类名通常首字母大写,紧接(object),表示该类是从哪个类继承下来的,通常,如果没有合适的继承类,就使用object类,这是所有类最终都会继承的类。
2. 创建实例:class名字+() ; 定义__init__方法,类似构造函数。def__init__(self, name, score): self表示创建的实例本身,调用_init_ 函数时slef参数不需要传,python解释器自己会把实例变量穿进去。
3. 数据封装: 通过函数访问这些数据
4. 访问限制:变量名如果以两个下划线_开头,就变成了私有变量,只有内部可以访问。可以通过定义get或set函数来获取和修改变量。(以双下划线开头和结尾的变量是特殊变量可以直接访问的)
5. 继承和多态:跟c++类似.当子类和父类都存在相同的run()方法时,我们说,子类的run()覆盖了父类的run(),在代码运行的时候,总是会调用子类的run()。这样,我们就获得了继承的另一个好处:多态。在继承关系中,如果一个实例的数据类型是某个子类,那它的数据类型也可以被看做是父类。但是,反过来就不行。对于一个变量,我们只需要知道它是Animal类型,无需确切地知道它的子类型,就可以放心地调用run()方法,而具体调用的run()方法是作用在Animal、Dog、Cat还是Tortoise对象上,由运行时该对象的确切类型决定,这就是多态真正的威力:调用方只管调用,不管细节,而当我们新增一种Animal的子类时,只要确保run()方法编写正确,不用管原来的代码是如何调用的。这就是著名的“开闭”原则:
对扩展开放:允许新增Animal子类;
对修改封闭:不需要修改依赖Animal类型的run_twice()等函数。
6. 静态语言VS动态语言:对于静态语言(例如Java)来说,如果需要传入Animal类型,则传入的对象必须是Animal类型或者它的子类,否则,将无法调用run()方法。对于Python这样的动态语言来说,则不一定需要传入Animal类型。我们只需要保证传入的对象有一个run()方法就可以了。这就是动态语言的“鸭子类型”,它并不要求严格的继承体系,一个对象只要“看起来像鸭子,走起路来像鸭子”,那它就可以被看做是鸭子。
7. 获取对象信息:
1) type(): 判断对象类型;变量指向函数或者类;
2) isinstance(): 判断有继承关系的class类型(优先使用isinstance()判断类型)
3) dir(): 获得对象的所有属性和方法,返回一个包含字符串的list
8. 实例属性和类属性:实例属性类似构造函数。由于Python是动态语言,根据类创建的实例可以任意绑定属性。给实例绑定属性的方法是通过实例变量,或者通过self变量。千万不要对实例属性和类属性使用相同的名字,因为相同名称的实例属性将屏蔽掉类属性