python面向对象 : 抽象类(接口类),多态,封装(私有制封装)

摘要:
您可以将呼叫者设置为相同。classAlipay:使用支付宝打印(“支付%s元”%self.money)classJdpay:self。money=moneydefpay(self):打印(使用JD“支付%s元”%self.money)defpay

一. 抽象类(接口类)

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

  从设计角度去看, 如果类是从现实对象抽象而来的, 那么抽象类就是基于类抽象而来的。

    从实现角度来看, 抽象类与普通类的不同之处在于: 抽象类中有抽象方法, 该类不能被实例化, 只能被继承, 且子类必须实现抽象方法. 这一点与接口有点类似, 但其实是不同的. 

  实现不同的支付方式:

  

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

    def alipay(self):
        print('使用支付宝支付了%s元' % self.money)


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

    def jdpay(self):
        print('使用京东支付了%s元' % self.money)


a = Alipay(500)
a.alipay()  # 使用支付宝支付了500元
j = Jdpay(200)
j.jdpay()  # 使用京东支付了200元

虽然都实现了支付,但是两个支付都是相同的功能,但调用方却不一样,可以把调用方设置一样.

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()  


a = Alipay(500)
pay(a)  # 调用函数pay,把对象a穿进去,并执行函数语句
j = Jdpay(200)
pay(j)  # 调用函数pay,把对象j穿进去,并执行函数语句
# 调用方都是函数pay 归一化设计

  虽然设置了一个pay函数,但是有可能后面接手你程序的人并不会发现,含是按照第一种的方法实现新的支付方式,所以我们要确保在之后添加的类中要有pay函数.

from abc import ABCMeta, abstractmethod  # 从abc模块引进ABCMeta,abstractmethod


class Allpay:
    @abstractmethod  # 在需要制定模板的函数上写一句
    def pay(self):   # 制定规范,子类中必须有pay方法,否则报错
        pass


class Alipay(Allpay):
    def __init__(self, money):
        self.money = money

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


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

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


class Wechatpay(Allpay):
    def __init__(self, money):
        self.money = money

    # def wechatpay(self):  #函数名不是pay会报错
    #     pass
    def pay(self):
        print('使用微信支付了%s元' % self.money)


def pay(obj):
    obj.pay()


a = Alipay(500)
pay(a)  # 使用支付宝支付了500元
j = Jdpay(200)
pay(j)  # 使用京东支付了200元
w = Wechatpay(700)
pay(w)  # 使用微信支付了700元

二. 多态

  python不支持多态, 也不用支持多态,因为python处处是多态, python是一种多态语言, 参数在传入之前是无法确定参数类型的. 崇尚鸭子类型

   鸭子类型 : 看着像鸭子,他就是鸭子, 下面的类有相同功能的方法, 都互称为鸭子.

class Str:
    def index(self):
        pass

class List:
    def index(self):
        pass

class Tuple:
    def index(self):
        pass

三. 封装

  封装,顾名思义就是将内容封装到某个地方,以后再去调用被封装在某处的内容。所以,在使用面向对象的封装特性时,需要:将内容封装到某处, 然后从某处调用被封装的内容.

  封装分为广义的封装和狭义的封装

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

class Animal:
    def __init__(self,name,sex,age):
        self.name = name  #广义的封装
        self.age = age
        self.sex = sex

  狭义的封装: 私有制.

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

  私有静态字段:

  在类外部引用私有静态字段

class Pay:
    __money = 1000  # 定义私有静态变量__money

    def pay(self):
        pass


p = Pay()
p.__money  # 报错,在类外部对象无法引用私有静态字段__money
Pay.__money  # # 报错,在类外部类名无法引用私有静态字段__money

  在类内部引用私有静态字段

class Pay:
    __money = 1000  # 定义私有静态变量__money

    def pay(self):
        print(p.__money)  # 在类内部对象可以引用私有静态字段__money
        print(Pay.__money)  # 在类内部类名可以引用私有静态字段__money

p = Pay()
p.pay()
# 1000
# 1000

  在子类引用私有静态字段

class Money:
    __money = 1000  # 定义私有静态变量__money


class Pay(Money):

    def pay(self):
        pass
        print(p.__money)  # 在子类内部对象不能引用父类的私有静态字段__money
        print(Pay.__money)  # 在子类内部类名不能引用父类的私有静态字段__money


