本文主要是介绍面向对象编程(三),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
面向对象编程(三)
继承下的派生实际应用
# 功能:重写已有方法,在保证原来功能正常的情况下加入自己需要的功能
import datetime
import json
dict1 = {'datetime':datetime.datetime.today(),'time':datetime.date.today()}
# res = json.dumps(dict1)
# print(res) # Object of type 'datetime' is not JSON serializable
class MyJSONEncoder(json.JSONEncoder):
def default(self,o): # 形参o就是即将要被序列化的数据对象
print('重写了')
if isinstance(o, datetime.datetime):
return o.strftime('%Y-%m-%d %X') # datetime格式转成字符串
elif isinstance(o, datetime.date):
return o.strftime('%Y-%m-%d') # data时间格式转成字符串
return super(MyJSONEncoder, self).default(o) # 重新调用父类的方法,防止以前的功能不能用
res = json.dumps(dict1,cls=MyJSONEncoder)
print(res) # {"datetime": "2022-04-08 16:01:19", "time": "2022-04-08"}
面向对象三大特征之封装
# 封装的含义
将类中的某些名字'隐藏'起来 不让外界直接调用
隐藏的目的是为了提供专门的通道(接口)去访问 在通道内可以添加额外的功能
# 如何封装
eg:
class Student(object):
def __init__(self,name,age):
self.name = name
self.age = age
__school = '家里蹲大学' # 名字前面加杠杠'__'即是封装该名字的意思
def func1(self):
print('func1')
def __func2(self): # 函数名前面加__就是封装整个函数
print('func2')
obj1 = Student('petter',18)
# print(obj1.name) # petter
# print(obj1.__school) # AttributeError: 'Student' object has no attribute '__school'
obj1.func1() # func1
obj1.__func2() # AttributeError: 'Student' object has no attribute '__func2'
# 怎么调用封装数据?
eg:
class Student(object):
def __init__(self, name, age):
self.name = name
self.age = age
__school = '家里蹲大学' # 名字前面加杠杠'__'即是封装该名字的意思
def func1(self):
print('func1')
def __func2(self): # 函数名前面加__就是封装整个函数
print('func2')
def interface_school(self): # 定义调用数据的接口
print('我来自%s'%self.__school)
def interface_func2(self): # 定义调用函数的接口
self.__func2()
obj1 = Student('petter', 18)
obj1.interface_school() # 我来自家里蹲大学
obj1.interface_func2() # func2
"""
将数据隐藏起来就限制了类外部对数据的直接操作,然后类内应该提供相应的接口来允许类外部间接地操作数据,
接口之上可以附加额外的逻辑来对数据的操作进行严格地控制
目的的是为了隔离复杂度,例如ATM程序的取款功能,该功能有很多其他功能组成
比如插卡、身份认证、输入金额、打印小票、取钱等,而对使用者来说,只需要开发取款这个功能接口即可,其余功能我们都可以隐藏起来
"""
property(方法伪装成数据)
eg:
# 输入正方形边长,计算周长和面积
class Calculate(object):
def __init__(self, r):
self.r = r
@property
def perimeter(self):
return '该正方形的周长是%f' % (self.r * 4)
@property
def area(self):
return '该正方形的面积是%f' % (self.r ** 2)
obj1 = Calculate(5)
print(obj1.perimeter) # 和数据一样的调用方式
print(obj1.area)
运行结果:
该正方形的周长是20.000000
该正方形的面积是25.000000
小发现
def func():
a = 2
return '运行结果是%s'%a * 3
print(func())
运行结果:
运行结果是2运行结果是2运行结果是2
如果return关键字后面有运算,要括号括起来,否则会出现多重输出
面向对象三大特征之多态
# 什么是多态?
一种事物的多种形态
eg:
植物>>>草本植物、木本植物、禾本植物
# 多态性
str,dict,tuple,set是不同的数据类型,他们的类也是不同
但是统计长度的方法都叫len,这就是多态
eg:
class Cat(object):
def call(self):
print('猫叫了')
class Dog(object):
def call(self):
print('狗叫了')
class Pig(object):
def call(self):
print('猪叫了')
obj1 = Cat()
obj2 = Dog()
obj3 = Pig()
obj1.call() # 猫叫了
obj2.call() # 狗叫了
obj3.call() # 猪叫了
'''
有相同操作的类,在定义这种操作时,应统一命名,生成不同的对象后,用不同的对象调用同一个方法名实现不同类里的操作
面向对象的多态性也需要python程序员自己去遵守
'''
# 虽然python推崇的是自由 但是也提供了强制性的措施来实现多态性(不推荐使用)
eg:
import abc
class Animal(object,metaclass=abc.ABCMeta):
@abc.abstractmethod # 这个语法糖使用后,在继承这个类时,必修要实现下面的方法
def call(self):
pass
class Cat(Animal):
def aa(self):
print('aa')
class Dog(Animal):
def call(self):
pass
def aa(self):
print('aa')
# obj1 = Cat()
# obj1.aa() # TypeError: Can't instantiate abstract class Cat with abstract methods call
obj2 = Dog()
obj2.aa() # aa
面向对象之反射
# 什么是反射
专业解释:指程序可以访问、检测和修改本身状态或者行为的一种能力
大白话:其实就是通过字符串来操作对象的数据和功能
# 反射需要掌握的四个方法
hasattr():判断对象是否含有字符串对应的数据或者功能
getattr():根据字符串获取对应的变量名或者函数名
setattr():根据字符串给对象设置键值对(名称空间中的名字)
delattr():根据字符串删除对象对应的键值对(名称空间中的名字)
# 反射的实际应用
# 编写小程序,判断对象中是否有指定的名字,有则取出展示
class Student(object):
school = '家里蹲大学'
obj1 = Student()
res = input('请输入字段').strip()
if hasattr(obj1, res): # 如果obj1对象里面有字段,返回Ture
name = getattr(obj1, res) # 获取字符串对应变量名或函数名
if callable(name): # 如果可调用
print('类中有一个功能%s'%res,obj1.name())
else:
print('类中有一个变量%s'%res,obj1.name)
else:
print('没找到')
setattr(obj1, 'name','petter' ) # 创建新名字
delattr(obj1,'school') # 删除名字
这篇关于面向对象编程(三)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!