首页 > 其他分享 >面向对象的三大特征

面向对象的三大特征

时间:2023-10-09 21:59:43浏览次数:25  
标签:特征 self print 面向对象 三大 test class def 继承

面向对象的三大特征

  1. 封装
  2. 继承
  3. 多态
  • super和mor的使用
  • 派生

封装

封装指的就是把数据与功能都整合到一起,听起来是不是很熟悉,没错,我们之前所说的”整合“二字其实就是封装的通俗说法。
    
    什么是封装
在程序设计中,封装(Encapsulation)是对具体对象的一种抽象,即将某些部分隐藏起来,在程序外部看不到,其含义是其他程序无法调用。

要了解封装,离不开“私有化”,就是将类或者是函数中的某些属性限制在某个区域之内,外部无法调用。

为什么要封装
封装数据的主要原因是:保护隐私(把不想别人知道的东西封装起来)

继承

什么是继承?


	  继承就是一种新建类的方式, 新建出来的类我们称为是'子类或者叫派生类',被继承的类我们称为是'父类或者是基类'
      当然出来的类子类可以遗传父类的所有属性

为什么要用继承?


	  类解决了什么问题: 对象与对象之间的代码冗余问题
       继承解决了什么问题:类与类之间的代码冗余问题

怎么使用继承?


	 经典类:没有继承object类的子子孙孙类都是经典类
      新式类:继承了object类的子子孙孙类都是新式类
     """
     	再有在Python2中才区分经典类和新式类,如果是Python3的版本,所有的类都是新式类,也就是说在Python3中默认的类都是继承了object类,在Python3中没有了经典类和新式类的说法了.
     """

继承原理:


python会在MRO列表上从左到右开始查找基类,直到找到第一个匹配这个属性的类为止。
而这个MRO列表的构造是通过一个C3线性化算法来实现的。我们不去深究这个算法的数学原理,它实际上就是合并所有父类的MRO列表并遵循如下三条准则:
1.子类会先于父类被检查
2.多个父类会根据它们在列表中的顺序被检查
3.如果对下一个类存在两个合法的选择,选择第一个父类

查找顺序:



1.由对象发起的属性查找,会从对象自身的属性里检索,没有则会按照对象的类.mro()规定的顺序依次找下去,
2.由类发起的属性查找,会按照当前类.mro()规定的顺序依次找下去,

单继承

 class Parent1:
    pass


class Parent2(object):
    pass
class Sub1(Parent1):
    pass
"Sub1类继承了Parent1的类,Sub1就称为是子类,Parent1类就称为是父类或者叫基类"""
单继承:一个类只继承了一个类


单继承下的属性查找

单继承下的属性查找:先从对象自己名称空间中查找,然后去产生这个对象的类中查找,最后去继承的父类中查找.
#单继承
class Test1:
    def __f1(self):
        print('test.f1')
    def f2(self):
        print('test.f2')
        self.__f1()
class Test2(Test1):
    def __f1(self):
        print('Test.f1')

ser=Test2()
ser.f2()
test.f2
test.f1

##########
#单继承
class Test1:
    def f1(self):
        print('test.f1')
    def f2(self):
        print('test.f2')
        self.f1()
class Test2(Test1):
    def f1(self):
        print('Test.f1')

ser=Test2()
ser.f2()
test.f2
Test.f1

多继承

 class Parent1:
    pass


class Parent2(object):
    pass
class Sub2(Parent1, Parent2):
    pass
   
多继承的类: Sub2就是子类,Parent1和Parent2都是父类
一个类继承了两个或者两个以上的类就是多继承了
#多继承的优点:
一个类继承了多个父类
缺点:
1.多继承违背了人的思维习惯
2.多继承让代码的可读性差
如果必须要用多继承,应该用Mixins

多继承下的属性查找

多继承下分菱形查找和非菱形查找

菱形查找

经典类:按照深度优先的查找顺序

经典类:按照深度优先的查找顺序
 # 在python2中,未继承object的类及其子类,都是经典类
    
