我的编程空间,编程开发者的网络收藏夹
学习永远不晚

多态和封装

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

多态和封装

一、多态

术语多态(polymorphism)源自希腊语,意思是“有多种形态”。这大致意味着即便你不知道变量指向的哪种对象,
也能够对其执行操作,且操作的行为将随所属的类型而异。
例如,假设你要为一个销售食品的电子商务网站创建在线支付系统,程序将接受来自系统另一部分的购物车。因此你只需要计算总价并从信用卡中扣除费用即可。
你首先想到的可能是,指定程序收到商品时必须如何表示。例如,呢可能要求用元组表示收到的商品。如下所示:
('apple',4)
如果你只需要描述性标签和价格,这样的表示很好,但不灵活。假设该网站新增了拍卖服务,即不断降低商品的价格,直到有人购买为止。
在这种情况下,如果能够允许用户像下面这样做就好了:将商品放入购物车并进入结算页面,等到价格合适时再点击支付。
然而,使用简单的元组表示商品无法做到这一点。要做到这一点,表示商品的对象必须在你编写的代码询问价格时通过网络检查其当前价格,也就是说不能像在元组中那样固定价格。要解决这个问题,可创建一个函数。

def get_price(object):
    if isinstance(object,tuple):
        return object[1]
    else:
        return magic_network(object)

# 这里使用isinstance 来执行类型检查旨在说明:使用类型价差通常是馊主意,应尽可能避免。
前面的代码使用函数isinstance来检查object是否是元组。如果是,就返回其第二个元素,否则就调用一个神奇的网络方法。
如果网络方法已就绪,问题就暂时解决了。但这种解决方案还是不太灵活。如果有位程序员很聪明,决定用十六进制的字符串表示价格,并将其存储在字典的‘price'键下呢?没问题,你只需要更新相应的函数。

def get_price(object):
    if isinstance(object,tuple):
        return object[1]
    elif isinstance(object,dict):
        return int(object['price'])
    else:
        return magic_network(object)

你确定现在考虑到了多样的可能性了吗?假设有人决定添加一种新字典,并在其中将价格存储在另一个键下,你该如何办呢?当然,可再次更新get_price,但这种应对之策在多长时间内有效呢? 每当有人以不同的方式实现对象时,你都需要重新实现你的模块。如果你将该模块卖给了别人,转而从事其他项目的开发,客户该怎么办?显然。这种实现不同行为的方式既不灵活也不切实际。

那么该如何做呢?让对象自己去处理这种操作。这好像没什么大不了,但仔细想想将发现,这样事情将简单得多:每种新对象都能够获取或计算并返回结果,而你只需要向它们询问价格即可。这正是多态的用武之地。

多态和方法

你收到一个对象,却根本不知道它是如何实现的----它可能是众多“形态”中任何一种。你只知道可以询问其价格,但这就够了。至于询问价格的方式,你应该熟悉。

print(object.get_price())
4

像这样与对象属性相关的函数称为方法。
其实好多内置函数就用来多态的方式。

str1= “abcd"
str1.count("a")
len(str1)
list1 = [1,2,3,4]
len(list1)

像这样无需知道变量是字符串还是列表就能调用方法len,只要你能向这个方法提供一个字符作为参数,它就能正常运行。

 多态形式多样

每当无需知道对象是什么样的就能对其执行操作时,都是多态在起作用。这不仅仅适用于方法,我们还通过内置运算符合函数大量使用了多态。

print(1 + 2)
3
price("hello" + "world")
helloworld

上述代码表明,加法运算符号(+)即可用于数学运算,也可用于字符串(以及其他类型的序列)。
很多函数和运算符都是多态的,你编写的大多数函数也可能如此,即便你不是有意为之。每当你使用多态的函数和运算符时,多态都将发挥作用。
事实上,要破坏多态,唯一的方法就是使用诸如type、issubclass 等函数显式地执行类型检查,但你应尽可能避免以这种方式破坏多态。
重要的是,对象按你希望那那样行事,而非它是否是正确的类型(类)。然而,不用使用类型检查的禁令已不像以前那么严格。引入本章后面讲讨论的抽象基类和模块abc后,issubclass本身也就是多态了!

鸭子类型
多态是Python编程方式的核心,有时称为鸭子类型。这个术语源自如下说法:如果走起来像鸭子,叫起来像鸭子,那么它就是鸭子。

二 、封装

封装(encapsulation)指的是向外部隐藏不必要的细节。这听起来有点像多态(无需知道对象内部的细节就可使用它)。
这两个概念很像,因为它们都是抽象的原则。它们都像函数一样,可帮助你处理程序的组成部分,让你无需关心不必要的细节。
但封装不同于多态。多态让你无需知道对象所属的类(对象的类型)就能调用其方法,而封装让你无需知道对象的构造方法就能使用它。
听起来还是有点像?下面看一个使用了多态但没有使用封装的示例。下来创建一个名为OpenObject的类。

