''' 继承:继承是从已有的类中派生出新的类,新类具有原类的数据属性和行为,并能扩展新的能力。 继承/派生名词: - 基类(base class)/超类(super class)/父类(father class) - 派生类(derived class)/子类(child class) 语法: class 类名(基类名): 语句块 子类不能直接访问父类的实例属性,但是可以直接访问类属性 ''' ''' 单继承:只继承一个父类 '''
class Person: def walk(self): print('walk') def say_hello(self): print('hello') class Student(Person): def study(self): print('study') def write(self): print('write') class Teacher(Person): def teach(self): print('teach') s1=Student() s1.walk() s1.say_hello()
''' 多继承:当父类中有相同的方法,在子类中调用该方法,并且没有指定调用哪个父类的方法 ~会按照父类列表从左到右的顺序进行查找,找到第一个定义该方法的父类,进行方法调用 '''
class Father: father_name_wild="father_wild" def __init__(self,name,age): self.father_name = name self.father_age = age def speak(self): print("father_speak") def walk(self): print("father_walk") class Mother: def __init__(self,name,age): self.mother_name = name self.mother_age = age def speak(self): print("mother_speak") def clean(self): print("mother_clean") class Son(Father,Mother): def __init__(self,name,age): self.son_name = name self.son_age = age def play(self): print("son_play") father=Father("father",40) mother=Mother("mother",39) son=Son("son",20) son.speak() print(mother.mother_name,mother.mother_age) print(father.father_name,father.father_age) print(son.son_name,son.son_age) print(son.father_name_wild)
''' 覆盖:覆盖是指在有继承关系的类中,子类中实现了与夫类同名的方法,在子类的实例调用该方法时~ ~实际调用的是子类中的方法版本,这种现象叫覆盖 '''
class Father: def walk(self): print("father_walk") class Son(Father): def walk(self): print("son_walk") son=Son() son.walk()
''' 封装:将一些属性和方法隐藏,如果需要外部代码访问,需要提供接口,使用接口访问隐藏的属性 ~和方法,从而提高代码的安全性和可维护性。 单下划线'_':属性或方法是以'_'开头,表示该属性或方法是受保护的,按照约定,外部代码 ~不能直接访问,但是这只是约定,并没有强制限制效果 '''
class Myclass: def __init__(self,value1,value2): self._protect_value = value1 self.__private_value=value2 myclass = Myclass(20,30) #受保护变量不允许直接访问只是约定 print(myclass._protect_value) # print(myclass.__private__value) #私有变量不能直接访问,原因:python将私有变量名修改为'_类名'+私有变量名 print(myclass._Myclass__private_valv
''' 如果受保护变量或私有变量需要外部代码访问,则可以提供getter和setter方法进行访问 '''
class Myclassv1: def __init__(self,value1,value2): self._protected_value=value1 self.__private_value=value2 def get_value(self): return self._protected_value,self.__private_value def set_value(self,value): self._protected_value=value c=Myclassv1(10,20) print(c._Myclassv1__private_value) print(c.get_value()) c.set_value(30) print(c.get_value())
''' @property装饰器:将方法转成属性,可以以属性的访问方式进行访问 @property默认将方法定义为一个只读属性,用来保护访问变量 @property和@property_name.setter组合使用,可以定义一个可写属性,property_name ~是@property装饰器方法转换的属性名 '''
class MyClass: def __init__(self,value): self.__private_value=value #@property装饰器将value方法转化成value属性 @property def value(self): print("调用了value方法") return self.__private_value #通过@property_name.setter给变量赋值 #方法名和@property修饰的的方法名需要一致 @value.setter def value(self,value): print("调用了seeter") self.__private_value=value @value.deleter def value(self): del self.__private_value c=MyClass(1) print(c.value) c.value=2 print(c.value) del c.value 会报错,因为已经删除了 print(c.value)
''' 多态:同一个方法名的方法的不同实现,分为动态多态和静态多态 静态多态:方法重载:方法名一样,参数个数不一样 '''
class Myclass: def add(self,a,b): return a+b #python不支持直接的方法重载 def add(self,a,b,c): return a+b+c #可以通过改变形参类型,比如添加默认参数或可变参数,以达到重载目的 def add(self,a,b,c=0): return a+b+c myclass = Myclass() print(myclass.add(1,2)) print(myclass.add(1,2,3))
''' 运算符重载 '''
class Point(): def __init__(self, x, y): self.x = x self.y = y #+号重载 def __add__(self, other): return Point(self.x + other.x, self.y + other.y) #由于重载了+号,需要输出使用重载+号的数据类型,所以需要再重载print()函数 def __str__(self): dic={'x':self.x, 'y':self.y} return f'{dic}' p1=Point(1,2) p2=Point(3,4) print(p1+p2)
''' 方法重写:子类重写父类中的方法,实现多态多态 动态多态:通过方法实现重写 '''
class Animal: def speak(self): return '通用声音' class Dog(Animal): def speak(self): return '狗叫' class cat(Animal): pass dog=Dog() cat=cat() print(dog.speak()) print(cat.speak())
''' 抽象类: 抽象类不能直接实例化,需要通过派生类来继承,并重写抽象类中的抽象方法 抽象类需要导入abc模块中ABC和abstractmethod 抽象类中不是所有的方法都是抽象方法,只有添加了@abstractmethod修饰器才是抽象方法 ~也可以有普通方法 '''
#模块导入 from abc import ABC, abstractmethod #定义抽象类 class Absclass(ABC): #@abstractmethod:抽象方法装饰器,将方法定义为抽象方法,只有方法声明 #~没有方法实现,抽象方法实现只能通过子类来实现 @abstractmethod def speak(self): pass #此处定义的是普通方法,与上面作对比。此处子类可以直接调用,不需要重写 def work(self): print("work") class Dog(Absclass): def speak(self): return 'woof' class Cat(Absclass): def speak(self): return 'meow' #抽象类不能被实例化 # a=Absclass() # print(a.speak()) def sound(animal): print(animal.speak()) dog1 = Dog() cat1 = Cat() sound(dog1) sound(cat1) dog1.work() cat1.work()
''' MRO ''' class A : def method(self): print('A.method()') class B(A): def method(self): print('B.method()') class C(A): def method(self): print('C.method()') class D(B,C): def method(self): print('D.method()') class E(C,B): def method(self): print('E.method()') class F(D,E): pass print(F.__mro__) ''' super():是用于调用父类(超类)的一个方法。使用 `super()` 时, ~Python 会动态查找类继承链中的下一个类。通过 MRO,避免了手动调用时可能发生的重复调用。 ''' class ClassA: def add(self, x, y): return x + y class ClassB(ClassA): def add (self, x, y): print('class B') return super().add(x,y) b=ClassB() print(type(b)) print(b.add(3,4))