面向对象之多态,多态性,反射,以及基于反射的可拔插设计

多态

什么多态?

多态指的是一类事物有多种形态,比如
动物有多种形态:人,狗,猪

>>例如
import abc  #创建抽象类 导入abc

class Animal(metaclass=abc.ABCMeta): #同一类事物:动物
    @abc.abstractmethod              #归一化设计
    def talk(self):
        pass

class People(Animal): #动物的形态之一:人
    def talk(self):
        print('say hello')

class Dog(Animal): #动物的形态之二:狗
    def talk(self):
        print('say wangwang')

class Pig(Animal): #动物的形态之三:猪
    def talk(self):
        print('say aoao')

文件也有多态性比如:
文件有多种形态:文本文件,可执行文件
import abc
class File(metaclass=abc.ABCMeta): #同一类事物:文件
    @abc.abstractmethod
    def click(self):
        pass

class Text(File): #文件的形态之一:文本文件
    def click(self):
        print('open file')

class ExeFile(File): #文件的形态之二:可执行文件
    def click(self):
        print('execute file')

多态性

1.什么是多态性

多态性是指在不考虑实例类型的情况下使用实例,多态性分为 静态多态性 和 动态多态性

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

动态多态性如下实例:

peo=People()
dog=Dog()
pig=Pig()

#peo、dog、pig都是动物,只要是动物肯定有talk方法
#于是我们可以不用考虑它们三者的具体是什么类型,而直接使用
peo.talk()
dog.talk()
pig.talk()

#更进一步,我们可以定义一个统一的接口来使用,动态的执行不同动物的talk方法
def func(obj):
    obj.talk()

二 为什么要用多态性(多态性的好处)

1.增加了程序的灵活性>>>
  以不变应万变,不论对象千变万化,使用者都是同一种形式去调用,如func(animal)

2.增加了程序额可扩展性>>>
 通过继承animal类创建了一个新的类,使用者无需更改自己的代码,还是用func(animal)去调用
class H2O: #水有多种形态冰,液态水,水蒸气
def init(self, name, temp):
self.name = name
self.temp = temp

def turn_active(self):
    if self.temp < 0:
        print("我是 %s 我已经变成冰了!" % self.name)
    elif self.temp > 0 and self.temp < 100:
        print("我是液水")
    elif self.temp > 100:
        print("我是%s 我变成水蒸气了" % self.name)

class Water(H2O):
    pass

class Iire(H2O):
    pass

class Vapor(H2O):
    pass

w1 = Water('水', 10) #生成各自的实例
i1 = Iire("冰", -100)
v1 = Vapor("水蒸气", 1000)

# ************
def func(obj): ##对于使用者来说,自己的代码根本无需改动
    obj.turn_active()

func(w1) #实例调用统一的接口来实行trun_active()方法

二 反射

1.什么反射:

反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力(自省)。这一概念的提出很快引发了计算机科学领域关于应用反射性的研究。它首先被程序语言的设计领域所采用,并在Lisp和面向对象方面取得了成绩。

2.python面向对象中的反射:

通过字符串的形式操作对象相关的属性。python中的一切事物都是对象(都可以使用反射)

四个可以实现自省的函数 下列方法适用于类和对象(一切皆对象,类本身也是一个对象)[hasattr,getattr,setattr,delattr]
hasattr(object,name)

判断object中有没有一个name字符串对应的方法或属性

getattr(object, name, default=None)

获取对象的属性方法(Get a named attribute from an object)

    def getattr(object, name, default=None): # known special case of getattr
        """
        getattr(object, name[, default]) -> value

        Get a named attribute from an object; getattr(x, 'y') is equivalent to x.y.
        When a default argument is given, it is returned when the attribute doesn't
        exist; without it, an exception is raised in that case.
        """
        pass
setattr(x, y, v)

def setattr(x, y, v): # real signature unknown; restored from __doc__
"""
Sets the named attribute on the given object to the specified value.

setattr(x, 'y', v) is equivalent to ``x.y = v''
"""
pass
delattr(x, y)

def delattr(x, y): # real signature unknown; restored from __doc__
    """
    Deletes the named attribute from the given object.

    delattr(x, 'y') is equivalent to ``del x.y''
    """
    pass

四个方法的使用演示

class BlackMedium:
    feture = 'Ugly'

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

    def sell_hourse(self):
        print('【%s】 正在卖房子,傻逼才买呢' % self.name)

    def rent_hourse(self):
        print('【%s】 正在租房子,傻逼才租呢' % self.name)

b1=BlackMedium("黑中介","北京")
print(hasattr(b1,"name")) #判断实例有没有name的这个属性

func=getattr(b1,"sell_hourse")# 获得实例属性
func()
func1=getattr(b1,"sell_hoursedasd","没有这个属性") # default默认值
print(func1)

setattr(b1,"key","v1") #给对应实例添加数据属性

print(b1.__dict__)

delattr(b1,"key") #  删除实例的属性
print(b1.__dict__)

setattr(b1,"func2",lambda x:x+1)  #实例 设置 函数属性

print(b1.func2(10))

三、动态导入模块

mm为当前目录下的文件夹下面有tt.py
m = model_t = __import__("mm.tt")  # 只能导入第一层
print(m)
m.tt.test1()

import importlib #使用模块 动态导入,推荐这种方法
m2=importlib.import_module("mm.tt")
print(m2)
m2.test2()

四、基于反射实现可拔插组件

bob正在负责写FTP的客户端,但是最近他有大事,给耽误了,并且其他人需要用到这个ftp中的一些方法,这时候我们就需要用到反射

