• 面向对象 --- 封装


    封装

    封装在于明确区分内外,使得类实现者可以修改封装内的东西而不影响外部调用者的代码;而外部使用用者只知道一个接口(函数),只要

    接口(函数)名、参数不变,使用者的代码永远无需改变。这就提供一个良好的合作基础——或者说,只要接口这个基础约定不变,则代

    码改变不足为虑。

    class Room:
        def __init__(self,name,length,width):
            self.name = name
            self.__length = length
            self.__width = width
            
        def get_name(self):
            return self.__name
        def set_name(self,newName):
            if type(newName) is str and newName.isdigit() ==False
                self.__name = newName
            else:
                print('不合法的姓名')
        def area(self):
            return self.__length * self.__width
    
    s = Room('sole',2,1)
    print(s.area())
    '''
    会用到私有的这个概念的场景
    1.隐藏起一个属性 不想让类的外部调用
    2.我想保护这个属性 不想让属性随意被改变
    3.我想保护这个属性 不想让子类继承
    '''

    property是一种特殊的属性,访问它时会执行一段功能(函数)然后返回值

    '''
    成人的BMI数值:
    过轻:低于18.5
    正常:18.5-23.9
    过重:24-27
    肥胖:28-32
    非常肥胖, 高于32
      体质指数(BMI)=体重(kg)÷身高^2(m)
      EX:70kg÷(1.75×1.75)=22.86
    '''
    class Person:
        def __init__(self,weight,height):
            self.weight = weight
            self.height = height
        @property
        def bmi(self):
            return  self.weight/self.height**2
    b1 = Personi(90,1.80)
    print(b1.bmi)
    import math
    class Circle:
        def __init__(self,radius): #圆的半径radius
            self.radius=radius
    
        @property
        def area(self):
            return math.pi * self.radius**2 #计算面积
    
        @property
        def perimeter(self):
            return 2*math.pi*self.radius #计算周长
    
    c=Circle(10)
    print(c.radius)
    print(c.area) #可以向访问数据属性一样去访问area,会触发一个函数的执行,动态计算出一个值
    print(c.perimeter) #同上
    '''
    输出结果:
    314.1592653589793
    62.83185307179586
    注意:此时的特性area和perimeter不能被赋值
    c.area=3 #为特性area赋值
    抛出异常:
    AttributeError: can't set attribute
    '''

    property

    将一个类的函数定义成特性以后,对象再去使用的时候obj.name,根本无法察觉自己的name是执行了一个函数然后计算出来的,这种特性的使用方式遵循了统一访问的原则.

    class Foo:
        def __init__(self,val):
            self.__NAME=val #将所有的数据属性都隐藏起来
    
        @property
        def name(self):
            return self.__NAME #obj.name访问的是self.__NAME(这也是真实值的存放位置)
    
        @name.setter
        def name(self,value):
            if not isinstance(value,str):  #在设定值之前进行类型检查
                raise TypeError('%s must be str' %value)
            self.__NAME=value #通过类型检查后,将值value存放到真实的位置self.__NAME
    
        @name.deleter
        def name(self):
            raise TypeError('Can not delete')
    
    f=Foo('egon')
    print(f.name)
    # f.name=10 #抛出异常'TypeError: 10 must be str'
    del f.name #抛出异常'TypeError: Can not delete'
    class Foo:
        def get_AAA(self):
            print('get的时候运行我啊')
    
        def set_AAA(self,value):
            print('set的时候运行我啊')
    
        def delete_AAA(self):
            print('delete的时候运行我啊')
        AAA=property(get_AAA,set_AAA,delete_AAA) #内置property三个参数与get,set,delete一一对应
    
    f1=Foo()
    f1.AAA
    f1.AAA='aaa'
    del f1.AAA

    classmethod

    class Classmethod_Demo():
        role = 'dog'
    
        @classmethod
        def func(cls):
            print(cls.role)
    
    Classmethod_Demo.func()

    staticmethod

    class Staticmethod_Demo():
        role = 'dog'
    
        @staticmethod
        def func():
            print("当普通方法用")
    
    Staticmethod_Demo.func()

    在完全面向对象的程序中,

    如果一个函数 即和对象没关系 也和类没有关系 

    那么就用staticmethod将这个函数方法变成一个静态方法类方法和静态方法 都是类调用的

    对象可以调用类方法和静态方法 一般情况下

    推荐用类名调用类方法 有一个默认参数 cls 代表这个类 

    静态方法 没有默认的参数 就象函数一样

  • 相关阅读:
    变量使用的注意事项
    计算机存储单元
    常量
    mybatis报错There is no getter for property named '***' in 'class ***'
    sonar-scanner扫描各种出错解决
    SonarQube搭建的各种问题
    linux每日命令(18):whereis命令
    Django视图层之路由配置系统(urls)
    Django---MTV模型、基本命令、简单配置
    web框架
  • 原文地址:https://www.cnblogs.com/soleZ/p/8317433.html
Copyright © 2020-2023  润新知