python

当前位置:首页 > python面向对象 > 当前文章

python面向对象

多态的概念统一函数接口实现多态

2021-09-26 178赞 老董笔记
每篇文章努力于解决一个问题!更多精品可移步文章底部。

  要了解多态就得先了解强类型语言和弱类型语言,如果只是学过python可能不好理解,因为没有对比就无从无感受。学过C或者其他强类型语言的话就好理解了。如果没有数据类型的概念可以查看编程语言为什么定义数据类型 

  什么是强类型定义语言

  强制数据类型定义的语言。也就是说,一旦一个变量被指定了某个数据类型,如果不经过强制转换,那么它就永远是这个数据类型了,不能被赋值成其他类型。如果你定义了一个整型变量a,那么就不能再给a赋值成字符串处理。强类型定义语言是类型安全的语言。

  什么是弱类型定义语言

  数据类型可以被忽略的语言。它与强类型定义语言相反,一个变量可以赋不同数据类型的值。

  python就是典型的弱类型语言,对于弱类型的语言来说,变量并没有声明类型,因此同一个变量完全可以在不同的时间赋不同的值。当同一个变量在调用同一个方法时,完全可能呈现出多种行为(具体呈现出哪种行为由该变量所引用的对象来决定),这就是所谓的多态(Polymorphism)。

  以函数为例理解多态

  上述的概念比较抽象,我们用下面的函数为例来帮助大家理解,定义1个函数,给这个函数的参数传递数值就打印数值,传递字符串就打印字符串。即在传参的时候不用考虑参数的数据类型。

# ‐*‐ coding: utf‐8 ‐*‐

def print_info(arg):
    print(arg,type(arg))

print_info("字符串")
print_info(123)
字符串 <class 'str'>
123 <class 'int'>

  如果是强类型语言,那么函数的参数是规定了数据类型的,传参的时候要符合参数的数据类型,传数值就只能传数值。

  在实际应用中,我们有两种方式实现多态,一是通过统一函数接口实现多态或,二是通过抽象类实现多态(最常用)

  1、统一函数接口实现多态

# -*- coding: utf-8 -*-

class Baidu(object):
    def open(self):
        print("访问百度.....")

class Google(object):
    def open(self):
        print("访问谷歌.....")

def my_open(obj_type):
    """统一调用接口"""
    obj_type.open()


if __name__ == "__main__":
    baidu_obj = Baidu()
    google_obj = Google()
    my_open(baidu_obj)
    my_open(google_obj)

访问百度.....
访问谷歌.....

  2、抽象类实现多态(最常用)

  抽象类是什么

  比如有ABC三个程序员,每个人分别操作mysql、clickhouse、redis数据库。为了统一管理,老板规定操作数据库的函数必须用同1个名字my_conncet。这样万一有人离职,别人也好接手对方的代码。

  为了做到这一点,老板事先定义1个类,在这个类里有my_connect方法,每个程序员开发时候继承这个类且自己的类必须去实现my_connect方法。老板定义的这个类就是抽象类。抽象类的作用其实就是提供一些规范。

  php可以用abstract关键字定义抽象类和抽象方法来约束继承者的行为。python中并没有抽象类的定义,但是可以手动抛出NotImplementedError异常来提示开发者。

# -*- coding: utf-8 -*-

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

    def my_connect(self):
        raise NotImplementedError("子类必须继承实现my_connect,你忘了")

class Clickhouse(Database):
    def my_connect(self):
        return '连接 Clickhouse'

class Redis(Database):
    def my_connect(self):
        return '连接 Redis!'

class Mysql(Database):
    def _connect(self):
        return '连接 Mysql!'

db1: 连接 Clickhouse
Traceback (most recent call last):
db2: 连接 Redis!
  File "D:/py3script/python66/python66.py", line 29, in 
    print(db.name + ': ' + db.my_connect())
  File "D:/py3script/python66/python66.py", line 11, in my_connect
    raise NotImplementedError("子类必须继承实现my_connect,你忘了")
NotImplementedError: 子类必须继承实现my_connect,你忘了


文章评论

多态的概念统一函数接口实现多态文章写得不错,值得赞赏