day 18

主要内容:

  01 接口类

  02 鸭子类型

  03 多态,封装

  04 类的成员(私有成员)

  

 

===============================

接口类:python中没有接口类的概念。它是为了指定一种规范

下面看一个例子:

#第一版
class Alipay:
    def __init__(self,money):
        self.money=money

    def pay(self):
        print("使用支付宝支付%s"%self.money)

class Jdpay:
    def __int__(self,money):
        self.money=money

    def pay(self):
        print("使用京东支付%s"%self.money)

a1=Alipay(1000)
a1.pay()

j1=Jdpay(500)
j1.pay()

每调用一次都要用对象名.函数的方法不太好

所以改进版:

#第二版
class Alipay:
    def __init__(self,money):
        self.money=money

    def pay(self):
        print("使用支付宝支付%s"%self.money)

class Jdpay:
    def __init__(self,money):
        self.money=money

    def pay(self):
        print("使用京东支付%s"%self.money)

def pay(obj):
    obj.pay()

a1=Alipay(1000)
j1=Jdpay(10000)


#归一化设计
pay(a1)
pay(j1)

通过定义一个pay接口来实现归一化设计,这样既美观又实用。那要是程序员不遵循这样的归一化设计呢?,接下来介绍一种强制制定一种规范,不规范就会报错的方法:

from abc import ABCMeta,abstractmethod
#强制制定一个规范,凡是继承类中必须有pay方法,如果没有,实例化对象的时候就会报错
class Payment(metaclass=ABCMeta):
    def __init__(self,money):
        delf.money=money
    @abstractmethod
    def pay(self): pass

class Alipay(Payment):
    def pay(self):
        print("使用支付宝支付%s" % self.money)


class Jdpay(Payment):
    def pay(self):
        print("使用京东支付%s" % self.money)


class Wechatpay(Payment):
    def pay(self):
        print("使用微信支付了%s" % self.money)

w1=Wechatpay(100)
w1.pay()

a1 = Alipay(500)
a1.pay()

j1=Jdpay(300)
j1.pay()




第二种方式:

class Payment:
    """
    此类什么都不做,就是制定一个标准,谁继承我,必须定义我里面的方法。
    """
    def pay(self,money):
        raise Exception("你没有实现pay方法")

class QQpay(Payment):
    def pay(self,money):
        print('使用qq支付%s元' % money)

class Alipay(Payment):
    def pay(self,money):
        print('使用阿里支付%s元' % money)

class Wechatpay(Payment):
    def fuqian(self,money):
        print('使用微信支付%s元' % money)


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

a = Alipay()
b = QQpay()
c = Wechatpay()
pay(a,100)
pay(b,200)
pay(c,300)

#======运行结果=========
#使用阿里支付100元
# Traceback (most recent call last):
# 使用qq支付200元
#   File "C:/Users/HelloWorld/PycharmProjects/fullstack_s2/day 18/04 多态 封装.py", line 90, in <module>
#     pay(c,300)
#   File "C:/Users/HelloWorld/PycharmProjects/fullstack_s2/day 18/04 多态 封装.py", line 83, in pay
#     obj.pay(money)
#   File "C:/Users/HelloWorld/PycharmProjects/fullstack_s2/day 18/04 多态 封装.py", line 67, in pay
#     raise Exception("你没有实现pay方法")
# Exception: 你没有实现pay方法

=========================

多态:同一个对象,多种形态。在python中,没有多态,或者说,都是多态...

比如我创建一个变量a=10,此时我们知道a是一个整数类型,但是我让a='jianghongwei',此时a就变成了字符串类型

这就是多态。

#在C,c++或者java中,定义变量或者给函数传值必须指定它的类型不然就会报错
int sum(int a,int b)
{
    int c= a+b;
    return c;
}

#而在python这种弱定义类语言中,a,b是可以任意形态的
def sum(a,b):
    c=a+b
    return c

鸭子类型:在python中,你看起来像鸭子,你就是鸭子

鸭子类型是指对相同的功能取了相同的名字,这样可以方便开发,这些类型都互称鸭子类型。

比如str,tuple,list,都有index方法,这就是统一了规范

class A:
    def f1(self):
        print('In A f1...')

    def f2(self):
        print('In B f2...')

class B:
    def f1(self):
        print('In B f1...')

    def f2(self):
        print('In B f2...')


obj1=A()
obj1.f1()
obj1.f2()

obj2=B()
obj2.f1()
obj2.f2()

======================

封装:

广义的封装:实例化一个对象,给对象空间封装一些属性

狭义的封装:私有制

私有成员:私有静态字段,私有方法,私有对象属性

 

class B:
    __money=10000

class A(B):
    name = 'alex'
    __age=1000
    def func(self):
        print(self.__age)   
        print(A.__age)
        print("func...")
    def func1(self):
        pass
        # print(self.__money)

a1 = A()
a1.func()
print(a1.__age)  #实例化对象不能访问私有静态字段
print(A.__age)  #类名不能访问私有静态字段
#对于私有静态字段,类外部不能访问,内部可以访问

self是一个形式参数,当执行obj1=Foo('wupeiqi',18)的时候,self等于obj1.

          当执行obj2=Foo('alex',73)的时候,self等于obj2

就是把内容封装到obj1和obj2的对象空间中,每个空间都有name和age

 

综上所述,对于面向对象的封装来说,其实就是使用构造方法将内容封装到 对象 中,然后通过对象直接或者self间接获取被封装的内容。

 

posted @ 2019-05-17 17:55  学不会SLAM的  阅读(126)  评论(0)    收藏  举报