面向对象之三大特征

张开发
2026/5/20 21:49:18 15 分钟阅读
面向对象之三大特征
封装封装Encapsulation是一种面向对象编程的基本概念指的是将对象的状态数据和行为方法绑定在一起并将其保护起来防止外部直接访问或修改。封装的目的是确保对象的数据只通过合法的接口进行访问和修改以提高代码的安全性、可维护性和灵活性私有化为了限制某些属性和方法仅在类内部访问对外部不可见或者避免父类中的某些属性和方法被子类继承可以将其私有化单下划线非公开API大多数Python代码都遵循这样一个约定有一个前缀下划线的变量或方法应被视为非公开的API例如_var1。这种约定不具有强制力。class Person: def __init__(self,name,age): self.name name self._age age person1 Person(Lucy,18) print(person1.name) print(person1._age) # 18双下划线名词改写有两个前缀下划线并至多一个后缀下划线的标识符例如__x会被改写为_类名__x。只有在类内部可以通过__x访问其他地方无法访问或只能通过_类名__x访问。名词改写是python属性私有化的底层逻辑class Person: def __init__(self,name,age): self.name name # 私有属性 self.__age age # 私有方法 def __run(self): print(f我叫{self.name}我今年{self.__age}) person1 Person(Lucy,18) print(person1.name) print(person1._Person__age) # 18 print(**20) person1._Person__run() # 我叫Lucy我今年18Property# 其他方法对私有属性的操作 ​ class Person: def __init__(self,name,age): self.name name self.__age age ​ def setAge(self, age): if age 18: self.__age age else: self.__age 18 def getAge(self): if self.__age18: return 18 else: return self.__age person1 Person(Lucy,16) print(person1.getAge()) # 16 person1.setAge(20) print(person1.getAge()) # 18在python中property的主要作用是将方法“伪装”成普通属性从而在获取、设置、删除属性时添加额外的逻辑如校验、计算、日志方法转换为属性可通过property装饰器将一个方法转换为属性来调用。转换后可直接使用 .方法名来使用而无需使用 .方法名()class Person: def __init__(self,name,age): self.name name self.__age age property def age(self): # 这一步是读取操作property修饰的方法名用私有属性的名字对外暴露age属性内部用 __age 存储原始数据 if self.__age18: return 18 else: return self.__age person1 Person(Lucy,16) ​ print(person1.age) # 16读写属性将方法名设置为去掉双下划线的私有属性名使用 属性名.setter 装饰class Person: def __init__(self,name,age): self.name name self.__age age property def age(self): # property修饰的方法名用私有属性的名字对外暴露age属性内部用 __age 存储原始数据 # 读取私有属性值 if self.__age18: return 18 else: return self.__age age.setter def age(self,age): # 为私有属性赋值 if age18: self.__age age else: self.__age 18 person1 Person(Lucy,12) print(person1.age) # 12 person1.age 14 print(person1.age) # 14继承子类派生类继承父类基类中的属性和方法实现代码重用。子类可以新增自己特有的方法也可以重写父类的方法。子类不能继承父类的私有属性和私有方法因为存在名称改写但是可以通过改写后的名称直接访问父类的私有成员不过这种做法违背了封装原则不建议使用。# 破坏封装的不良做法 class BankAccount: def __init__(self, balance): self.__balance balance ​ def deposit(self, amount): if amount 0: self.__balance amount else: raise ValueError(存款金额必须为正) ​ def get_balance(self): return self.__balance ​ class HackerAccount(BankAccount): def steal_money(self): # 直接访问父类的私有属性 self._BankAccount__balance 1000000 ​ account HackerAccount(100) account.steal_money() print(account.get_balance()) # 1000000单继承 语法class 类名父类: 类体 class Person: def __init__(self,name,age,gender): self.name name self.age age self.gender gender def hobby(self): print(ctrl) class man(Person): # 单继承 当之类不增加额外的属性init不需要写 def self_introduction(self): print(f名字{self.name},年龄{self.age},性别{self.gender}) def hobby(self): # 重写方法 print(play game) man1 man(Jack,18,male) man1.self_introduction() man1.hobby()多继承调用方式时现在子类中查找若不存在则从左到右依次查找父类中是否包含方法 语法class 类名(父类1, 父类2, ...): 类体 ​ class Person: def __init__(self, name, age): self.name name self.age age ​ def hobby(self): print(Persons hobby: reading) ​ def introduce(self): print(fIm {self.name}, {self.age} years old.) ​ class Worker: def __init__(self, company): self.company company ​ def work(self): print(fWorking at {self.company}) ​ def hobby(self): print(Workers hobby: sleeping) ​ # 多继承同时继承 Person 和 Worker class StudentWorker(Person, Worker): def __init__(self, name, age, company, school): # 分别调用两个父类的初始化方法 Person.__init__(self, name, age) Worker.__init__(self, company) self.school school ​ def study(self): print(fStudying at {self.school}) ​ sw StudentWorker(Alice, 22, Microsoft, Stanford) sw.introduce() sw.work() sw.study()复用父类方法子类可以在类中使用 super().方法名() 或 父类名.方法名() 来调用父类的方法class Person: def __init__(self, name, age): self.name name self.age age ​ def hobby(self): print(Persons hobby: reading) ​ def introduce(self): print(fIm {self.name}, {self.age} years old.) ​ class Worker: def __init__(self, company): self.company company ​ def work(self): print(fWorking at {self.company}) ​ def hobby(self): print(Workers hobby: sleeping) ​ # 多继承同时继承 Person 和 Worker class StudentWorker(Person, Worker): def __init__(self, name, age, company, school): # 分别调用两个父类的初始化方法 Person.__init__(self, name, age) Worker.__init__(self, company) self.school school ​ def study(self): # super().方法名 super().introduce() print(fStudying at {self.school}) # 类名.方法名 Person.introduce(self) ​ sw StudentWorker(Alice, 22, Microsoft, Stanford) sw.introduce() sw.work() sw.study()方法解析顺序方法解析顺序mro—Method Resolution Order。可使用 类名.mro访问类的继承链来查看方法解析顺序class Person: def __init__(self, name, age, **kwargs): super().__init__(**kwargs) # 调用 MRO 链上的下一个 __init__ self.name name self.age age ​ def hobby(self): print(Persons hobby: reading) ​ def introduce(self): print(fIm {self.name}, {self.age} years old.) ​ class Worker: def __init__(self, company, **kwargs): super().__init__(**kwargs) # 调用 MRO 链上的下一个 __init__ self.company company ​ def work(self): print(fWorking at {self.company}) ​ def hobby(self): print(Workers hobby: sleeping) ​ class StudentWorker(Person, Worker): def __init__(self, name, age, company, school, **kwargs): super().__init__(namename, ageage, companycompany, **kwargs) self.school school ​ def study(self): super().introduce() # 调用 MRO 链上第一个 introduce() print(fStudying at {self.school}) print(StudentWorker.__mro__) # (class __main__.StudentWorker, class __main__.Person, class __main__.Worker, class object) sw StudentWorker(Alice, 22, Microsoft, Stanford) sw.introduce() # 来自 Person sw.work() # 来自 Worker sw.study() # study() 使用 super().introduce() 调用 MRO 上第一个 introduce()方法重写在子类中定义与父类方法重名的方法调用时会调用子类中重写的方法class Animal: def speak(self): print(Animal makes a sound) ​ class Dog(Animal): def speak(self): # 重写父类的 speak 方法 print(Dog barks) ​ class Cat(Animal): def speak(self): # 重写父类的 speak 方法 print(Cat meows) a Animal() d Dog() c Cat() a.speak() # Animal makes a sound d.speak() # Dog barks c.speak() # Cat meows⚠️子类重写init()并调用时不会执行父类的init()方法。如有必要需在子类init()中使用super().init()来调用父类的init()方法多态同一事物在不同场景下呈现不同状态class Animal: def speak(self): print(动物发出声音) ​ class Dog(Animal): def speak(self): print(小狗汪汪汪) ​ class Cat(Animal): def speak(self): print(小猫喵喵喵) ​ ​ def make_sound(animal): animal.speak() ​ ​ dog Dog() cat Cat() ​ make_sound(dog) make_sound(cat)

更多文章