面向对象三大特性

Posted Bugbiss

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了面向对象三大特性相关的知识,希望对你有一定的参考价值。

面向对象三大特性

1.面向对象的三大特性:继承,封装,多态

封装:将一堆代码或者数据等放到一个空间中,并且可以使用

多态:同一个对象,多种形态.(python默认支持多态)

封装:根据职责将属性和方法封装到一个抽象的类中
继承:实现代码的重用,相同的代码不需要重复的编写
多态:不同的子类对象调用相同的父类方法,产生不同的执行结果

2.鸭子类型

python崇尚鸭子类型(编程思路)

class A:
    def login(self):
        print("登陆")
    def register(self):
        print("注册")
    def func1(self):
        pass
class B:
    def login(self):
        print("登陆")
    def register(self):
        print("注册")
    def func2(self):
        pass

A,B互为鸭子,虽然A,B两个类没有关系,但是统一了两个类中相似方法的方法名,
也就是在某种意义上统一的标准.

3.类的约束

约束是对类的约束
例:
    奇奇的主管让其完成一个支付功能
版本1:
class QQpay:
    def pay(self,money):
        print(f"使用qq支付了{money}")
class Alipay:
    def pay(self,money)
        print(f"使用阿里支付了{money}")
obj1 = QQpay()
obj1.pay(100)
obj2 = Alipay()
obj2.pay(200)

版本2:要做到统一接口
class QQpay:
    def pay(self,money):
        print(f"使用qq支付了{money}")
class Alipay:
    def pay(self,money):
        print(f"使用阿里支付了{money}")
def pay(obj,money):   #归一化设计,统一接口
    obj.pay(money)
obj1 = QQpay()
obj2 = Alipay()
pay(obj1,100)
pay(obj2,200)

版本3:新招了一个程序员六六,完善支付功能
class QQpay:
    def pay(self,money):
        print(f"使用qq支付了{money}")
class Alipay:
    def pay(self,money):
        print(f"使用阿里支付了{money}")
class Wechat:
    def zhifu(self.money):
        print(f"使用微信支付了{money}")
def pay(obj,money):   #归一化设计,统一接口
    obj.pay(money)
obj1 = QQpay()
obj2 = Alipay()
pay(obj1,100)
pay(obj2,200)
obj3 = Wechat()
obj3.zhifu(300)

版本4:制定约束,约定俗成,但是没有做到完全强制
class Payment:
    def pay(self,money):
        pass
class QQpay(Payment):
    def pay(self,money):
        print(f"使用qq支付了{money}")
class Alipay(Payment):
    def pay(self,money):
        print(f"使用阿里支付了{money}")
class Wechat(Payment):
    def zhifu(self.money):
        print(f"使用微信支付了{money}")
def pay(obj,money):   #归一化设计,统一接口
    obj.pay(money)
obj1 = QQpay()
obj2 = Alipay()
pay(obj1,100)
pay(obj2,200)
obj3 = Wechat()
obj3.zhifu(300)

版本5:做到强制约束
方法1:python语言惯于使用的一种约束方式,在父类主动抛出错误
方法2:借鉴于Java语言,定义抽象类的概念,做到真正的强制约束
 
方法1:
    前提:你的项目已经上线了,之前的QQpay,Alipay,以及pay函数这个接口都已经成型,如果此时新添加一个微信支付,其他的py文件引用支付功能时还是直接引用pay
class Payment:
    def pay(self,money):
        raise Exception("你的子类需要定义pay方法")
class QQpay(Payment):
    def pay(self,money):
        print(f"使用qq支付了{money}")
class Alipay(Payment):
    def pay(self,money):
        print(f"使用阿里支付了{money}")
class Wechat(Payment):
    def zhifu(self.money):       #主动报出错误
        print(f"使用微信支付了{money}")
def pay(obj,money):   #归一化设计,统一接口
    obj.pay(money)
obj1 = QQpay()
obj2 = Alipay()
obj3 = Wechat()
pay(obj1,100)
pay(obj2,200)
pay(obj3,300)