class G: # 在python2中,未继承object的类及其子类,都是经典类
    def test(self):
        print('from G')

class E(G):
    def test(self):
        print('from E')

class F(G):
    def test(self):
        print('from F')

class B(E):
    def test(self):
        print('from B')

class C(F):
    def test(self):
        print('from C')

class D(G):
    def test(self):
        print('from D')

class A(B,C,D):
    # def test(self):
    #     print('from A')
    pass

obj = A()
obj.test() # 如上图,查找顺序为:obj->A->B->E->G->C->F->D->object
# 可依次注释上述类中的方法test来进行验证,注意请在python2.x中进行测试

新式类:按照广度优先查找

1696858522951.png

"""python3中都是新式类,都是广度优先查询"""
class G(object):
    def test(self):
        print('from G')

class E(G):
    def test(self):
        print('from E')

class F(G):
    def test(self):
        print('from F')

class B(E):
    def test(self):
        print('from B')

class C(F):
    def test(self):
        print('from C')

class D(G):
    def test(self):
        print('from D')

class A(B,C,D):
    # def test(self):
    #     print('from A')
    pass

obj = A()
obj.test() # 如上图,查找顺序为:obj->A->B->E->C->F->D->G->object
# 可依次注释上述类中的方法test来进行验证

非菱形

class E:
    def test(self):
        print('from E')

class F:
    def test(self):
        print('from F')

class B(E):
    def test(self):
        print('from B')

class C(F):
    def test(self):
        print('from C')

class D:
    def test(self):
        print('from D')

class A(B, C, D):
    # def test(self):
    #     print('from A')
    pass


print(A.mro())
'''
[<class '__main__.A'>, <class '__main__.B'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.F'>, <class '__main__.D'>, <class 'object'>]
'''

obj = A()
obj.test() # 结果为:from B
# 可依次注释上述类中的方法test来进行验证

super和mor的使用

class popro:#父类
    star='earth'
    def __init__(self,name,age,gander):
        self.name=name
        self.age=age
        self.gender=gander
class Chinses(popro):
    nation='China'
    def __init__(self,name,age,gander,rmb):
        super().__init__(name,age,gander)
        self.rmd=rmb
    def speak_english(self):
        print(f'{self.name}有多少{self.rmd}人民币')
str=Chinses('qwe',12,'男','1233')
str.speak_english()


class A:
    def test(self):
        super().test()


class B:
    def test(self):
        print('from B')


class C(A, B):
    pass

"""mro列表是通过一个C3算法得出来的,我们无需明白底层原理,只需要知道每个类的mro列表到底是什么,然后按照这个列表去查找就行"""
# 在打印mro列表的时候,一定是从起始类开始
# c = C()
# c.test()
# print(C.mro()) # [<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>]
# print(C.__mro__)

"""mro列表,每个类都有自己的mro列表,怎么查看类的mro列表"""
a = A()
# a.test()
print(A.mro()) # (<class '__main__.A'>, <class 'object'>)
print(A.__mro__)

多态

什么是多态?
	同一种事物的多种形态
    
import abc # abstract class 抽象类   具体的Specific

class Animal(metaclass=abc.ABCMeta): # 把animal类变成了抽象类
    """父类中得方法不是为了实现逻辑的,实现功能的,而是单纯的为了限制子类的行为"""
    @abc.abstractmethod # 把抽象类中得方法变成抽象方法, 它不实现具体的功能,就是单纯的为了限制子类中的方法
    def speak(self):
        pass
    @abc.abstractmethod
    def jiao(self):
        pass


"""抽象类和普通类有什么区别? 抽象类只能够被继承、不能够被实例化"""

# Animal() # Can't instantiate abstract class Animal with abstract methods speak

鸭子类型

"""鸭子类型就是更多的关注的是对象的行为,而不是对象的类型"""

class People(Animal):
    def speak(self):pass
        # print('from People.speak')
    def jiao(self):
        pass

class Dog(Animal):
    def speak(self):
        pass


