首页 > 其他分享 >22. 面向对象之多态

22. 面向对象之多态

时间:2024-08-16 21:37:57浏览次数:12  
标签:run 22 对象 self 绑定 多态 面向对象 方法 def

1. 多态

1.1 概念

多态指的是一类事物有多种形态

比如动物有多种形态:人、猴、鸭

1.2 代码示例

from abc import ABC, abstractmethod

# 对于程序来说,定义一个基类可以有多个子类
class Animal(ABC):
    @abstractmethod
    def run(self):
        pass

    @abstractmethod
    def speak(self, name):
        print(f'{name}正在说话')

# 第一种形态:人
class Person(Animal):
    def run(self):
        print('可以润')

    def speak(self, name):
        print(f'{name}正在说话')

# 第二种形态:猴
class Monkey(Animal):
    def run(self):
        print('猴哥也可以润')

# 第三种形态:鸭子
class Duck(Animal):
    def run(self):
        print('鸭子也可以润')

1.3 多态性

动态绑定:在程序运行的过程中,根据对象的类型,动态的将方法进行绑定

动态多样性:动态绑定在继承背景下的特性就叫动态多态性

静态多样性:如任何类型都可以用运算符加号+  进行运算

from abc import ABC, abstractmethod

# 同一类事物:动物
class Animal(ABC):
    @abstractmethod
    def run(self):
        pass

# 第一种形态:人
class Person(Animal):
    def run(self):
        print('可以润')

# 第二种形态:猴
class Monkey(Animal):
    def run(self):
        print('猴哥也可以润')

# 第三种形态:鸭子
class Duck(Animal):
    def run(self):
        print('鸭子也可以润')

person1 = Person()
monkey1 = Monkey()
duck1 = Duck()

# person1、monkey1、duck1都是动物,只要是动物肯定有run方法
# 于是可以不用考虑三个对象的具体是声明类型,而直接使用
person1.run()
monkey1.run()
duck1.run()

# 更进一步,可以定义一个统一的接口来使用
def func(obj):
    obj.run()

python中一切皆对象,本身就支持多态性

# 在不考虑对象类型的情况下统计对象的长度
a.__len__()
b.__len__()
c.__len__()

# python内置了一个统一的接口
len(a)
len(b)
len(c)

2. 鸭子类型

鸭子类型(duck typing)是一种编程风格,不是一个真实存在的约束关系,是一种普遍的规范

看起来像、声音像、走起路来像鸭子,那么它就是鸭子

# 二者看起来都像文件,因而就可以当文件一样去用,然而它们并没有直接的关系
class Txt:  # Txt类有两个与文件类型同名的方法,即read和write
    def read(self):
        pass

    def write(self):
        pass


class Video:  # Video类也有两个与文件类型同名的方法,即read和write
    def read(self):
        pass

    def write(self):
        pass

3. 绑定方法和非绑定方法

3.1 概念

绑定方法(动态方法):

绑定给谁,谁来调用就自动将它本身当作第一个参数传入

绑定给类的方法、绑定给对象的方法

 

非绑定方法(静态方法):

既不绑定给类也不绑定给对象

 

一句话概括:方法即函数,可以理解为绑定函数、非绑定函数

3.2 绑定给对象的方法

概述:

  绑定给对象的方法就是在类内部直接定义的方法------即在类内部写的函数,写的时候自动带上self参数

  特点就是会自动补全self参数

  对象调用绑定给对象的方法的时候不需要传入self参数,类调用对象的绑定方法的时候需要传入self参数(对象名)

class Student:

    def __init__(self, name):
        self.name = name

    def run(self):  # 绑定给对象的方法就是在类内部定义的方法,自动补全self对象
        print(f'这是run方法,{self.name}可以润')


stu1 = Student(name='lavigne')  # 实例化得到的对象

# (1)对象调用对象的绑定方法
#    不需要传递self参数,在对象调用对象的绑定方法的时候会自动将对象作为self参数传进去
stu1.run()  # 这是run方法,lavigne可以润

# (2)类调用对象的绑定方法
#    必须主动给self传入一个对象
stu2 = Student(name='avril')
# Student.run()  # 报错  TypeError: Student.run() missing 1 required positional argument: 'self'
Student.run(stu1)  # 这是run方法,lavigne可以润
Student.run(stu2)  # 这是run方法,avril可以润

3.3 绑定给类的方法  classmethod

类在使用时会将类本身当作参数传给类方法的第一个参数(即便是对象来调用也会将类当作第一个参数传入)

classmethod把类中的函数定义成类方法

class Student:
    def __init__(self, name):
        self.name = name

    @classmethod
    def read(cls):  # 绑定给类的方法,必须用classmethod装饰器,并且在定义函数的时候默认补全参数cls
        print(f'当前是绑定给类的read方法:{cls}')


# (1)对象调用绑定给类的方法
#    不需要传入cls参数
#    会自动识别实例化当前对象的类,直接将类传入
stu1 = Student(name='lavigne')
stu1.read()  # 当前是绑定给类的read方法:<class '__main__.Student'>