方法2:
from abc import ABCMeta,abstractmethod
#抽象类,接口类:强制指定规则(规范)
class Payment(metaclass = ABCMeta):   #指定元类
    @absstractmethod
    def pay(self,money):
        pass
class QQpay(Payment):
    def pay(self,money):
        print(f"使用qq支付了{money}")
class Alipay(Payment):
    def pay(self,money):
        print(f"使用阿里支付了{money}")
class Wechat(Payment):
    def zhifu(self.money):             #结果会报错
        print(f"使用微信支付了{money}")
   #def pay(self,money):              #强制定义,正常输出
   #    print(f"使用微信支付了{money}")
def pay(obj,money):   #归一化设计,统一接口
    obj.pay(money)
obj1 = QQpay()
obj2 = Alipay()
obj3 = Wechat()
pay(obj1,100)
pay(obj2,200)
pay(obj3,300)

4.super的深度剖析

严格按照mro的执行顺序去执行

class A:
    def f1(self):
        print("in A f1")
    def f2(self):
        print("in A f2")
class Foo(A):
    def f1(self):
        super().f2()  #super(Foo,self)
        print("is Foo f1")
obj = Foo()
obj.f1()
# in A f2
# is Foo f1
按照self对象从属于类的mro的顺序,执行Foo类的下一个类

class A:
    def f1(self):
        print("in A")
class Foo(A):
    def f1(self):
        super(Foo,self).f1()
        print("in Foo")
class Bar(A):
    def f1(self):
        print("in Bar")
class Info(Foo,Bar):
    def f1(self):
        super(Info,self).f1()
        print("in Info f1")
print(Info.mro()) #[Info,Foo,Bar,A,object]
obj = Info()
obj.f1()
#in Bar
#in Foo
#in Info f1


class A:
    def f1(self):
        print("in A")
class Foo(A):
    def f1(self):
        super().f1()
        print("in foo")
class Bar(A):
    def f1(self):
        print("in Bar")
class Info(Foo,Bar):
    def f1(self):
        super(Foo,self).f1()
        print("in Info f1")
obj = Info()
obj.f1()
#in Bar
#in Info f1

5.带颜色的print

书写格式:
    print('\033[1;35;0m字体变色,但无背景色 \033[0m')
#开头部分的三个参数:显示方式;前景色;背景色;是可选参数,可以只写其中的某一个,另外由于表示三个参数不同含义的数值都是唯一的没有重复的,所以三个参数的书写先后顺序没有固定要求,系统都能识别,但是,建议按照默认的格式规范书写,
对于结尾部分,其实也可以省略,但是为了书写规范,建议\033[开头,\033[0m结尾.
      
                                       
                                       
数值表示的参数含义:

显示方式: 0(默认值)、1(高亮)、22(非粗体)、4(下划线)、24(非下划线)、 5(闪烁)、25(非闪烁)、7(反显)、27(非反显)
前景色: 30(黑色)、31(红色)、32(绿色)、 33(黄色)、34(蓝色)、35(洋 红)、36(青色)、37(白色)
背景色: 40(黑色)、41(红色)、42(绿色)、 43(黄色)、44(蓝色)、45(洋 红)、46(青色)、47(白色)
 
常见开头格式:
\033[0m        默认字体正常显示,不高亮
\033[32;0m     红色字体正常显示
\033[1;32;40m  显示方式: 高亮    字体前景色:绿色  背景色:黑色
\033[0;31;46m  显示方式: 正常    字体前景色:红色  背景色:青色
     
     
举例:
print('\033[1;35;0m字体变色,但无背景色 \033[0m')  # 有高亮
print('\033[1;45m 字体不变色,有背景色 \033[0m')  # 有高亮
print('\033[1;35;46m 字体有色,且有背景色 \033[0m')  # 有高亮
print('\033[0;35;46m 字体有色,且有背景色 \033[0m')  # 无高亮

以上是关于面向对象三大特性的主要内容,如果未能解决你的问题,请参考以下文章

面向对象 三大特性 五大原则

面向对象三大特性五大原则

面向对象三大基本特性,五大基本原则

面向对象三大基本特性,五大基本原则

面向对象三大基本特性,五大基本原则

面向对象三大基本特性,五大基本原则