21,钻石继承,多态,封装,几个装饰器函数

 组合 什么有什么的关系
# 一个类的对象作为另一个类对象的
# 继承
# 子类可以使用父类中的名字(静态属性 方法)
# 抽象类和接口类 :
# 只能被继承不能被实例化
# 子类必须实现父类中的同名方法——规范代码
# 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 静态方法 由类调用,一个方法既不会用到对象的属性,也不会用到类的属性

 

posted @ 2018-05-28 17:14  Mr~Zhang  阅读(183)  评论(0编辑  收藏  举报