面向对象编程的一个重要特点就是数据封装,比如在上面例子中,Dog类的每个实例都有weight和color,我们可以直接在Dog类的内部定义访问数据的函数,这样,就把“数据”给封装起来了。这些封装数据的函数是和Dog类本身是关联起来的,我们称之为类的方法:
class Dog(object): def __init__(self, weight, color): self.weight = weight self.color = color def print_dog(self): print('%s: %s' % (self.weight, self.color))我们从外部看Dog类,就只需要知道,创建实例需要给出weight和color,而如何打印,都是在Dog类的内部定义的,这些数据和逻辑被“封装”起来了,调用很容易,但却不用知道内部实现的细节。
(3). 访问限制从前面Dog类的定义来看,外部代码还是可以自由地修改一个实例的weight、color属性,我们可以设置内部属性不被外部访问:
class Dog(object): # 加下划线 def __init__(self, weight, color): self.__weight = weight self.__color = color def print_dog(self): print('%s: %s' % (self.__weight, __self.color)) huskey = Dog(60, 'green') print(huskey.__name) # 无法再访问属性,会出错但是如果外部代码需要获取weight、color属性呢?-> 添加get_weight、get_color方法
class Dog(object): ... def get_weight(self): return self.__weight def get_color(self): return self.__color如果又要允许外部代码修改weight、color怎么办?->添加set_weight、set_color方法
class Dog(object): ... def set_weight(self,weight): self.__weight = weight def set_color(self): self.__color = color
为什么要费这么大周折呢?之前不是可以直接husky.weight=10直接改吗
因为在方法中,可以对参数做检查,避免传入无效的参数:
继承就是:父类和子类之间的交互关系
(1)为什么要用继承?最大的好处是子类获得了父类的全部功能
class Animal(object): def run(self): print('Animal is running...') # Dog继承父类Animal,并且自动拥有run属性,可以在Dog对象中直接调用 class Dog(Animal): pass # 子类可以自己增加一些方法(eat),同时也可以重写父类的方法(run)---》这就是多态 class Cat(Animal): def run(self): print('Dog is running...') def eat(self): print('Eating meat...') (2)什么是多态?在继承关系中,如果一个实例的数据类型是某个子类,那它的数据类型也可以被看做是父类。但是反过来就不行了
C是dog,C也是animal
D是animal,但你不能说D也是Dog
任何依赖父类作为参数的函数或者方法都可以不加修改地正常运行,原因就在于多态。
当我们需要传入Dog、Cat、Tortoise……时,我们只需要接收Animal类型就可以了,因为Dog、Cat、Tortoise……都是Animal类型,然后,按照Animal类型进行操作即可。由于Animal类型有run()方法,因此,传入的任意类型,只要是Animal类或者子类,就会自动调用实际类型的run()方法,这就是多态的意思
对于一个变量,我们只需要知道它是Animal类型,无需确切地知道它的子类型,就可以放心地调用run()方法,而具体调用的run()方法是作用在Animal、Dog、Cat还是Tortoise对象上,由运行时该对象的确切类型决定
def run_twice(animal): animal.run() run_twice(Animal()) # 调用animal的run run_twice(Dog()) # 调用dog的run run_twice(Cat()) # 调用cat的run 2. 面向对象高级编程 (1). __slots__的使用动态绑定允许我们在程序运行的过程中动态给class加上功能, 但是,如果我们想要限制实例的属性怎么办?比如,只允许对Student实例添加name和age属性。