Python 面向对象(三)

2023-11-15

6.3 多态

  • 多态就是同一个对象在不同情况下有不同的状态出现

  • 多态不是语法,是一种设计思想

  • 多态性:一种调用方式,不同的执行效果

  • 多态:同一事物的多种形态,动物分为人类、猪类、狗类

  • 多态和多态性

  • Mixin设计模式

  • 我们使用多继承语法来实现Mixin

  • 使用Mixin实现多继承的时候非常小心

    • 首先他必须表示某一单一功能,而不是某个物品
    • 职责必须单一,如果有多个功能,则写多个Mixin
    • Mixin不能依赖于子类的实现
    • 子类即使没有继承这个Mixin类,也能照样工作,只是缺少了某个功能
  • 优点

    • 使用Mixin可以在不对类进行任何修改的情况下,扩充功能
    • 可以方便的组织和维护不同功能组件的划分
    • 可以根据需要任意调整功能类的组合
    • 可以避免创建很多新的类,导致类的继承混乱

7. 类相关函数

  • issubclass:检测一个类是否是另一个类的子类
  • isinstance:检测一个对象是否是一个类的实例
  • hasattr:检测一个对象是否有成员xxx
  • getattr:get attribute
  • setattr:set attribute
  • delattr:delete attribute
  • dir:获取对象的成员列表
class A():
    pass

class B(A):
    pass

class C(B,A):
    pass

print(A.__mro__)
print(B.__mro__)
复制代码
(<class '__main__.A'>, <class 'object'>)
(<class '__main__.B'>, <class '__main__.A'>, <class 'object'>)
复制代码
# 多继承的例子
# 子类可以直接拥有父类的属性和方法,私有属性和方法除外
class Fish():
    def __init__(self, name):
        self.name = name
        
    def swim(self):
        print("I am swimming......")
        
class Bird():
    def __init__(self, name):
        self.name = name
        
    def fly(self):
        print("I am flying.....")
        
class Person():
    def __init__(self, name):
        self.name = name
        
    def worked(self):
        print("Working......")
        
class SuperMan(Person, Bird, Fish):
    def __init__(self, name):
        self.name = name    
        
s = SuperMan("a")
s.fly()
s.swim()
s.worked()


# 单继承的例子

class Student(Person):
    def __init__(self, name):
        self.name = name
        
stu = Student("a")
stu.worked()
复制代码
I am flying.....
I am swimming......
Working......
Working......
复制代码
# 菱形继承问题
class A():
    pass
class B(A):
    pass
class C(A):
    pass

class D(B,C):
    pass
复制代码
# 构造函数例子

class Person():
    # 对Person类进行实例化的时候
    # 姓名要确定
    # 年龄得确定
    # 地址肯定有
    def __init__(self):
        self.name = "NoName"
        self.age = 18
        self.address = "Studentwhonheim"
        print("In init func")

# 实例化一个人
p = Person() 
复制代码
In init func
复制代码
# 构造函数的调用顺序 - 1
# 如果子类没有写构造函数,则自动向上查找,直到找到为止
class A():
    def __init__(self):
        print("A")
class B(A):
    def __init__(self):
        print("B")

class C(B):
    pass

# 此时,首先C的构造函数
# 如果没有,则向上按照MRO顺序查找父类的构造函数,直到找到为止
c = C()
复制代码
A
复制代码
# 构造函数的调用顺序 - 2
class A():
    def __init__(self):
        print("A")
class B(A):
    def __init__(self, name):
        print("B")
        print(name)

class C(B):
    pass

# 此时,首先C的构造函数
# 如果没有,则向上按照MRO顺序查找父类的构造函数,直到找到为止
# 此时,会出现参数结构不对应错误
c = C()
复制代码
---------------------------------------------------------------------------

TypeError                                 Traceback (most recent call last)

<ipython-input-11-40c74f7fff64> in <module>
     14 # 如果没有,则向上按照MRO顺序查找父类的构造函数,直到找到为止
     15 # 此时,会出现参数结构不对应错误
---> 16 c = C()


TypeError: __init__() missing 1 required positional argument: 'name'
复制代码
# 构造函数的调用顺序 - 3
class A():
    def __init__(self):
        print("A")
class B(A):
    def __init__(self, name):
        print("B")
        print(name)

class C(B):
    # C中想扩展B的构造函数
    # 即调用B的构造函数后再添加一些功能
    # 有两种方法实现
    
    '''
    # 第一种是通过父类名调用
    def __init__(self, name):
        # 首先调用父类构造函数
        B.__init__(self, name)
        # 其次,再增加自己的功能
        print("这是C中附加的功能")
    '''
    
    # 第二种,使用super调用
    def __init__(self, name):
        # 首先调用父类构造函数
        super(C, self).__init__(name)
        # 其次,再增加自己的功能
        print("这是C中附加的功能")