class Pig(Animal):
    def speak(self):
        pass

"""多态带来的特性:在不考虑对象类型的情况下,直接调用对象的方法或者属性"""
def animal(obj):
    return obj.speak()

animal(obj)
animal(obj1)
animal(obj2)

"""面试题:请举出Python中使用多态的例子:len"""

len('hello')
len([1,2,3,4])
len((1,2,3,4))


def len(obj):
    return obj.__len__
len('helloworld')
len([1,2,3,4])
len((1,2,3,4))

派生

派生:子类可以派生出自己新的属性,在进行属性查找时,子类中的属性名会优先于父类被查找

class popro:#父类
    star='earth'
    def __init__(self,name,age,gander):
        self.name=name
        self.age=age
        self.gender=gander
class Chinses(popro):
    nation='China'
    def __init__(self,name,age,gander,rmb):
        popro.__init__(self,name,age,gander)
        self.rmd=rmb
    def speak_english(self):
        print(f'{self.name}有多少{self.rmd}人民币')
str=Chinses('qwe',12,'男','1233')
str.speak_english()


调用super()会得到一个特殊的对象,该对象专门用来引用父类的属性,且严格按照MRO规定的顺序向后查找
class popro:#父类
    star='earth'
    def __init__(self,name,age,gander):
        self.name=name
        self.age=age
        self.gender=gander
class Chinses(popro):
    nation='China'
    def __init__(self,name,age,gander,rmb):
        super().__init__(name,age,gander)
        self.rmd=rmb
    def speak_english(self):
        print(f'{self.name}有多少{self.rmd}人民币')
str=Chinses('qwe',12,'男','1233')
str.speak_english()
这两种方式的区别是:方式一是跟继承没有关系的,而方式二的super()是依赖于继承的,并且即使没有直接继承关系,super()仍然会按照MRO继续往后查找
关于在子类中重用父类功能的这两种方式,使用任何一种都可以,但是在最新的代码中还是推荐使用super()


  好文要顶 已关注 收藏该文 无聊闲作
粉丝 - 3 关注 - 2
    我在关注他 取消关注 0 0     升级成为会员   « 上一篇: 绑定方法和非绑定方法隐藏属性和property装饰器 绑定方法 posted on 2023-10-09 21:36  无聊闲作  阅读(0)  评论(0)  编辑  收藏  举报       刷新评论刷新页面返回顶部 升级成为园子VIP会员 编辑 预览   3135afc2-7d97-47a2-d767-08db9fc0486a     自动补全

不改了 退出 订阅评论 我的博客

 

[Ctrl+Enter快捷键提交]

  【推荐】阿里云-云服务器省钱攻略 :五种权益,限时发放,不容错过   <iframe data-google-container-id="1" data-load-complete="true" frameborder="0" height="250" id="google_ads_iframe_/1090369/C1_0" marginheight="0" marginwidth="0" name="google_ads_iframe_/1090369/C1_0" scrolling="no" style="border: 0; vertical-align: bottom" title="3rd party ad content" width="300"></iframe> 编辑推荐:
· 问题排查:应用程序不再接收新请求
· 一种对数据库友好的 GUID 的变种使用方法
· BS系统的登录鉴权流程演变
· [ASP.NET Core]在 Mini-API 中注入服务
· 深入理解 python 虚拟机:生成器停止背后的魔法
阅读排行:
· 面试官随便问几个问题就知道你究竟做没做过微信支付宝支付
· .NET 数据库大数据操作方案(插入、更新、删除、查询 、插入或更新)
· C# 12 中的新增功能
· .NET Core使用SkiaSharp快速生成二维码( 真正跨平台方案)
· 起风了,NCC 云原生项目孵化计划
   

标签:特征,self,print,面向对象,三大,test,class,def,继承
From: https://www.cnblogs.com/wolongnp/p/17753252.html

