python面向对象的三大特性
好的,我将重新整理代码,重新编号,并提供详细的注释,确保每个部分都清晰易懂。
1. 封装(私有化)
1.1 理解封装
表面上:属性和方法封装在类中。
实质上:将属性和方法私有化,并定义 set
和 get
方法,外界通过 set
和 get
访问属性,对属性是一种权限的约束。
1.2 封装的作用
通过 set
方法限制赋值,通过 get
方法限制取值。
1.3 私有化
设置私有方法可以让我们通过 get_属性名(self)
和 set_属性名(self, 参数)
来访问内部属性,这样更加安全,也可以通过 get
或者 set
方法进行访问的限制。
class Person:# 限制属性作用,只有在该列表中的属性才能被其他方法和属性访问# 如果不在该列表中,即使是对象方法也是不能访问的# 这样做可以防止在函数外动态创建属性__slots__ = ['__name', '__age', '__flag']def __init__(self, name, age):self.__name = name # 私有属性self.__age = age # 私有属性self.__flag = True # 私有属性def get_name(self):if self.__flag:return self.__nameelse:return '没有权限查看用户名'def get_age(self):return self.__agedef set_name(self, name):if len(name) >= 6:self.__name = nameelse:print('名字必须要大于等于6位')def set_age(self, age):if 0 < age < 125:self.__age = ageelse:print('年龄赋值失败,必须在0~125范围内')# 创建对象
p = Person('lucy', 20)
print(p.get_name()) # 输出: lucy
print(p.get_age()) # 输出: 20p.set_name('steven')
print(p.get_name()) # 输出: stevenp.set_name('tom')
print(p.get_name()) # 输出: tomp.set_age(10)
print(p.get_age()) # 输出: 10
1.4 使用 @property
装饰器
为了让用户体验到通过 对象名.属性名
访问对象内部的属性,同时起到限制作用,可以使用 @property
装饰器。
class Person:__slots__ = ['__name']def __init__(self):self.__name = 'gfb'@propertydef name(self):return self.__name@name.setterdef name(self, name):self.__name = name# 创建对象
p = Person()
print(p.name) # 输出: gfb
p.name = 'steven'
print(p.name) # 输出: steven
2. 继承
继承让程序更加简洁,提高代码的复用性,提高了程序的可读性。继承了父类的非私有属性和方法(父类、基类、超类)。如果子类定义了一个相同的属性,先找子类属性,再找父类。如果父类与子类有相同的方法,则认为子类重写了此方法(重写、覆盖、override)。
2.1 示例代码
class Animal:type1 = '动物' # 类属性def __init__(self):self.name = '花花' # 实例属性print('----->Animal')def run(self):print('正在奔跑....')def eat(self):print('喜欢吃...')def __str__(self):return '当前类型:{}'.format(Animal.type1)class Dog(Animal):type1 = '狗' # 子类覆盖父类的类属性def __init__(self, name, color):# 调用父类的 __init__ 方法Animal.__init__(self)self.name = name # 子类覆盖父类的实例属性self.color = colordef see_home(self):print('看家高手....')def eat(self):print('喜欢啃骨头...')# 创建对象
d = Dog('大黄', '黄色')
d.run() # 输出: 正在奔跑....
d.eat() # 输出: 喜欢啃骨头...
d.see_home() # 输出: 看家高手....
print(d.name) # 输出: 大黄
print(d) # 输出: 当前类型:狗
3. 多继承
多继承的查找顺序:
- 经典类:广度优先(从左到右的原则)
- 新式类:C3 算法形式 - 深度优先 - MRO 原则
可以通过 类名.__mro__
或者 类名.mro()
函数查看搜索顺序。
3.1 示例代码
class A:def method(self):print("A method")class B(A):def method(self):print("B method")super().method()class C(A):def method(self):print("C method")super().method()class D(B, C):def method(self):print("D method")super().method()# 创建对象
d = D()
d.method()
# 输出:
# D method
# B method
# C method
# A method
4. 多态
多态就是一个父类的名可以接受一个子类对象。比如我们创建了一个动物类,也创建了一个狗类,狗类继承了动物类,我们创建了一个动物类对象,因为狗类是动物类的子类,我们在接收狗对象的时候可以将这个狗对象存放在创建的动物类变量中。
4.1 示例代码
class Pet:type = '宠物'class Dog(Pet):def __init__(self, name):self.name = nameclass PetShop:def __init__(self, name):self.name = nameself.pets = set()def save_pet(self, pet):if isinstance(pet, Pet):self.pets.add(pet)print('添加成功!')else:print('不是宠物不收留!')def sale_pet(self, pet):if isinstance(pet, Pet):self.pets.discard(pet)print('宠物减少')else:print('不是宠物不收留!')def search_pet(self, pname):for pet in self.pets:if pname == pet.name:print('宠物在商店里')breakelse:print('不存在此宠物!')def all_pets(self):print('宠物商店所有的宠物信息如下:')for pet in self.pets:print(pet.name)# 创建宠物商店
shop = PetShop('Happy Pet Shop')# 创建宠物
dog1 = Dog('大黄')
dog2 = Dog('小白')# 添加宠物
shop.save_pet(dog1)
shop.save_pet(dog2)# 查看所有宠物
shop.all_pets()# 搜索宠物
shop.search_pet('大黄')# 销售宠物
shop.sale_pet(dog1)# 查看所有宠物
shop.all_pets()
注意点
- Python 中的多态是假的,因为是弱数据类型。
__setattr__()
:赋值的时候触发,使用的时候要通过父类方法进行赋值object.__setattr__(参数1, 参数2)
。
希望这些注释版的代码和解释能帮助你更好地理解面向对象编程的三大特性:封装、继承和多态。