继承
隐藏内部实现细节,对外提供操作方式。
权限控制:是通过对属性或方法添加单下划线、双下划线以及首尾双下划线来实现。
单下划线开头:以单下划线开头的属性或方法表示protected受保护的成员,这类成员被视为仅内部使用,允许类本身和子类进行访问,但实际上它可以被外部代码访问。
双下划线开头:表示priavte私有的成员,这类成员只允许定义该属性或方法的类本身进行访问。
首尾双下划线:一般表示特殊的方法。
class Student(): # 双下划线 def __init__(self,name,age,gender): self._name=name # self._name 受保护的 只有类和子类可以访问 self.__age=age # self.__age 表示私有的 只有类本身可以访问 self.gender=gender # 普通的实例属性,类的内部,外部,及子类都可以访问 # 受保护的 def _func1(self): print('子类和本身可以访问') # 私有的 def __func2(self): print('止呕定义的类可以访问') # 普通的实例方法 def show(self): self._func1() # 类本身访问受保护的方法 self.__func2() # 类本身访问私有方法 print(self._name) # 受保护的实例属性 print(self.__age) # 私有的实例属性 stu=Student('张三',25,'男') print(stu._name) # print(stu.__age) # 私有的实例属性不能访问,报错 stu._func1() # stu.__func2() # 私有的实例方法不能访问,报错 # 私有的属性和方法可以通过以下方法访问 print(stu._Student__age) stu._Student__func2() print(dir(stu))
属性的设置
class Student(): def __init__(self,name,gender): self.name=name self.__gender=gender # 使用@property 修饰方法 将方法转换成属性使用 只能查看值,不能修改值 @property def gender(self): return self.__gender # 将gender这个属性设置可修改 @gender.setter def gender(self,gender): if gender!='男' and gender !='女': print('性别有误') self.__gender='男' else: self.__gender=gender stu=Student('张三','男') print(stu.name,stu.gender) # stu.gender 就会执行gender()方法 stu.gender='女' print(stu.name,stu.gender)
继承
1,在python中一个子类可以继承N多个父类。
2,一个父类也可以拥有N多个子类。
3,如果一个类没有继承任何类,那么这个类默认继承的是object类。
继承的语法结构:
class 类名(父类1,父类2,...父类N): pass
# 默认继承object class Person: def __init__(self,name,age): self.name=name self.age=age def show(self): print(f'大家好,我叫{self.name},年龄:{self.age}') class Student(Person): def __init__(self,name,age,stuno): super().__init__(name,age) #调用父类的初始化方法 self.stuno=stuno class Doctor(Person): def __init__(self,name,age,department): super().__init__(name,age) self.department=department stu=Student('张三',10,'1002') stu.show() doc=Doctor('李四',34,'外科') stu.show()
class Father1(): def __init__(self,name): self.name=name def show1(self): print('这是父类1的方法') class Father2(): def __init__(self,age): self.age=age def show2(self): print('这是父类2的方法') class Son(Father1,Father2): def __init__(self,name,age,gender): Father1.__init__(self,name) Father2.__init__(self,age) self.gender=gender son=Son('张三',20,'男') son.show1() son.show2()
方法重写
子类继承了父类就拥有了父类中公有成员和受保护的成员。
父类的方法并不能完全适合子类的需求,这个时候子类就可以重写父类的方法。子类在重写父类的方法时,要求方法的名称必须与父类的方法的名称相同,在子类重写后的方法中可以通过super().XXX()调用父类中的方法。
# 默认继承object class Person: def __init__(self,name,age): self.name=name self.age=age def show(self): print(f'大家好,我叫{self.name},年龄:{self.age}') class Student(Person): def __init__(self,name,age,stuno): super().__init__(name,age) #调用父类的初始化方法 self.stuno=stuno def show(self): super().show() # super().方法名调用父类中的方法 print('这是子类重写的方法') class Doctor(Person): def __init__(self,name,age,department): super().__init__(name,age) self.department=department def show(self): #super().show() print(f'子类重写的方法,{self.name},{self.age}') stu=Student('张三',10,'1002') stu.show() #调用子类自有的方法 doc=Doctor('李四',34,'外科') doc.show() #调用子类自有的方法
多态
指的是“多种形态”,即便不知道一个变量引用的对象到底是什么类型,仍然可以通过这个变量调用对象的方法。
在程序运行过程中根据变量所引用对象的数据类型,动态决定 调用哪个对象中的方法。
Python语言中的多态,根本不关心对象的数据类型,也不关心类之间是否存在继承关系,只关心对象的行为(方法)。只要不同的类中有同名的方法,即可实现多态。
class Person(): def eat(self): print('人吃米饭') class Cat(): def eat(self): print('猫吃鱼') class Dog(): def eat(self): print('狗吃骨头') def fun(obj): # 这里不知道obj具体的数据类型,只需要obj有同名的方法 obj.eat() per=Person() cat=Cat() dog=Dog() fun(per) fun(cat) fun(dog)
object类
所有类直接或间接的父类
所有类都拥有object类的属性和方法
| object类中特殊的方法 | 功能描述 |
| __new__() | 由系统调用,用于创建对象 |
| __init__() | 创建对象时手动调用,用于初始化对象属性值 |
| __str__() | 对象的描述,返回值是str类型,默认输出对象的内存地址 |
class Person(object): def __init__(self,name,age): self.name=name self.age=age def show(self): print(f'大家好,{self.name},{self.age}') # 重写父类中__str__()方法 def __str__(self): return '我是子类中的方法,重写了父类中的方法' # 创建Person类的对象 per=Person('张三',20) #创建对象时自动会调用__init__() print(dir(per)) print(per) #自动调用了__str__方法 <__main__.Person object at 0x000000A241D77290> print(per.__str__())
特殊方法
| 运算符 | 特殊方法 | 功能描述 |
| + | __add__() | 执行加法运算 |
| - | __sub__() | 执行减法运算 |
| < <= == | __lt__() __le__() __eq__() | 执行比较运算 |
| > >= != | __gt__() __ge__() __ne__() | 执行比较运算 |
| * / | __mul__() __truediv__() | 执行乘法运算,非整除运算 |
| % // | __mod__() __floordiv__() | 执行取余运算,整除运算 |
| ** | __pow__() | 执行幂运算 |
a=10 b=20 print(dir(a)) print(f'a={a},b={b}') print(a+b) print(f'{a}+{b}',a.__add__(b)) print(f'{a}-{b}',a.__sub__(b)) print(f'{a}<{b}',a.__lt__(b)) print(f'{a}<={b}',a.__le__(b)) print(f'{a}=={b}',a.__eq__(b)) print(f'{a}>{b}',a.__gt__(b)) print(f'{a}>={b}',a.__ge__(b)) print(f'{a}!={b}',a.__ne__(b)) print(f'{a}*{b}',a.__mul__(b)) print(f'{a}/{b}',a.__truediv__(b)) print(f'{a}%{b}',a.__mod__(b)) print(f'{a}//{b}',a.__floordiv__(b)) print(f'{a}**{b}',a.__pow__(b))
特殊属性
| 特殊属性 | 功能描述 |
| obj.__dict__ | 对象的属性字典 |
| obj.__class__ | 对象所属的类 |
| class.__bases__ | 类的父类元组 |
| class.__base__ | 类的父类 |
| class.__mro__ | 类的层次结构 |
| class._subclasses__() | 类的子类列表 |
class A(): pass class B(): pass class C(A,B): def __init__(self,name,age): self.name=name self.age=age a=A() b=B() c=C('tom',20) print('对象a的属性字典',a.__dict__) # {} print('对象b的属性字典',b.__dict__) # {} print('对象c的属性字典',c.__dict__) # {'name': 'tom', 'age': 20} print('对象a的所属类',a.__class__) print('对象b的所属类',b.__class__) print('对象c的所属类',c.__class__) print('A类的父类元组',A.__bases__) print('B类的父类元组',B.__bases__) print('C类的父类元组',C.__bases__) print('A类的父类',A.__base__) print('B类的父类',B.__base__) print('C类的父类',C.__base__) print('A类的层次结构',A.__mro__) print('B类的层次结构',B.__mro__) print('C类的层次结构',C.__mro__) print('A类的子类列表',A.__subclasses__) print('B类的子类列表',B.__subclasses__) print('C类的子类列表',C.__subclasses__)
posted on
浙公网安备 33010602011771号