面向对象之封装

面向对象封装:

 封装就是隐藏对象的属性和实现细节,仅对外提供公共访问方式。

封装的真谛在于明确地区分内外,封装的属性可以直接在内部使用,而不能被外部直接使用,

然而定义属性的目的终归是要用,外部要想用类隐藏的属性,需要我们为其开辟接口,

让外部能够间接地用到我们隐藏起来的属性;被封装的内容的特点:1.外界不能直接访问,2.内部依然可以使用。

两个目的:

​   1.为了保证 关键数据的安全性。

  ​ 2.对外部隐藏实现细节,隔离复杂度。

封装原则:

  1. 将不需要对外提供的内容都隐藏起来;

  2. 把属性都隐藏,提供公共方法对其访问。

学习了封装后就可以控制属性的权限;在python只要两种权限,

  1.公开的.默认就是公开的。

  2.私有的,只能由当前类自己使用。

在外界访问私有的内容:

属性虽然被封装了,但是还是需要使用的,在外界如何访问。

通过定义方法类完成对私有属性的修改和访问。

什么时候应该封装:

​ 当有一些数据不希望外界可以直接修改时

​ 当有一些函数不希望给外界使用时

如何使用封装呢?语法如下:

""" 
在python中用双下划线开头的方式将属性隐藏起来(设置成私有的)
其实这仅仅这是一种变形操作且仅仅只在类定义阶段发生变形
类中所有双下划线开头的名称如__x都会在类定义时自动变形成:_类名__x的形式:
"""



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__N是可以访问到的,
#这种,在外部是无法通过__x这个名字访问到。

封装方法:

其目的是隔离复杂度。

"""
在编程语言里,对外提供的接口(接口可理解为了一个入口),
可以是函数,称为接口函数,这与接口的概念还不一样,接口代表一组接口函数的集合体。
""" # 取款是功能,而这个功能有很多功能组成:插卡、密码认证、输入金额、打印账单、取钱 # 对使用者来说,只需要知道取款这个功能即可,其余功能我们都可以隐藏起来,很明显这么做 # 隔离了复杂度,同时也提升了安全性 class ATM: def __card(self): print('插卡') def __auth(self): print('用户认证') def __input(self): print('输入取款金额') def __print_bill(self): print('打印账单') def __take_money(self): print('取款') def withdraw(self): self.__card() self.__auth() self.__input() self.__print_bill() self.__take_money() a=ATM() a.withdraw()

封装数据:

"""
将数据隐藏起来这不是目的。隐藏起来然后对外提供操作该数据的接口,
然后我们可以在接口附加上对该数据操作的限制,以此完成对数据属性操作的严格控制。
""" class Teacher: def __init__(self,name,age): # self.__name=name # self.__age=age self.set_info(name,age) def tell_info(self): print('姓名:%s,年龄:%s' %(self.__name,self.__age)) def set_info(self,name,age): if not isinstance(name,str): raise TypeError('姓名必须是字符串类型') if not isinstance(age,int): raise TypeError('年龄必须是整型') self.__name=name self.__age=age t=Teacher('jack',18) t.tell_info() t.set_info('jack',19) t.tell_info()

property装饰器:

property就是将一个类的函数定义成特性以后,对象再去使用的时候obj.name,

根本无法察觉自己的name是执行了一个函数然后计算出来的,这种特性的使用方式遵循了统一访问的原则。

"""
property装饰就是为了使得调用方式一致;有三个相关的装饰器 :
1.property   该装器用在获取属性的方法上 
2.@key.setter  该装器用在修改属性的方法上 
3.@key.deleter 该装器用在删除属性的方法上 
key是被property装饰的方法的名称 也就是属性的名称 
内部会创建一个对象 变量名称就是函数名称  
所以在使用setter和deleter时 必须保证使用对象的名称取调用方法 
所以是 key.setter
"""


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'

封装在于明确区分内外,使得类实现者可以修改封装内的东西而不影响外部调用者的代码;

而外部使用用者只知道一个接口(函数),只要接口(函数)名、参数不变,使用者的代码永远无需改变。

这就提供一个良好的合作基础——或者说,只要接口这个基础约定不变,则代码改变不足为虑。

abc模块的使用:

抽象类概念

抽象类是一个特殊的类,只能被继承,不能实例化

2.为什么要有抽象类

其实在未接触抽象类概念时,我们可以构造香蕉、苹果、梨之类的类,然后让它们继承水果这个的基类,水果的基类包含一个eat函数。

但是你有没有想过,我们可以将香蕉、苹果、梨实例化,去吃香蕉、苹果、梨。但是我们却不能将水果实例化,因为我们无法吃到叫水果的这个东西。

所以抽象类中只能有抽象方法(没有实现功能),该类不能被实例化,只能被继承,且子类必须实现抽象方法。

3.抽象类的作用

在不同的模块中通过抽象基类来调用,可以用最精简的方式展示出代码之间的逻辑关系,让模块之间的依赖清晰简单。

抽象类的编程,让每个人可以关注当前抽象类的方法和描述,而不需要考虑过多的实现细节,这对协同开发有很大意义,也让代码可读性更高。

"""
abc 不是随意取的 而是单词的缩写
abstract class
翻译为抽象类
抽象类的定义 :
类中包含 没有函数体的方法

"""

import abc

class AClass(metaclass=abc.ABCMeta):

    @abc.abstractmethod
    def run(self):
        pass
    @abc.abstractmethod
    def run1(self):
        pass


class B(AClass):

    def run(self):
        print("runrunrurn...")

b = B()

接口:

接口是一套协议规范,明确子类们应该具备哪些功能;抽象类是用于强制要求子类必须按照协议中规定的来实现;

然而,python不推崇限制你的语法, 我们可以设计成鸭子类型,既让多个不同类对象具备相同的属性和方法;

对于使用者而言,就可以以不变应万变,轻松的使用各种对象;只要遵循了USB接口协议,都能够被电脑所调用;

接口主要是方便了对象的使用者,降低使用者的学习难度;只要学习一套使用方法,就可以以不变应万变。

class Interface:
     
    def f1(self):
        '''
        to do something
        :return:
        '''
 
class Something(Interface):
     
    def f1(self):
        print('to do something...')
     
    def f2(self):
        print('to do other..')
原文地址:https://www.cnblogs.com/sweet-i/p/11252771.html