封装

封装分为两种:

1、广义封装:封装到对象中的属性称为广义封装

2、狭义封装:封装到类或对象中不可在外部调用的变量属性或方法称为狭义封装

 

类分为两部分:

1、静态变量(静态字段)部分

2、方法部分

示例1

class Person:
    chara = '穿衣服'   # 这部分称为静态变量或静态字段

    def __init__(self,name,age):   # 这部分称为方法
        self.name = name
        self.age = age

每个部分又分许多小部分:

示例2

class Person:

    chara = '穿衣服'  # 公有静态变量
    __breed = '黄皮肤' # 私有静态变量

    def __init__(self,name,age):   # 普通方法(构造方法)
        self.name = name  # 公有对象属性
        self.__age = age   # 私有对象属性

    def eat(self):    # 公有方法
      print('人都需要吃饭补充能量')

    def __work(self):  # 私有方法
        pass

私有方法:在类外部不能被调用,只有在类内部才能调用。
公有方法:在任何地方都能被调用。

p = Person('eric',100)
print(p.chara)
print(p.breed)
AttributeError: 'Person' object has no attribute 'breed'

print(p.__breed)
AttributeError: 'Person' object has no attribute '__breed'
想在外部访问__breed怎么办?
print(p._Person__breed)  # 黄皮肤,虽然这种方法能够访问到类里面的私有类型的内容,但是在以后的编程中不能这么用。

 

私有类型的内容只能在类的内部去调用,例如在类内部调用__breed这个静态变量。

class Person:

    chara = '穿衣服'  # 公有静态变量
    __breed = '黄皮肤' # 私有静态变量

    def __init__(self,name,age):   # 普通方法

        self.name = name  # 公有对象属性
        self.__age = age   # 私有对象属性

    def __work(self):  # 私有方法
        print('他的工作是鉴黄师')

    def meth(self):
        print(self.__age)  # 查看age的值
        self.__work()  # 调用私有方法,查看里面的内容
        print(self.__breed)

p = Person('eric',100)
p.meth()
100
他的工作是鉴黄师
黄皮肤
子类同样不能访问父类中的私有静态变量或方法
在类的执行时,将类加载到内存时,类内部有__变量名这样的方法,在python解释器中,都会被解释成 _类名__变量名 这样的格式

练习题:
BMI指数(BMI是计算而来的,但很明显它听起来像是一个属性而非方法,如果我们将其做成一个属性,更便于理解)
成人的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 BMI:

    def __init__(self,height,weight):
        self.__height= height
        self.__weight = weight

    def value(self):
         BMI = self.__weight / (self.__height**2)   # 对象的私有属性只能在类的内部调用
         return BMI

b = BMI(1.74,62)
print(b.value())
计算BMI指数

接口类和抽象类

抽象类和接口类是一种规范,一种写代码时的规范,在接口类中,定义了一些接口名并且并未实现接口的功能,子类继承接口类,并且实现接口的功能 

接口类:(模拟支付接口)

第一版:

class Wechat_pay(Pay_regulations):
    def pay(self,money):
        print('您通过微信支付%s元' %money)

class Alipay(Pay_regulations):
    def pay(self,money):
        print('您通过支付宝支付%s元' %money)

w = Wechat_pay()
w.pay(200)
a = Alipay()
a.pay(100)
缺点:每实例化一次,就要传一次值,类多了的话,就会显得很繁琐

第二版:

class Wechat_pay(Pay_regulations):
    def pay(self,money):
        print('您通过微信支付%s¥' %money)

class Alipay(Pay_regulations):
    def pay(self,money):
        print('您通过支付宝支付%s¥' %money)

def pay(obj,money):
    obj.pay(money)

w = Wechat_pay()
a = Alipay()
优点:统一了支付规则,归一化设置。

第三版:

class Pay_regulations:   # 定义一个父类,作为规范
    def pay(self,money):pass

class Wechat_pay(Pay_regulations):  # 每个接口继承父类的规范
    def pay(self,money):
        print('您通过微信支付%s元' %money)

class Alipay(Pay_regulations):
    def pay(self,money):
        print('您通过支付宝支付%s元' %money)

def pay(obj,money):
    obj.pay(money)

w = Wechat_pay()
a = Alipay()
pay(a,400)
pay(w,300)
View Code

接口提取了一群类共同的函数,可以把接口当做一个函数的集合。

然后让子类去实现接口中的函数。

这么做的意义在于归一化,什么叫归一化,就是只要是基于同一个接口实现的类,那么所有的这些类产生的对象在使用时,从用法上来说都一样。

归一化,让使用者无需关心对象的类是什么,只需要的知道这些对象都具备某些功能就可以了,这极大地降低了使用者的使用难度。

抽象类:

第四版:

from abc import ABCMeta,abstractmethod   # 导入接口类的必要模块,作用:让定义的接口强制按照这个规范去执行,不按规范执行就会报错,这种格式就表示的是抽象类。

class Pay_regulations(metaclass=ABCMeta):   

   @abstractmethod
    def pay(self,money):pass

class Wechat_pay(Pay_regulations):
    def pay(self,money):
        print('您通过微信支付%s元' %money)

class Alipay(Pay_regulations):
    def pay(self,money):
        print('您通过支付宝支付%s元' %money)

def pay(obj,money):
    obj.pay(money)

w = Wechat_pay()
a = Alipay()
pay(a,400)
pay(w,300)
View Code

与java一样,python也有抽象类的概念但是同样需要借助模块实现,抽象类是一个特殊的类,它的特殊之处在于只能被继承,不能被实例化

如果说类是从一堆对象中抽取相同的内容而来的,那么抽象类是从一堆中抽取相同的内容而来的,内容包括数据属性和函数属性。

 

posted on 2018-06-29 11:37  花豆豆  阅读(902)  评论(0编辑  收藏  举报