# 此时,首先C的构造函数
# 如果没有,则向上按照MRO顺序查找父类的构造函数,直到找到为止
# 此时,会出现参数结构不对应错误
c = C("我是C")
复制代码
B
我是C
这是C中附加的功能
复制代码
# Mixin案例

class Person():
    name = "ruochen"
    age = 18
    
    def eat(self):
        print("EAT......")
        
    def drink(self):
        print("DRINK......")
    
    def sleep():
        print("SLEEP......")

class Teacher(Person):
    def work(self):
        print("Work")
        
class Student(Person):
    def study(self):
        print("Study")
        
class Tutor(Teacher, Student):
    pass

t = Tutor()

print(Tutor.__mro__)
print(t.__dict__)
print(Tutor.__dict__)

print("*" * 20)
class TeacherMixin():
    def work(self):
        print("Work")
        
class StudentMixin():
    def study(self):
        print("Study")
        
class TutorM(Person, TeacherMixin, StudentMixin):
    pass

tt = TutorM()
print(TutorM.__mro__)
print(tt.__dict__)
print(TutorM.__dict__)
复制代码
(<class '__main__.Tutor'>, <class '__main__.Teacher'>, <class '__main__.Student'>, <class '__main__.Person'>, <class 'object'>)
{}
{'__module__': '__main__', '__doc__': None}
********************
(<class '__main__.TutorM'>, <class '__main__.Person'>, <class '__main__.TeacherMixin'>, <class '__main__.StudentMixin'>, <class 'object'>)
{}
{'__module__': '__main__', '__doc__': None}
复制代码
# issubclass
class A():
    pass

class B(A):
    pass

class C():
    pass

print(issubclass(B, A))
print(issubclass(C, A))
print(issubclass(C, object))
复制代码
True
False
True
复制代码
# isinstance
class A():
    pass

a = A()

print(isinstance(a, A))
print(isinstance(A, A))
复制代码
True
False
复制代码
# hasattr
class A():
    name = "NoName"

a = A()
print(hasattr(a, "name"))
print(hasattr(a, "age"))
复制代码
True
False
复制代码
# help案例
# 我想知道setattr的具体用法
help(setattr)
复制代码
Help on built-in function setattr in module builtins:

setattr(obj, name, value, /)
    Sets the named attribute on the given object to the specified value.
    
    setattr(x, 'y', v) is equivalent to ``x.y = v''
复制代码
# dir 案例
class A():
    pass
# dir(A)
a = A
dir(a)
复制代码
['__class__',
 '__delattr__',
 '__dict__',
 '__dir__',
 '__doc__',
 '__eq__',
 '__format__',
 '__ge__',
 '__getattribute__',
 '__gt__',
 '__hash__',
 '__init__',
 '__init_subclass__',
 '__le__',
 '__lt__',
 '__module__',
 '__ne__',
 '__new__',
 '__reduce__',
 '__reduce_ex__',
 '__repr__',
 '__setattr__',
 '__sizeof__',
 '__str__',
 '__subclasshook__',
 '__weakref__']

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python 面向对象(三) 的相关文章

