• day 26面向对象 的封装 接口 抽象


    大纲分析

    # 面向对象
    # 类 :一类具有相同属性和方法的事物
    #类的定义:class
    #类中可以定义的方法种类:
    #普通方法 self 对象
    #类方法 cls @classmethod 类/对象
    #静态方法 @staticmethod 类/对象
    #属性方法 self @property 对象
    #私有方法 self __方法名 self/cls
    #类中可以定义的属性: 静态属性 类
    # 对象
    #实例化 : 类名()
    #创造对象
    #初始化对象 __init__
    #返回一个对象
    #对象的属性:
    # 普通属性 对象
    # 私有属性 __属性名 self
    #属性的操作
    #增 对象名.新属性名 = 值
    #删 del 对象名.属性名
    #改 对象名.属性名 = 新值
    #查 对象名.属性名

    #组合 : 一个类的对象作为另一个类对象的属性;什么有什么
    #继承 : 解决代码的复用,提取公共代码到父类;什么是什么
    # 单继承和多继承
    # 子类继承了父类除了私有的之外的所有属性和方法
    # 子类执行方法的查找顺序:
    # 经典类中:先找自己,自己没有找父类,遵循深度优先
    # 新式类中:先找自己,自己没有找父类,遵循广度优先
    # 子类执行父类的方法:
    #1.指名道姓 指到谁就是谁 父类名.父类中的方法名(self)
    #2.super 只能在新式类中使用,且找的顺序是mro顺序 super(子类名,子类对象名).方法名()
    # *** 抽象类和接口类
    #@abstractmethod
    #多态
    # python 天生多态
    #崇尚鸭子类型 : 不需要通过继承关系就实现对相似的功能

    # 封装
    # 【封装原则】
    # 1. 将不需要对外提供的内容都隐藏起来;
    # 2. 把属性都隐藏,提供公共方法对其访问。
    # 私有变量和私有方法
    # 在python中用双下划线开头的方式将属性隐藏起来(设置成私有的)
    # 针对变量属性x (静态或者动态 ) __x 相当于 _类名__x
    # 封装 :把一些属性和方法放到类里 这本身就是一种封装
    # 封装 : 把属性和方法藏在类里 我只能在类内部调用,不能再外部使用

    #1 私有属性之一 私有的对象属性
    # class Room:
    # def __init__(self,name,price,length,width):
    # self.name = name
    # self.price = price
    # self.__length =length #私有的对象属性
    # self.__width = width
    #
    # def area(self):
    # return self.__length*self.__width
    #
    # house = Room('小超超',1000000,2,1)
    # print(house.area())

    # 私有属性能不能继承 不能继承 因为上级的 _A__func 这一级 是 _B__FUNC
    # 定义一个私有变量属性方法 : __名字
    #在类的内部可以直接用 : __名字
    #在类的外部不能直接使用,如果一定要用,在私有方法之前加上:_类名,变成 _类名__名字
    #在类外的名字 通过__dict__就可以查看不建议
    # class A:
    # def func(self): # fun()
    # print('__a_func')
    #
    # class B(A):
    # def __init__(self):
    # self.func() # func()
    # print(11)
    # b = B()
    # __a_func
    # 11
    # 这样的情况 self.func() 变成 b.func() 被A func(b)调用 继承了A 先打印 后打印11
    # class A:
    # def __func(self): #_A__func()
    # print('__a_func')
    #
    # class B(A):
    # def __init__(self):
    # self.__func() # _B__func()
    # def __func(self):
    # print(11)
    # b = B()
    # # 11
    # 因为父级A 是 _A__func() ,子集B 是_B__func() 函数名不一样所以不能继承A父类的
    # 但是下边的函数名是一样的。
    # 此时 b._B__func()
    # --------------
    # property
    # @property 把一个方法 伪装成一个属性 直接用就行了 在方法上加上@property
    #1.属性的值 是这个方法的返回值
    #2.这个方法不能有参数了 只能有self
    # 公有的
    #私有的 + property
    # class Person:
    # def __init__(self,name,height,weight):
    # self.name = name
    # self.height = height
    # self.__weight = weight
    #
    # @property
    # def bmi(self):
    # return self.__weight / (self.height ** 2)
    #
    # li = Person('李岩',1.75,65)
    # print(li.bmi)
    #
    #
    # 圆形类 : 面积 周长
    # from math import pi
    # class Circle:
    # def __init__(self,r):
    # self.r = r
    # @property
    # def area(self):
    # return self.r*self.r*pi
    #
    # @property
    # def perimeter(self):
    # return self.r*pi*2
    # c1 = Circle(5)
    # print(c1.area)
    # print(c1.perimeter)
    #

    #圆形类 : 面积 周长 property 的应用
    # from math import pi
    # class Circle:
    # def __init__(self,r):
    # self.r = r
    # @property
    # def area(self):
    # return self.r*self.r*pi
    #
    # @property
    # def perimeter(self):
    # return self.r*pi*2
    # c1 = Circle(5)
    # print(c1.area)
    # print(c1.perimeter)
    # 很重要的实例
    # 1简单的打折
    # class Goods:
    # discount = 0.8
    # def __init__(self,name,price):
    # self.name = name
    # self.__price = price
    # @property
    # def price(self):
    # return self.__price*Goods.discount
    # app = Goods('苹果',10)
    # print(app.price)
    # # #如没有哪个伪装属性@propetry 必须打印app.price()
    # app.price = 6 不能改变 因为里面是私有的
    # print(app.price)
    # 2题目组合propety 组合setter,修改改变价格为6元
    # 注意事项 修改的价格时候搭配 方法上面@property
    # 下边的同一个属性上面@属性.setter () 前提必须有prooety
    # 注意这个属性必须前后是一种
    # class Goods:
    # __dicount = 0.8
    # def __init__(self,name,price):
    # self.name = name
    # self.__price = price
    # @property
    # def price(self):
    # return self.__price*Goods.__dicount
    # @price.setter #装饰器
    # def price(self,new_price):
    # if type(new_price) is int: # 这个或者时float
    # self.__price = new_price
    # app = Goods('苹果',10)
    # app.price = 6 # setter
    # print(app.price) # property
    # 注意装饰器的调用没有返回值的话 直接调用就空
    # 封装
    # __私有+property
    #让对象的属性变得更安全了
    #获取到的对象的值可以进行一些加工
    #修改对象的值的同时可以进行一些验证

    # class Foo:
    # @property
    # def AAA(self):
    # print('get的时候运行我啊')
    #
    # @AAA.setter
    # def AAA(self,value):
    # print('set的时候运行我啊')
    #
    # @AAA.deleter
    # def AAA(self):
    # print('delete的时候运行我啊')
    #
    # #只有在属性AAA定义property后才能定义AAA.setter,AAA.deleter
    # f1=Foo()
    # print(f1.AAA) #property 为什么是None 在打印这个属性 只是调用没有返回
    # f1.AAA='aaa' #setter
    # del f1.AAA #deleter

    # 删除名字 先@property 后 @deleter 里面删除 外边在删除
    # class Goods:
    # __discount = 0.8 #静态属性
    # def __init__(self,name,price):
    # self.__name = name
    # self.__price = price #原价
    # @property
    # def name(self):
    # return self.__name
    #
    # @name.setter
    # def name(self,new_name):
    # self.__name = new_name
    #
    # @name.deleter
    # def name(self):
    # del self.__name
    # @property
    # def price(self): #折后价
    # return self.__price * Goods.__discount
    #
    # @price.setter
    # def price(self,new_price): #修改原价
    # if type(new_price) is int:
    # self.__price = new_price
    # apple = Goods('苹果',10)
    # apple.price = '10' #settrt
    # print(apple.price) #property
    # del __self.name
    # print(apple.name)



    # ---------

    #私有的
    #私有的静态属性、方法、对象属性
    #使用__名字的方式调用,保证在类内部可以调用,外部不行
    #私有的 不能被继承
    # 当有一个名字,不想被外部使用也不想被子类继承,只想在内部使用的时候就定义私有的

    #私有的
    #私有的静态属性、方法、对象属性
    #使用__名字的方式调用,保证在类内部可以调用,外部不行
    #私有的 不能被继承
    # 当有一个名字,不想被外部使用也不想被子类继承,只想在内部使用的时候就定义私有的

    # class D:
    # def __init__(self):
    # print('d')
    # class C(D):
    # def __init__(self):
    # print('c')
    # super().__init__()
    # class B(D):
    # def __init__(self):
    # print('b')
    # super().__init__()
    # class A(B,C):
    # def __init__(self):
    # print('a')
    # super().__init__()
    # #mro
    # a = A()
    # print(A.mro())
    # from math import pi
    # class Circle:
    # def __init__(self,circle_r):
    # self.circle_r = circle_r
    # def perimetre(self):
    # return 2*pi*self.circle_r
    # def area(self):
    # return pi*self.circle_r**2
    # class Rings:
    # def __init__(self,d_R,d_r):
    # self.d_R = Circle(d_R)
    # self.d_r = Circle(d_r)
    #
    # # Circle()这个是圆的对象 左边的是属性 Rings这个类 以Circle这个类的对象为属性 叫组合
    # @property
    # def ring_perimetre(self):
    # return self.d_R.perimetre()+self.d_r.perimetre()
    # @property
    # def ring_area(self):
    # return self.d_R.area()-self.d_r.area()
    # ring = Rings(10,5)
    # print(ring.ring_perimetre)
    # print(ring.ring_area)
    #
    # class A:
    # __N=0 #类的数据属性就应该是共享的,但是语法上是可以把类的数据属性设置成私有的如__N,会变形为_A__N
    # def __init__(self):
    # self.__X=10 #变形为self._A__X
    # def __foo(self): #变形为_A__foo
    # print('from A')
    # def bar(self):
    # self.__foo() #只有在类内部才可以通过__foo的形式访问到.
    # a = A()
    # print(A._A__foo())???????????????
    # A._A__N # 外边访问内部 是可以访问到的,即这种操作并不是严格意义上的限制外部访问,仅仅只是一种语法意义上的变形
    # print(A._A__N ) #外边访问内部 语法没问题 但是不能这么用
    # 1.
    # 类中定义的__x只能在内部使用,如self.__x,引用的就是变形的结果。
    # 2.
    # 这种变形其实正是针对外部的变形,在外部是无法通过__x这个名字访问到的。
    # 3.
    # 在子类定义的__x不会覆盖在父类定义的__x,因为子类中变形成了:_子类名__x, 而父类中变形成了:_父类名__x,即双下滑线开头的属性在继承给子类时,子类是无法覆盖的。

    # property属性 @property 在方法的前面 上面加上这个 底下的方法就变成属性了
    # 打印的时候就是直接打印方法 而不需要方法加上括号了
    # 复制代码
    # class People:
    # def __init__(self,name,weight,height):
    # self.name=name
    # self.weight=weight
    # self.height=height
    # @property
    # def bmi(self):
    # return self.weight / (self.height**2)
    #
    # p1=People('egon',75,1.85)
    # print(p1.bmi)
    # 什么是特性property
    #
    # property是一种特殊的属性,访问它时会执行一段功能(函数)然后返回值

    #-------------------
    #接口定义:是规范子类的一个模板,只要接口类定义的,就应该在子类中实现。
    # 接口类 不能被继承 就是父类就不能被继承,
    # 自己理解 接口类 模板 是针对 子类的方法不一样的而抛出异常,
    # 让其继承父类的方法,需要定义一个函数和一个新的父类
    # # 第一种比较low的那种
    # class Payment: #定义一个父类 为解决 子类的方法不统一
    # def pay(self,money): raise NotImplementedError #主动刨出异常
    #
    # class Apple_pay(Payment):
    # def pay(self,money):
    # print('请使用苹果支付了%s元'% money)
    #
    # class Ali_pay(Payment):
    # def pay(self, money):
    # print('请使用支付宝支付了%s元' % money)
    #
    # class Wechat_pay(Payment):
    # def fukuan(self, money):
    # print('请使用苹果支付了%s元' % money)
    # def pay (obj,money): #定义的函数和父类的方法必须一致才会检测通过的,
    # return obj.pay(money)
    # ap = Apple_pay()
    # al =Ali_pay()
    # we = Wechat_pay()
    # pay(ap,100)
    # pay(we,200)

    # 接口2 固定用法 自动检测异常的 如果子类不能继承父类就异常 接口类不能被继承
    # 如果有两个@abstractclassmethods 两个都会检测 必须符合两个才不会抛出异常
    # from abc import ABCMeta,abstractmethod
    # 父类(metaclass=ABCMeta)
    # 在父类方法上面装饰 @abstractmethod

    # from abc import ABCMeta,abstractmethod
    # class Payment(metaclass=ABCMeta): #定义一个父类 为解决 子类的方法不统一 metaclass元类
    # @abstractmethod
    # def pay(self,money):pass
    # @abstractmethod
    # def ger(self,money):pass
    # class Apple_pay(Payment):
    # def pay(self,money):
    # print('请使用苹果支付了%s元'% money)
    #
    # class Ali_pay(Payment):
    # def pay(self, money):
    # print('请使用支付宝支付了%s元' % money)
    #
    # class Wechat_pay(Payment):
    # def fukuan(self, money):
    # print('请使用苹果支付了%s元' % money)
    # def pay (obj,money): #定义的函数和父类的方法必须一致才会检测通过的,
    # return obj.pay(money)
    # ap = Apple_pay()
    # # al =Ali_pay()
    # # we = Wechat_pay()
    # pay(ap,100)
    # pay(we,200)
    # wechat 因为和父类方法不一样 所以就异常

    # 题目三 如果父类有两个方法 那字类也必须继承父类两个方法 否则报错 。
    # 接口类:
    # 是规范子类的一个模板,只要接口类中定义的,就应该在子类中实现
    # 接口类不能被实例化,它只能被继承
    # 支持多继承
    # ——————————————————————————
    # 定义一个类
    #类里面的方法
    #并没有用到self
    # 类方法 改变一个静态的属性
    # class Goods:
    # __discount = 0.8
    # @classmethod
    # def change_discount(cls,new_discount):
    # cls.__discount = new_discount
    # @classmethod
    # def get_discount(cls):
    # return cls.__discount
    # Goods.change_discount(0.75)
    # print(Goods.get_discount())
    #类方法
    #调用:不需要实例化 直接用类名调用就好
    #定义:不用接受self参数,默认传cls,cls就代表当前方法所在的类
    #什么时候用类方法?
    #需要使用静态变量 且 不需要和对象相关的任何操作的时候

    #静态方法
    #如果这个方法 既不需要操作静态变量
    # 也不需要使用对象相关的操作,
    # 就使用静态方法
    # class A:
    # @staticmethod
    # def func(name): #静态方法
    # print(123)
    # A.func('alex')
    #面向对象编程:专门为面向对象编程提供的一个方法——staticmethod
    #它完全可以当做普通函数去用,只不过这个函数要通过类名.函数名调用
    #其他 传参 返回值 完全没有区别

    #类里面,一共可以定义这三种方法:
    #普通方法 self
    #类方法 cls
    #静态方法

    #绑定方法 和 非绑定方法

    # class A:
    # @staticmethod
    # def func1(name): #静态方法
    # print(123)
    #
    # @classmethod
    # def func2(cls): # 静态方法
    # print(123)
    #
    # def func3(self):pass
    # a = A()
    # print(a.func1) #静态方法
    # print(a.func2) #类方法 : 绑定到A类的func
    # print(a.func3) #普通方法:绑定到A类对象的func

    #静态方法和类方法 都是直接可以使用类名调用
    #普通方法:对象调用
  • 相关阅读:
    LeetCode第[84]题(Java):Largest Rectangle in Histogram(最大的矩形柱状图)
    LeetCode第[79]题(Java):Word Search(矩阵单词搜索)
    LeetCode第[78]题(Java):Subsets(求子集)扩展——第[90]题:Subsets 2
    关于SpringMVC中两种映射器不能共存的解决
    LeetCode第[73]题(Java):Set Matrix Zeroes(矩阵置0)
    php分页的实现
    PHP编码规范
    PHP常用函数
    PHP配置文件详解php.ini
    面向对象编程——parent—this
  • 原文地址:https://www.cnblogs.com/xiaoluoboer/p/7881127.html
Copyright © 2020-2023  润新知