# (2)类调用绑定给类的方法
#    不需要传入cls参数
#    默认将当前类作为cls的默认参数传入
Student.read()  # 当前是绑定给类的read方法:<class '__main__.Student'>

总结:

  定义绑定给类的方法的时候,必须用装饰器@classmethod;类似于绑定给对象的方法函数,会自动补全参数cls

  对象调用绑定给类的方法,不需要传入cls参数

  类调用绑定给类的方法,不需要传入cls参数

3.4 非绑定方法  staticmethod

在类内部用staticmethod装饰的函数即非绑定方法,就是普通函数

staticmethod既不绑定给类,也不绑定给对象,在定义函数的时候和普通函数一样不会补全任何默认参数

 

标签:run,22,对象,self,绑定,多态,面向对象,方法,def
From: https://www.cnblogs.com/hbutmeng/p/18363425

相关文章

  • CSP22
    题面T1放了个啥?T1读假了好几遍首先一行不能为空,一列的空位必须相邻,一列可以为空点击查看代码#include<bits/stdc++.h>#definespeed()ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);#definelllonglong#definepbpush_back#defineullunsignedlonglong......
  • 『模拟赛』暑假集训CSP提高模拟22
    Rank非常好重测,使我Rank--A.法阵原[CF1503E]2-Coloring出题人注:原题3100,张口放T1一眼高难度题,于是果断开始暴力打表,但我的打表程序十分暴力,跑\(n=6,m=9\)的点就已经开始硬控了,遂只拿到30pts。打表就不用放了吧,等我咕咕正解。B.连通块同[yLCPC2024]F.PANDORA......
  • 热血江湖:发布网www.SouFu6.cn,新开热血江湖来袭!22
           热血江湖:发布网www.SouFu6.cn,新开热血江湖来袭!141       私服SF有着许多独特的品质,使其与正版游戏区别开来。首先,私服SF通常会提供大量的游戏元素和功能,比如新增的职业、装备、地图等,让玩家能够体验到更丰富的游戏内容。其次,私服SF还通常会......
  • 在macOS上运行SQL Server 2022进行数据库开发
    有很多工具可用于在macOS上使用SQL进行开发,包括VSCode的mssql扩展和独立但舒适的AzureDataStudio。作为一名开发人员,您可能听说过AzureSQL数据库模拟器,并且您肯定听说过在容器中部署SQL。最近,在arm64(M1/M2)Mac上本地运行SQL容器的新选项变得可用,它使运行完整的SQLServer映......
  • 暑假集训csp提高模拟22
    赛时rank24,T120,T266,T30,T410T1*3100,T2逆天trick,T3抽象题面,T4也挺抽象反正是暴力专场T1、T3、T4太抽象了,不会,直接挂的官方题解可能模拟赛难度为强紫+弱紫/强蓝+紫+紫?调了一个最简单的T2,学习一下这个trick。我树套树还没写玩呢T1法阵2-Coloring原题3100,张口放......
  • day22 Java基础——方法(干货)
    day22Java基础——方法在Java中,方法是一段组织好的、可重复使用的代码块,用于执行一个特定的操作。方法提供了一种封装代码的方式,使得代码模块化,便于管理和重用。以下是关于Java中方法的一些基本介绍:文章目录day22Java基础——方法1.方法的定义2.方法的调用2.1方法......
  • Ubuntu22.04 安装及卸载 Docker --需自行找加速站
    Ubuntu22.04DockerEngine的安装及卸载如果没有合适的docker镜像加速站,本文就不太重要了。当前时间2024.8.16参照Docker官网描述的Ubuntu安装方式。文中所有shell均来自官网,并进行了本地化修改。当前操作适用于:UbuntuNoble24.04(LTS)UbuntuJammy22.04(LTS)......
  • AGC022E Median Replace
    传送门题意:给定长度为奇数的01?串,问多少种填法使得串可以变成\(1\)。一次操作定义为把连续三个数变成它们的中位数。这种计数题可以先考虑怎么判定一个串是否可以变成\(1\),称作合法。根据人类智慧,可以想到\(000S\)合法\(\iff\)\(0S\)合法,进而启示我们考虑串\(S\)的......
  • win10安装wsl+Ubuntu22.04+docker记录
    1.安装wsl2.0,开启hyper-V虚拟化2.在微软商店下载Ubuntu22.04并进行安装打开命令提示符或PowerShell作为管理员//设置WSL默认版本wsl--set-default-version2//查看状态名称wsl-l-v//停止wsl--terminateUbuntu-22.04//启动wsl-dUbuntu-22.04wsl运行一段时......
  • JAVA面向对象|(一)Java接口 Interface
    目录一、概述(一)概念(二)特点(三)接口VS类二、使用 (一)类实现接口(二)接口间的多继承 演示(三)标记接口 1.标记接口 定义2.标记接口 作用3.标记接口 应用参考文章:Java接口_w3cschool一、概述(一)概念        Java接口是一种抽象类型,是一系列方法的声明......