p = Pay()
# p.__money  # 子类的对象无法引用父类的私有静态字段__money
# Pay.__money  # 子类名无法引用父类的私有静态字段__money
p.pay()

  总结:对于私有静态字段来说,只能在本类中内部访问,类的外部,派生类(子类)均不可访问.

# 可以访问,但是工作中千万不要用 : '__类名私有静态字段'
# print(Pay._Pay__money)
# print(Pay.__dict__)

  私有方法:对于私方法来说,只能在本类中内部访问,类的外部,派生类(子类)均不可访问.

class B:
    def __f1(self):
        print('777')

class A(B):
    def __func(self):
        print('666')

    def func1(self):
        self.__func()  # 类内部可以访问
        self.f1()  # 子类无法访问父类的私有方法

a = A()
# a.__func()  # 类外部对象不能访问
# A.__func()  # 类外部类名不能访问
a.func1()
# 666
# 666

  私有属性

class A:

    def __init__(self,name,age,weight):

        self.name = name
        self.__age = age
        self.__weight = weight
    def func(self):
        print(self.__age)  #类内可以引用私有属性
a1 = A('jsck',18,45)
print(a1.name)
print(a1.__dict__)  # {'name': 'jsck', '_A__age': 18, '_A__weight': 45}
# print(a1.__age)  # 类外无法引用私有属性
a1.func()

  面试题

class Parent:
    def __func(self):
        print('in Parent func')

    def __init__(self):  # 自动执行__init__方法
        self.__func()  # self.__func() =>> self.__Parent__func


class Son(Parent):
    def __func(self):
        print('in Son func')


son1 = Son()  # in Parent func

免责声明:文章转载自《python面向对象 : 抽象类(接口类),多态,封装(私有制封装)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇解决正则表达式中用中文匹配的方法linux(centos7) 常用命令和快捷键 持续验证更新中...下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

静态代理和动态代理的区别

什么是静态代理: 打一个最简单的比方,我现在想要学习,那么就必须得把书包拿过来,把书掏出来,准备好纸笔,然后开始学习,等学完了我还得收拾书,把书塞回书包里,还得整理一下书包,这是一个完整的学习的过程,但是我很懒,不想动弹,只想学习,那可能就得让妈妈帮我把书包拿过来,把书打开,我只管学习就好了,学完以后,妈妈再帮我把书整理好放回去.(我这是打个什么破比方.....

spider爬虫练习,爬取顶点小说网,小说内容。

------------恢复内容开始------------ 我这里练习爬虫的网站是顶点小说网,地址如下: https://www.booktxt.net/ 我这里以爬取顶点小说网里面的凡人修仙传为例子: 首先观察界面: 第一章: 第二章: 由上面可得出规律,每点一次下一章,url后面的数字就会自动加1。 爬虫主要分为3步: 第一步:构建url列表...

Java集合(五) Set 添加元素

Java中Set集合是如何实现添加元素保证不重复的?   Set集合是一个无序的不可以重复的集合。今天来看一下为什么不可以重复。   Set是一个接口,最常用的实现类就是HashSet,以HashSet为例。   HashSet类实现了Set接口, 其底层其实是包装了一个HashMap去实现的。HashSet采用HashCode算法来存取集合中的元素,因此...

Python 并发编程(一)之线程

常用用法 t.is_alive() Python中线程会在一个单独的系统级别线程中执行(比如一个POSIX线程或者一个Windows线程)这些线程将由操作系统来全权管理。线程一旦启动,将独立执行直到目标函数返回。可以通过查询一个线程对象的状态,看它是否还在执行t.is_alive() t.join() 可以把一个线程加入到当前线程,并等待它终止Python...

Python接口自动化(九) cookie登录,session保持,参数关联接口

cookie登录博客园,session保持,发布新博客,报错:{'errors': ['用户账号不匹配,请备份未提交的内容并检查当前登录账号'], 'type': 0} import requestsimport jsonimport datetimeheaders={"User-Agent":"Mozilla/5.0 (Windows NT 10.0;...

c#FileStream文件读写

//C#文件流写文件,默认追加FileMode.Append             string msg = "okffffffffffffffff";            byte[] myByte = System.Text.Encoding.UTF8.GetBytes(msg);            using (FileStream fsWr...