class OpenObject():
    def __init__(self):
        pass    
    def set_name(self,name):
        self.name= name
    def get_name(self):
        return self.name

实例化一个对象

o=OpenObject()
o.set_name("Sir Lancelot")
o.get_name()
Sir Lancelot

通过像调用函数一样调用类来创建了一个对象,并将其关联到o,然后就可以使用方法set_name和get_name了。
一切看起来都完美无缺。然而,如果o将其名称存储在全局变量 global_name中呢?这意味着使用OpenObject类的实例时,你需要考虑global_name的内容,事实上,必须确保无人能修改它。

class OpenObject():
    name = "Sir Lancelot"
    def __init__(self):
        pass
    def set_name(self, name):
        OpenObject.name = name
    def get_name(self):
        return self.name

如果创建多个OpenObject,将出现问题,因为它们共用一个变量

o = OpenObject()
o1 = OpenObject()
print(o1.get_name())
o.set_name("Sir Grub")
print(o.get_name())
print(o1.get_name())

结果为:

Sir Lancelot
Sir Grub
Sir Grub

这说明在设置一个对象的名称时,将自动设置另一个对象的名称。这可不是想要的结果。基本上我们都希望对象时抽象的;当调用方法时,无需操心其他的操作,如避免干扰全局变量,如何将名称“封装”到对象中呢? 没问题,将其作为一个属性即可。
属性时归属于对象的变量,就像方法一样。实际上,方法差不多就是与函数相关联的属性,如果使用属性而非全局变量重新编写起那么的类,并将其重命名为CloseObject,就可以像下面这样做:

class OpenObject():
    def __init__(self):
        pass
    def set_name(self, name):
        self.name = name
    def get_name(self):
        return self.name
o = OpenObject()
o.set_name("Sir Grub")
print(o.get_name())
结果为:
Sir Grub

到目前为止一切顺利,但这并不能证明名称不是存储在全局变量中的。下面再来创建一个对象。

o1 = OpenObject()
print(o1.get_name())
结果为:
Sir Lancelot

从中可知正确的设置了新对象的名称,但第一个对现在怎么样了呢?

print(o.get_name())
Sir Grub

其名称还在! 因为这个对象有自己的状态,对象的属性由其属性(如名称)描述。对象的方法肯修改这些属性,因此对象将一系列函数(方法)组合起来,并赋予他们访问一些变量(属性)的权限,而属性可用在两次函数调用之间存储值。


免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

多态和封装

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

多态和封装

一、多态 术语多态(polymorphism)源自希腊语,意思是“有多种形态”。这大致意味着即便你不知道变量指向的哪种对象,也能够对其执行操作,且操作的行为将随所属的类型而异。例如,假设你要为一个销售食品的电子商务网站创建在线支付系统,程序
2023-01-30

Java中封装、继承和多态的示例分析

这篇文章主要介绍Java中封装、继承和多态的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!封装所谓的封装就是把类的属性和方法使用private修饰,不允许类的调用者直接访问,我们定义如下一个类,可以看到所有的
2023-06-15

面向对象封装、继承、多态

一、面向对象封装 01. 封装封装 是面向对象编程的一大特点面向对象编程的 第一步 —— 将 属性 和 方法 封装 到一个抽象的 类 中外界 使用 类 创建 对象,然后 让对象调用方法对象方法的细节 都被 封装 在 类的内部 02. 小明跑
2023-01-31

java的三大特性封装、继承、多态

我们知道面向对象的三大特性是封装、继承和多态。然而我们有时候总是搞不清楚这些概念。下面对这些概念进行整理,为以后面向抽象的编程打下坚实的基础。  封装的概念还是很容易理解的。如果你会定义类,那么相信你对封装的概念已经完全掌握了。下面定义的几个类,就是对数据的封
java的三大特性封装、继承、多态
2017-04-24

Java中封装、继承、多态特性是什么

这篇文章主要为大家展示了“Java中封装、继承、多态特性是什么”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Java中封装、继承、多态特性是什么”这篇文章吧。1.封装什么是封装,谈谈自己对封装的
2023-06-22

java封装继承多态的好处有哪些

Java封装、继承和多态是面向对象编程的三个核心概念。它们的好处包括:封装:封装可以隐藏对象的内部细节,只暴露必要的接口给其他对象使用。这样可以提高代码的安全性和可维护性,降低代码的耦合度。继承:继承可以让子类继承父类的属性和方法,减少了重
java封装继承多态的好处有哪些
2024-02-29

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录