相关文章

  • php面向对象
    1.简介在面向对象的程序设计(英语:Object-orientedprogramming,缩写:OOP)中,对象是一个由信息及对信息进行处理的描述所组成的整体,是对现实世界的抽象。在现实世界里我们所面对的事情都是对象,如计算机、电视机、自行车等对象的主要三个特性:1.对象的行为:可以对对象施加那些操作......
  • 特征筛选-WOE和IV
    背景在评分卡建模流程中,WOE(WeightofEvidence)常用于特征变换,IV(InformationValue)则用来衡量特征的预测能力。文章取自:风控模型—WOE与IV指标的深入理解应用代码取自:特征值筛选依据:IV值和WOE的python计算WOE和IV的应用价值WOE(WeightofEvidence)叫做证据权重,大家可以思考下为......
  • 面向过程编程 和 面向对象编程
    1.什么是面向过程变成?首先,在编程中,面向过程和面向对象是编程的两大编程思想,分别是:面向过程和面向对象,二不是一门新的技术栈.面向过程中核心是过程二字,过程就是先干什么、在干什么、最后干什么,就是机械式的思维方式优点:复杂的问题简单化、进而流程化缺点:扩展性差,牵一发而动......
  • lesson9 简易计算器-2 面向对象的属性和方法写法
     packagecom.zym.lesson9;importjavax.swing.*;importjava.awt.*;importjava.awt.event.ActionEvent;importjava.awt.event.ActionListener;importjava.awt.event.WindowAdapter;importjava.awt.event.WindowEvent;publicclassTestCalc2{publicsta......
  • 数据库的三大范式;varchar与char的区别
    一、数据库的三大范式1.1第一范式数据表中的每一列(每个字段)都不可以再拆分。例如用户表,用户地址还可以拆分成国家、省份、市,这样才符合第一范式。1.2第二范式在第一范式的基础上,非主键完全依赖于主键,而不能是依赖于主键的一部分。例如订单表里面,存储了商品信息(商品价格、商品类型),那......
  • 视频汇聚平台EasyNVR可提供的三大视频监控系统可用的楼宇对讲系统
    EasyNVR是一种可支持设备通过RTSP/Onvif流媒体协议接入的视频处理系统。该系统能够对接入的视频流进行处理,并以多种格式进行多端分发,包括RTSP、RTMP、HTTP-FLV、WS-FLV、HLS和WebRTC等多种格式。在智慧安防等视频监控场景中,EasyNVR可提供视频实时监控直播、云端录像、云存储、录像......
  • 面向对象的三个基本特征:封装、继承、多态
    封装在面向对象编程中,封装是一种将数据和相关操作封装在一个单元内部的概念。它通过将数据和方法组合在一个类中,隐藏了内部实现的细节,只暴露了必要的接口给外部使用。封装的目的是保护数据的完整性和安全性,同时提供一个清晰的接口供其他对象进行交互。通过封装,我们可以实现数据......
  • 十四天学会C++之第四天(面向对象编程基础)
    类和对象是什么?在C++中,类是一种用户定义的数据类型,它可以包含数据成员(也就是属性)和成员函数(也就是方法)。类是一种模板或蓝图,用于创建具体的对象。对象是类的实例,它是根据类的定义创建的,可以用来表示现实世界中的各种事物。对象具有类定义的属性和行为。面向对象编程思想面向对象编......
  • 类和面向对象
    一、什么是类        类(Class)是面向对象程序设计(OOP,Object-OrientedProgramming)实现信息封装的基础。类是一种用户定义的引用数据类型,也称类类型。每个类包含数据说明和一组操作数据或传递消息的函数。类的实例称为对象。        类的实质是一种引用数据类型,类......
  • Learning Hard C# 学习笔记: 5.C#中的面向对象编程
    目前除C#外流行的面向对象编程的几个语言分别是:Java,C++等;面向对象的语言都具有以下特征:封装-将客观事物封装成类,并将类内部的实现隐藏,以保证数据的完整性;继承-子类通过继承可以复用父类的代码;多态-允许将子对象赋值给父对象的一种能力.5.1封装封装指的是......