随机推荐

  • FRP-内网穿透-frps服务端-WEB管理面板-Dashboard

    FRP 内网穿透 frps服务端 WEB管理面板 Dashboard 1 启动云服务端frps 2 修改配置文件 3 启动 刷新服务 4 异常处理 5 SSH web服务 管理界面 DNS Unix 文件服务 https 安全暴露 点对点内
  • C/C++编译时的Link.EXE错误问题与解决方法

    C C 编译时的Link EXE错误问题与解决方法 作者 Acharlix 1 LIBCD lib wincrt0 obj error LNK2001 unresolved external symbol WinMain 16 问题描述er
  • 第二章排错的工具:调试器Windbg(下)

    感谢博主 http book 51cto com art 200711 59874 htm 2 2 读懂机器的语言 汇编 CPU执行指令的最小单元 2 2 1 需要用汇编来排错的常见情况 汇编是CPU执行指令的最小单元 下面一些情况下 汇编
  • ES Module的基本用法

    import 导入 6种 export app js import from 必须在文件的最顶层 最外层的作用域 路径可以是相对路径 或根目录下的绝对路径 或应完整的url 说明可以引用cdn上的一些文件 但不能以字母开头 js会以为是加载
  • 【Unity开源项目精选】ML-Agents:给你的游戏加入AI

    洪流学堂 让你快人几步 你好 我是你的技术探路者郑洪智 你可以叫我大智 今天给你分享一个Unity开源项目 希望对你有帮助哦 ML Agents Unity机器学习代理工具包 ML Agents 是一个开源项目 它使游戏和仿真能够作为培训智
  • Go语言的TCP和HTTP网络服务基础

    目录 TCP Socket 编程模型 Socket读操作 HTTP网络服务 HTTP客户端 HTTP服务端 TCP IP 网络模型实现了两种传输层协议 TCP 和 UDP 其中TCP 是面向连接的流协议 为通信的两端提供稳定可靠的数据传输服
  • Dump文件分析 - PDB不匹配的情景

    Dump文件分析 PDB不匹配的情景 WinDbg 一 运行程序产生dump 二 WinDbg 基于地址偏移量计算异常地址 方法一 三 WinDbg 强制加载pdb 方法二 参考 总结 WinDbg Windows 调试程序 WinDbg
  • Exps on March 23rd

    电话 固定电话 telephone手机 cellphone mobilephone无绳电话 cordless phone公共电话 paying phone长途电话 long distance call国际电话 international c
  • 「远程开发」VSCode使用SSH远程linux服务器 - 公网远程连接

    文章目录 前言 视频教程 1 安装OpenSSH 2 vscode配置ssh 3 局域网测试连接远程服务器 4 公网远程连接 4 1 ubuntu安装cpolar内网穿透 4 2 创建隧道映射 4 3 测试公网远程连接 5 配置固定TCP端
  • Linux安装mysql5.7.23设置密码问题

    问题 安装mysql没有设置密码导致无法进入mysql 系统 ubuntu 18 04 mysql版本 mysql Ver 14 14 Distrib 5 7 23 for Linux x86 64 using EditLine wrapp
  • 【Linux】HTTPS协议

    目录 前言 HTTPS协议原理 1 概念 2 加密和解密 3 常见加密方式 3 1 对称加密 3 2 非对称加密 4 数据摘要和数据指纹 5 HTTPS工作原理 5 1 方案一 仅对称加密 5 2 方案二 仅非对称加密 5 3 方案三 双方
  • pandas---数据处理(csv文件)

    近期在弄一个项目的前期数据 所以总结了一下 内容如下 以下以csv文件为例 1 DataFrame常用操作 1 1 DataFrame去除空行 1 对于一般空行 2 对于列表式 list 空行 1 2 数据的填充 1 表格中填充0 1 3
  • Springboot actuator端点配置与及基本说明2.2.4版

    pom配置
  • 数据结构与算法之美(01)为什么要学习数据结构和算法?

    你是不是觉得数据结构和算法 跟操作系统 计算机网络一样 是脱离实际工作的知识 可能除了面试 这辈子也用不着 尽管计算机相关专业的同学在大学都学过这门课程 甚至很多培训机构也会培训这方面的知识 但是据我了解 很多程序员对数据结构和算法依旧一窍
  • 解决git中出现的“fatal ‘xxxx‘ does not appear to be a git repository”错误的方法

    今天来分享一下我在使用git中出现的一个错误提示 话不多说 我们直接来分析 这个错误是我在通过SSH方式pull远程仓库时候出现的 错误提示如下 fatal xxx 你的仓库别名 does not appear to be a git re
  • 使用yum命令安装jdk1.8没有jps命令

    问题 使用yum命令安装jdk1 8后 不能使用jps 这是由于没有openjdk devel这个包 使用yum命令下载 yum install java 1 8 0 openjdk devel x86 64 下载完成之后就可以使用jps命
  • Leetcode 刷题笔记(二十八) ——动态规划篇之子序列问题:连续子序列和不连续子序列

    文章目录 系列文章目录 前言 题录 53 最大子数组和 674 最长连续递增序列 300 最长递增子序列 718 最长重复子数组 1143 最长公共子序列 1035 不相交的线 系列文章目录 一 数组类型解题方法一 二分法 二 数组类型解题
  • LSTM原理及实现

    LSTM网络 LSTM核心思想 逐步理解LSTM 遗忘门 输入门 输出门 LSTM变体 多层LSTM LSTM实现手写数字 设置LSTM参数 初始化权值参数 训练 参考资料 前面我们介绍了RNN 现在我们来介绍一种特殊的RNN结构 LSTM
  • 如何用python编写程序打开csv格式文件

    目录 1 用pandas库打开 2 用python内置函数打开 1 用pandas库打开 用如下例子说明 import pandas as pd import os import csv data dir D a user file fna
  • Python 面向对象(三)

    6 3 多态 多态就是同一个对象在不同情况下有不同的状态出现 多态不是语法 是一种设计思想 多态性 一种调用方式 不同的执行效果 多态 同一事物的多种形态 动物分为人类 猪类 狗类 多态和多态性 Mixin设计模式 主要采用多继承方式对类的