组合 什么有什么的关系
# 一个类的对象作为另一个类对象的
# 继承
# 子类可以使用父类中的名字(静态属性 方法)
# 抽象类和接口类 :
# 只能被继承不能被实例化
# 子类必须实现父类中的同名方法——规范代码
# metaclass = ABCMeta 、@abstractmethod
# python支持多继承,对于python来说抽象类和接口类没有区别
# 接口类是python特有的,因为python直接用类就可以实现接口的效果
# python没有“接口”这种数据类型,java中有
钻石继承
class A(object): def func(self): print('in A') class B(A): def func(self): print('in B') class C(A): def func(self): print('in C') class D(B,C): def func(self): print('in D') D.func(1) B.func(1) print(B.mro()) print(D.mro()) in D in B [<class '__main__.B'>, <class '__main__.A'>, <class 'object'>] [<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]
找一个名字,如果这个名字在子类不存在,就会遵循一个顺序往上找。继承关系会形成一张图,每个类都是这个途中的节点寻找顺序会把途中的每一个节点都找,且只找一次——遍历算法
Python3中里面的所有类都是新式类,新式类的遍历算法——遵循广度优先规律
找下一个点的时候,首先往深度走,但是如果这个深度的类,以后还会有机会找到,那么,就从广度找。
print(类.mro)能够查找子类之间的寻找顺序。
super并不是单纯的找父类,和mro顺序是完全对应的。
class A(): def func(self):print('in,A') class B(A): def func(self):print('in,B') class C(A): def func(self):print('in,C') class D(B): def func(self):print('in,D') class E(C): def func(self):print('in,E') class F(D,E): def func(self):print('in,F') print(F.mro()) [<class '__main__.F'>, <class '__main__.D'>, <class '__main__.B'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]
python3: 新式类:python3里全部都是新式类,新式类默认继承object。
python2:经典类:不主动继承object——遵循深度优先遍历算法,没有mro方法,也没有super方法。
新式类:主动继承object
多态
python天生自带多态
java多态 class Foo:pass class list(Foo):pass class dict(Foo):pass class str(Foo):pass def len(a): print(a) len(1)
封装
封装:面向对象的的特性
私有静态属性
# __静态属性 = 'aaa' # 私有的静态属性 # print(__静态属性) # __静态属性,_类名__名字 # 在一个变量之前 加上两个双下划线是有特殊意义的 # 加上了这个双下划线,这个变量就变成了私有的 # print(A.__静态属性) # 报错 私有的名字不能在类的外部使用 # print(A.__dict__) # # print(A._A__静态属性) # 从语法的角度上不允许你直接调用的 A.__wahaha = 'hahaha' # 在一个类的外部是不可能定义一个私有的名字的 print(A.__dict__)
私有对象属性
class Room: def __init__(self,owner,id,length,width,height): self.owner = owner self.id = id self.__length = length self.__width = width self.__height = height def area(self): return self.__length * self.__width r = Room('杰哥哥',302,2,1.5,0.5) print(r.area())
@property(将一个方法,伪装成一个属性)
from math import pi class Circle: def __init__(self,r): self.r = r @property def area(self): return self.r**2*pi @property def perimeter(self): return 2*pi*self.r c = Circle(5) # c.r print(c.area) # ==> c.area() print(c.perimeter) # 将一个方法伪装成一个属性
class Person: def __init__(self,name): self.__name = name # self.name = name @property def name(self): return self.__name @name.setter def name(self,new): if type(new) is str: self.__name = new alex = Person(444) print(alex.name) alex.name = 'sb' # 能不能改? —— 不能直接改 print(alex.name)
class Demo: def __init__(self,wahaha): self.__wahaha = wahaha @property # wahaha = property(wahaha) def wahaha(self): print('in wahaha') return self.__wahaha @wahaha.setter # wahaha = wahaha.setter(wahaha) # 也是一个装饰器方法 def wahaha(self,new): self.__wahaha = new d = Demo('wahaa') print(d.wahaha) # 可以被查看 d.wahaha = 123 # 可以被修改 print(d.wahaha)
class A: def __init__(self,path): self.__f = open(path,'w') @property def f(self):return self.__f @f.deleter def f(self): # 所有的借用操作系统的资源,在删除一个变量之前都必须先归还资源 self.close() del self.__f def write(self,content): self.__f.write(content) def close(self): self.__f.close() obj = A('wahaha') obj.write('wahahayawahaha') obj.close() del obj.f # f变量删除,文件没有关 print(obj.f)
@staticmethod
class Student: def __init__(self,name,sex): self.name = name self.sex = sex @staticmethod # 相当于函数 def login(): name = input('>>') if name == 'alex':print('登录成功') # 学生的登陆行为 Student.login()
# method 方法 —— 函数 由实例化对象去调用
# property 伪装成属性的方法 —— 特性 由实例化对象去调用
# classmethod 类方法 由类调用,只使用类中的静态变量
# staticmethod 静态方法 由类调用,一个方法既不会用到对象的属性,也不会用到类的属性