面向对象三大特性的多态
一、多态
\'\'\'
1、什么是多态?
多态指的是同一种类型的实物,不同的形态
- 父类:动物
- 吃: eat
- 叫: speak
- 子类:
- 猪:
吃:eat
吧唧吧唧
叫:speak
哼哼哼
技能:
飞
- 狗:
吃:tian chi
舔 ji 舔 ji
叫:tell
汪汪汪
游泳
- 猫:
吃:chi
咬 ji 咬 ji
叫:jaio
喵喵喵
- 笔
铅笔:
写:def write():
写完可以擦掉
钢笔:
写:def xie():
写完可以用胶布粘掉
毛笔:
写:def xie_zi():
写完可以手撕,无法从写
2、多态的目的:
“多态”也被称之为“多态性”,目的是为了 在不知道对象具体类型的情况下,统一对象调用方法的规范(比如:名字)
多态的表现“形式之一”就是继承:
- 先抽象,再继承
父类:定制一套统一的规范(比如:方法名统一)
子类:遵循父类的统一的规范(比如:子类继承父类方法名的统一)
注意:在python中不会强制限制子类必须遵循父类的规范,所以出现了抽象类
\'\'\'
# # 正面教材
# #动物类
# class Animal:
#
# #方法吃
# def eat(self):
# pass
#
# #方法叫
# def speak(self):
# pass
#
# #猪类
# class Pig(Animal):
# def eat(self):
# print(\'吧唧....\')
#
# def speak(self):
# print(\'哼哼哼....\')
#
# #猫类
# class Cat(Animal):
# def eat(self):
# print(\'咬 ji 咬 ji \')
#
# def speak(self):
# print(\'喵喵喵...\')
#
# #狗类
# class Dog(Animal):
# def eat(self):
# print(\'舔ji 舔ji\')
#
# def speak(self):
# print(\'汪汪汪...\')
#
#
# animal1 = Dog()
# animal2 = Cat()
# animal3 = Pig()
#
# #让动物们叫起来
# animal1.speak()
# animal2.speak()
# animal3.speak()
#反面教材
#动物类
class Animal:
#方法吃
def eat(self):
pass
#方法叫
def speak(self):
pass
#猪类
class Pig(Animal):
def eat(self):
print(\'吧唧\')
def speak(self):
print(\'哼哼哼\')
#猫类
class Cat(Animal):
def chi(self):
print(\'咬ji 咬ji\')
def jaio(self):
print(\'喵喵喵\')
#狗类
class Dog(Animal):
def tian_chi(self):
print(\'舔 ji 舔 ji\')
def wangwang_jiao(self):
print(\'汪汪汪\')
animal1 = Dog()
animal2 = Pig()
animal3 = Cat()
#让动物们叫起来
animal1.speak()
animal2.speak()
animal3.speak()
二、抽象类
\'\'\'
1、什么是抽象类?
在python中内置的abc模块中,有一个抽象类
2、抽象类的作用:
让子类必须遵循父类的编写规范
3、如何实现抽象类?
- 父类需要继承abc模块中,metaclass=abc.ABCMeta
- 在父类的方法中,需要装饰上 abc.abstractmethod
注意:在python中不推荐使用抽象类(耦合度极高,程序可扩展性极地)
注意:子类必须按照父类的方法编写规范,缺一不可(只要父类中有几个抽象方法,子类就必须要定义几个)
\'\'\'
import abc
#父类
class Animal(metaclass=abc.ABCMeta):
#方法:吃
@abc.abstractmethod
def eat(self):
pass
#方法:叫
@abc.abstractmethod
def speak(self):
pass
#子类
#猪类
class Pig(Animal):
def eat(self):
print(\'吧唧吧唧\')
def speak(self):
print(\'哼哼哼\')
def run(self):
pass
pig_obj = Pig()
print(pig_obj.speak()) #哼哼哼
三、鸭子类型
\'\'\'
1、什么是鸭子类型?
不同的对象,只要长得像鸭子,动作行为像鸭子,那他就是鸭子
鸭子类型也是多态的一种表现形式
2、为什么要有鸭子类型?
不同对象,先抽象出相同类型的方法,给他们定制一套统一的规范
所有的类,在定义时都按照统一的规范进行编写
- 多态的三种表现形式:
- 继续父类:
-耦合度高,程序可扩展性低
- 继承抽象类:
- 耦合度极高,程序的可扩展性极地
- 鸭子类型:
- 耦合度低,程序的可扩展性高
注意:因为鸭子类型的耦合性低,可扩展性高,所以在python中强烈推荐鸭子类型
\'\'\'
#猪类
class Pig:
def eat(self):
print(\'吧唧吧唧\')
def speak(self):
print(\'哼哼哼\')
#猫类
class Cat:
def eat(self):
print(\'咬ji咬ji \')
def speak(self):
print(\'喵喵喵\')
#狗类
class Dog:
def eat(self):
print(\'舔 ji 舔 ji\')
def speak(self):
print(\'汪汪汪\')
四、多态之炫技
#多态之炫技:了解,面试时装逼用的
#猪类
class Pig:
def eat(self):
print(\'吧唧吧唧\')
def speak(self):
print(\'哼哼哼\')
#猫类
class Cat:
def eat(self):
print(\'咬 ji 咬 ji\')
def speak(self):
print(\'喵喵喵\')
#狗类
class Dog:
def eat(self):
print(\'舔 ji 舔 ji\')
def speak(self):
print(\'汪汪汪\')
dog = Dog()
pig = Pig()
cat = Cat()
# dog.speak()
# pig.speak()
# cat.speak()
#多态之炫技
# def SPEAK(animal):
# animal.speak()
#
# SPEAK(dog)
# SPEAK(cat)
# SPEAK(pig)
str1 = \'yafeng is very handsome!!!\'
list1 = [\'yafeng\', \'is\', \'very\', \'handsome!!!\']
print(str1.__len__()) #26
print(list1.__len__()) #4
#自定义统计长度函数
def LEN(obj):
return obj.__len__()
print(LEN(str1)) #26
print(LEN(list1)) #4
print(len(str1)) #26
print(len(list1)) #4
五、isinstance 与 issubclass
\'\'\'
isinstance 与 issubclass 是python的内置模块:
- isinstance: 判断一个对象是否是另一个类的实例(isinstance还可以判断一个对象是否是一个已知的类型,类似type)
- 如果是:True
- 如果不是:False
- issubclass: 判断一个类是否是另一个类的子类
- 如果是:True
- 如果不是:False
\'\'\'
#isinstance:
class Foo:
pass
class Boo:
pass
foo_obj = Foo()
boo_obj = Boo()
print(isinstance(foo_obj, Foo)) #True
print(isinstance(boo_obj, Foo)) #False
#issubclass
class Father:
pass
class Sub(Father):
pass
class Foo:
pass
print(issubclass(Sub, Father)) #True
print(issubclass(Foo, Father)) #False
六、classmethod 与 staticmethod
\'\'\'
1、classmethod 与 staticmethod都是python解释器内置的装饰器
classmethod:
是一个装饰器,给在类内部定义的方法装饰,将类内部的方法变为“类的绑定方法”。
staticmethod:
翻译:静态方法
是一个装饰器,给在类内部定义的方法装饰,将类内部的方法变为“非绑定方法”
- 对象的绑定方法:
- 由对象来调用,由谁来调用,会将谁(对象)当做第一个参数传入。
- 类的绑定方法:
- 由类来调用,由谁来调用,会将谁(类)当做第一个参数传入。
- 非绑定方法:
- 可以由对象或类来调用,谁来调用都是一个普通方法(普通函数),方法需要传入几个参数,就得传入几个
\'\'\'
# #classmethod
# class DB:
# __data = \'yafeng is very handsome!!!\'
#
# def __init__(self, user, pwd, role):
# self.user = user
# self.pwd = pwd
# self.role = role
#
# #查看数据方法
# @classmethod
# def check_db(cls, user, pwd, role): #cls--->指的是类
#
# #在类方法内部定义调用类产生一个实例---->对象
# obj = cls(user, pwd, role)
#
# #1、查看数据前,必须要通过校验
# if obj.user == \'yafeng\' and obj.pwd == \'666\' and obj.role == \'admin\':
# print(\'校验通过\')
# print(cls.__data)
# return cls.__data
#
# DB.check_db(\'yafeng\', \'666\', \'admin\')
# #校验通过
# # yafeng is very handsome!!!
# #staticmethod
# import uuid #用于产生随机字符串的模块
#
# print(uuid.uuid4()) #bf30df87-0071-4c8e-bd7d-cfb3cea7c260
class Foo:
@staticmethod
def func(res):
print(res)
obj = Foo()
#对象调用非绑定方法(此时需传参)
obj.func(666) #666
#类调用非绑定方法
Foo.func(123) #123
七、反射
\'\'\'
反射:
反射指的是通过“字符串”对 对象的属性进行操作
- hasattr:通过“字符串”判断对象的属性或方法是否存在
- getattr:通过“字符串”获取对象的属性或方法
- setattr:通过“字符串”设置对象的属性或方法
- delattr:通过“字符串”删除对象的属性或方法
注意:反射的四个方法是python内置的
\'\'\'
# class Foo:
# def __init__(self, x, y):
# self.x = x
# self.y = y
#
#
# foo_obj = Foo(10, 20)
#
# #hasattr
# #通过字符串x 判断对象中是否有x属性
# print(hasattr(foo_obj, \'x\')) #True
# print(hasattr(foo_obj, \'y\')) #True
# print(hasattr(foo_obj, \'z\')) #False
#
#
# #getattr
# res = getattr(foo_obj, \'x\')
# print(res) #10
#
# #若属性不存在,也可以自定义返回的默认值
# res = getattr(foo_obj, \'z\', \'默认值\')
# print(res) #默认值
#
# #setattr
# #为foo_obj 设置一个属性z, 值为30
# # res = setattr(foo_obj, \'z\', 30)
# # print(res) #*****不可以这么玩None
#
# setattr(foo_obj, \'z\', 30)
# print(hasattr(foo_obj, \'z\')) #True
# res = getattr(foo_obj, \'z\')
# print(res) #30
#
# #delattr
# delattr(foo_obj, \'x\')
# print(hasattr(foo_obj, \'x\')) #False
#反射应用
class File_control:
def run(self):
while True:
#让用户输入上传或下载功能的命令:
user_input = input(\'请输入 上传(upload)或 下载(download) 的功能:\').strip()
#通过用户输入的字符串判断方法是否存在,然后调用相应的方法
if hasattr(self, user_input): # if True:
func = getattr(self, user_input) #拿到内容
func()
else:
print(\'输入有误...\')
def upload(self):
print(\'文件正在上传...\')
def download(self):
print(\'文件正在下载...\')
file_obj = File_control()
file_obj.run()
\'\'\'
请输入 上传(upload)或 下载(download) 的功能:upload
文件正在上传...
请输入 上传(upload)或 下载(download) 的功能:download
文件正在下载...
请输入 上传(upload)或 下载(download) 的功能:
\'\'\'