客户端残次品代码

    class FtpClient:
    def __init__(self,name):
        print("client ....")
        self.name=name

调用者需要基于反射调用FTp的客户端,如下:

from Ftp_client import *
c1 = FtpClient("client")
if hasattr(c1, "put"): #判断FTP客户端有没有put方法
    put_func = getattr(c1, "put") # 有就调用执行
    put_func()
else:
    print("没有执行put 完成其他操作!") #没有do other things!

原文地址:https://www.cnblogs.com/zjcode/p/8718596.html

时间: 2024-10-08 18:01:47

面向对象之多态,多态性,反射,以及基于反射的可拔插设计的相关文章

基于反射实现自己主动化restful开发

[Author]: kwu 基于反射实现自己主动化restful开发,通用的仅仅须要写查询数据库的sql.并增加相应的javabean实现的高速restful服务的开发. 1.编写数据库的查询sql.相应sql.properties daily = DailyReport;select t.day,t.cnt,t.type from (select day,cnt,type From dailyreport where type=? order by day desc limit ? ) t o

基于反射和泛型的编程

基于反射和泛型的编程,泛型是容器话的思路统过泛型对象或泛型方法,管理实际 要操作的对象,以实现对于实际对象管理的一种编程. 比如导出excel生成报表这种在平台开发中及其普遍的需求,有多个对象有生成报表 的需求如每个对象编写生成excel逻辑,程序会变得异常复杂,重复逻辑众多,通过将导 出excel逻辑泛型化,需要生成excel的bean本身不需要做任何变化,就可以按照需求生 成对应报表,这是一种很优雅很方便的报表生成方式.

《软件测试自动化之道》- 基于反射的UI自动化测试框架 - UI Automation Test Framework

测试自动化程序的任务 基于反射的ui测试自动化程序,要完成的6项任务: 通过某种方式从测试套件程序中运行待测程序(AUT: Applicaton Under Test),以便于两个程序之间进行通信 操纵应用程序的窗体,从而模拟用户对窗体所实施的moving和resizing操作 检查应用程序窗体,确定应用程序的状态是否准确 操纵应用程序控件的属性,从而模拟用户的一些操作,比如模拟在一个TextBox控件里输入字符 检查应用程序控件的属性,确定应用程序的状态是否准确 调用应用程序的方法,从而模拟一

基于反射实现自动化restful开发

[Author]: kwu 基于反射实现自动化restful开发,通用的只需要写查询数据库的sql,并加入对应的javabean实现的快速restful服务的开发. 1.编写数据库的查询sql,对应sql.properties daily = DailyReport;select t.day,t.cnt,t.type from (select day,cnt,type From dailyreport where type=? order by day desc limit ? ) t orde

《软件测试自动化之道》读书笔记 之 基于反射的UI测试

<软件测试自动化之道>读书笔记 之 基于反射的UI测试 2014-09-24 测试自动化程序的任务待测程序测试程序  启动待测程序  设置窗体的属性  获取窗体的属性  设置控件的属性  获取控件的属性  方法调用  待测程序代码 测试自动化程序的任务 返回 基于反射的ui测试自动化程序,要完成的6项任务: 通过某种方式从测试套件程序中运行待测程序(AUT: Applicaton Under Test),以便于两个程序之间进行通信 操纵应用程序的窗体,从而模拟用户对窗体所实施的moving和r

黑马程序员——Java基础---面向对象之多态

------<a href="http://www.itheima.com" target="blank">Java培训.Android培训.iOS培训..Net培训</a>.期待与您交流!                                                                     面向对象之多态 一:多态的概念  多态性在实际中的含义就是不同的对象有相同的一般轮廓或形态,但具体执行的过程却大相径庭

5.4 SAP ABAP 面向对象概念 - 多态 - 摘自 《SAP ABAP面向对象程序设计:原则、模式及实践》

<SAP ABAP面向对象程序设计:原则.模式及实践> https://book.douban.com/subject/30317853/ http://www.duokan.com/shop/tbt/book/179473 https://item.jd.com/12423999.html https://e.jd.com/30429611.html 5.4 多态 5.4.1 多态的概述 多态是一个生物学和化学中的专有名词,被面计算机科学家引用到面向对象的程序设计中. 我们用柯林斯英语词典看

面向对象编程 多态

面向对象编程 -多态 对象的多态性是指在父类中定义的属性或行为被子类继承之后,可以具有不同的数据类型或表现出不同的行为.这使得同一个属性或行为在父类及其各个子类中具有不同的语义. 多态这个概念,在 Java 中指的是变量可以指向的对象的类型,可是变量声明类型的子类.对象一旦创建,它的类型是不变的,多态的是变量. 在 PHP5 中,变量的类型是不确定的,一个变量可以指向任何类型的数值.字符串.对象.资源等.我们无法说 PHP5 中多态的是变量. 我们只能说在 PHP5 中,多态应用在方法参数的类型

面向对象之多态

面向对象之多态: 由于子类重写父类方法,然后用父类引用指向子类对象,调用方法时候会进行动态绑定,这就是多态 面向对象编程之接口: 接口(interface)是抽象方法和静态常量定义的集合. 接口是一种特殊的抽象类,这种抽象类中只包含抽象方法和静态常量. 接口中没有其它类型的内容 接口的定义 interface 接口名{ public getName(); public setName($name);}在接口中的抽象方法只能是 public 的,默认也是 public 权限.并且不能设置成 pri