【我要学python】面对对象编程之继承和多态
class animal(object):
def run():
print('animal is running...') class dog(animal):
def run(self):
print('dog is running...')
def eat(self):
print('Eating meat')
class cat(animal):
pass a=dog() #dog和cat自动拥有了父类animal的run()方法
a.run() #子辈的run()方法覆盖了父辈的run()方法,从而多态
a.eat() #要理解什么是多态,我们首先要对数据类型再作一点说明。当我们定义一个class的时候,我们实际上就定义了一种数据类型。我们定义的数据类型和Python自带的数据类型,比如str、list、dict没什么两样
cat.run() class Timer(object):
def run(): #run方法中不能写self
print('Start...') d=Timer
d.run() 输出内容:
dog is running...
Eating meat
animal is running...
Start...
引用开发者吴涛的一段话解释面对面对象程序设计以及多态:
面向对象的程序设计方法是目前最先进的程序设计理念,也是被目前绝大多数程序设计语言都使用的一种程序设计方法,它可以最大限度地提高程序代码的可复用性和可维护性,如果您想学习程序设计,那么这种设计方法是必须需要掌握的。
为了降低用户的学习门槛,火山对这套理念进行了最大限度的精简,一些晦涩难懂的和一些不大常用/实用的内容均被剔除出去,只保留了其精华和必须需要掌握的部分,因此学习起来并不难。
让我们根据一个实际生活中的例子来具体说明:
● 假设有一家工厂,所生成的产品是电水壶,这种电水壶有这些主要特点:
1、由壶体和壶盖组成;
2、颜色是银白色的;
3、有一个开关可以控制启动烧水;
4、水烧开后会发出鸣叫声音报警。
按照面向对象的设计方法,我们把这个电水壶称为这个工厂的一"类"产品,简称为“电水壶类”,它具有同样的4个特点:
1、有两个成员变量:壶体和壶盖;
2、有一个成员属性:颜色,它的值等于银白色;
3、有一个成员方法:烧水(即按下开关就开始烧水);
4、有一个成员事件:水已经烧开警报
变量用来存储类中的数据,属性用来表达或修改类的特征,方法用作执行类的功能,事件用来对外发送通知,类就是记录有一系列变量、属性、方法、事件成员的集合,所有具有这些特征成员的具体产品就叫做这个类的对象,这就是面向对象的程序设计理念来由。
用前面的例子来讲,“电水壶类”就是电水壶的产品设计规范,而具体的单个电水壶产品就是“电水壶类”的对象(有时也叫对象实例)。
这就是类的封装。
● 假设有一天,工厂想生产一种具有自动保温功能的电水壶,有两种方案:一是完全重新设计一个新的电水壶,二是在现有电水壶的基础上增加一个保温开关。很显然,第二种方式更经济实惠,工厂把这种新的电水壶称为保温电水壶,它增加了一个特点:
1、增加了一个开关: 保温,按下开关后可以对已经烧开的水进行自动保温。
按照前面的设计方法,由于新电水壶增加了一个成员,所以我们不能把它归纳到已有的“电水壶类”里面,但是我们可以建立一个新的类:“保温电水壶类”,它在“电水壶类”的基础上同样增加了一个新成员:
1、成员方法:保温(即按下开关就开始保温)
由于它基于“电水壶类”设计而来,因此我们把“电水壶类”称为“保温电水壶类”的基础类或父类,把“保温电水壶类”称为“电水壶类”的继承类或子类,它们之间是继承与被继承的关系,继承类自动具有基础类的所有特征成员。
由于继承类包括了基础类的所有成员,因此继承类也可以认为是基础类的一种。这个也很容易理解:我们可以把“保温电水壶”称为“电水壶”,但是不能把“电水壶”称为“保温电水壶”。假设客户要买1000个“电水壶”,现有产品数量不够时我们可以用“保温电水壶”来充数,但是客户要买1000个“保温电水壶”就绝对不能用“电水壶”来充数,是不是这个道理?
从程序设计的角度来讲,就是我可以把一个数据类型为“保温电水壶类”的对象赋值到一个数据类型为“电水壶”的变量,但是不允许把一个数据类型为“电水壶”的对象赋值到一个数据类型为“保温电水壶类”的变量。
需要注意的是:如果把一个数据类型为“保温电水壶类”的对象赋值到一个数据类型为“电水壶”的变量,那么这个变量里面实际存储的还是一个“保温电水壶类”对象,并不会因为变量的数据类型为“电水壶”存储进去的对象的数据类型就也为“电水壶”了。这个也很好理解:工厂用“保温电水壶”充作“电水壶”交付给了客户,不会因为这个充数行为就导致“保温电水壶”产品变成“电水壶”产品了。
这就是类的继承。
●让我们继续假设,假设有一天工厂发现电茶壶的销路要比电水壶好,同样有两种方案:一是完全重新设计一个新的电茶壶,二是修改现有电水壶的烧水功能,将其改为烧茶。同样很显然,第二种方式更经济实惠。那么这种电茶壶的特点为:
1、修改了电水壶的烧水功能,使其改去烧茶。
同样,我们需要定义一个名为“电茶壶类”的类,然后定义一个同样名为“烧水”的方法,该方法覆盖了“电水壶类”中的原有名为“烧水”的方法,然后将“电水壶类”中的“烧水”方法标记为虚拟方法(虚拟方法仅是一个标记,用作标记“烧水”方法可以被继承类覆盖),这样以后调用“电茶壶类”类的“烧水”方法时,就会改去烧茶,而不会去烧水。
需要注意的是:如果把一个数据类型为“电茶壶类”的对象赋值到一个数据类型为“电水壶”的变量,据前所述,这个变量里面实际存放的还是一个“电茶壶类”的对象,因此如果调用该变量的“烧水”方法,实际上调用的还是“电茶壶类”的烧茶功能。
这就是类的多态。
● 以上就是火山中所使用的面向对象程序设计的全部内容了,最后一点其实与面向对象设计无关:
假设甲公司和乙公司都生产电水壶,商店如果同时进货了这两种电水壶,就必须在电水壶上分别贴上标签:“甲公司的电水壶”、“乙公司的电水壶”,以免引起混淆。
在程序设计里面,就对应为“甲公司.电水壶类”、“乙公司.电水壶类”,前面的“甲公司”和“乙公司”分别定义了一个命名空间,也叫做“包”。包用作避免名称混淆,在同一个名称的包内,不允许存在相同名称的类,在不同名称的包内,可以存在相同名称的类。
所有在包中定义的类,其名称前被自动加上包名,“包名.类名”称为类的绝对名称。如果该类的名称在程序的所有包中均唯一或者在该类所处包内部引用此类,可以省略掉其包名来引用此类。
譬如,假设程序中不存在“乙公司.电水壶类”或者在“甲公司”包自身的代码内部,就可以直接使用“电水壶类”来引用“甲公司.电水壶类”。
注意:包名中间也可以包括句点,譬如“湖北.武汉.甲公司”或“湖南.长沙.乙公司”,这样的命名空间更明确清晰一些,也更具有唯一性。
引用廖雪峰博客对面对面对象程序设计的一段话:
我们可以从某个现有的class继承定义一个class,新的class称为子类(Subclass),而被继承的class称为基类、父类或超类(Base class、Super class)如:class Dog(Animal): 而不是class Dog(object):
好处:1.子类能获得父类的全部功能,包括父类的方法 2.多态:子类的实例既是属于子类,也属于父类。
注意:子类会继承父类的方法,但当子类有同样的方法,如run(),子类会覆盖父类,运行时会调用子类的run()
多态好处:只要确认是某类型,就可以调用该类型的方法,如果子类实例有同名方法,则调用子类方法,否则调用父类方法,这样不必再为子类单独建立一个函数调用方法 如: def run_twice(animal): animal.run() 子类Dog不需要再建立一个函数调用Dog.run,而直接使用run_twice(Dog)就行,而且其实是使用子类方法Dog.run。在调用时也不需要管内部细节,直接调用,运行时会自动根据该对象的确切类型(是否子类,子类是否有同样方法)决定。 同时,继承和多态还可以一级一级继承下去
静态语言 vs 动态语言 对于静态语言(例如Java)来说,如果需要传入Animal类型,则传入的对象必须是Animal类型或者它的子类,否则,将无法调用run()方法
对于动态语言Python来说,则不一定需要传入Animal类型。我们只需要保证传入的对象有一个run()方法就可以了
简单来说就是,动态语言不一定需要传入Animal类型,而只需要该类型定义了run()的方法就可以调用run_twice()。静态语音如Java则不行,必须传入Animal类型的
【我要学python】面对对象编程之继承和多态的更多相关文章
- python面对对象编程----2:__init__
面对对象编程估计我们最早接触到的就是__init__了,也就是实例的初始化处理过程: 1:来看看最基础的__init__ class Card(object): #抽象类Card,并不用于实例化 de ...
- 16、python面对对象之类和继承
前言:本文主要介绍python面对对象中的类和继承,包括类方法.静态方法.只读属性.继承等. 一.类方法 1.类方法定义 使用装饰器@classmethod装饰,且第一个参数必须是当前类对象,该参数名 ...
- python面对对象编程------4:类基本的特殊方法__str__,__repr__,__hash__,__new__,__bool__,6大比较方法
一:string相关:__str__(),__repr__(),__format__() str方法更面向人类阅读,print()使用的就是str repr方法更面对python,目标是希望生成一个放 ...
- javascript面对对象编程 之继承
上一篇博客中为大家介绍了javascript面向对象编程原则的封装,今天为大家介绍继承.在javascript中没有类的概念,全部不能像c#.java语言那样.直接的用类去继承类.比方如今有比方.如今 ...
- python面对对象编程----------7:callable(类调用)与context(上下文)
一:callables callables使类实例能够像函数一样被调用 如果类需要一个函数型接口这时用callable,最好继承自abc.Callable,这样有些检查机制并且一看就知道此类的目的是c ...
- python面对对象编程---------6:抽象基类
抽象基本类的几大特点: 1:要定义但是并不完整的实现所有方法 2:基本的意思是作为父类 3:父类需要明确表示出那些方法的特征,这样在写子类时更加简单明白 用抽象基本类的地方: 1:用作父类 2:用作检 ...
- python面对对象编程-------5:获取属性的四种办法:@property, __setattr__(__getattr__) ,descriptor
一:最基本的属性操作 class Generic: pass g= Generic() >>> g.attribute= "value" #创建属性并赋值 > ...
- python面对对象编程中会用到的装饰器
1.property 用途:用来将对像的某个方法伪装成属性来提高代码的统一性. class Goods: #商品类 discount = 0.8 #商品折扣 def __init__(self,nam ...
- python面对对象编程----1:BlackJack(21点)
昨天读完了<Mastering Object-oriented Python>的第一部分,做一些总结. 首先,第一部分总过八章,名字叫Pythonic Classes via Specia ...
随机推荐
- HDU 5868 Different Circle Permutation Burnside引理+矩阵快速幂+逆元
题意:有N个座位,人可以选座位,但选的座位不能相邻,且旋转不同构的坐法有几种.如4个座位有3种做法.\( 1≤N≤1000000000 (10^9) \). 题解:首先考虑座位不相邻的选法问题,如果不 ...
- asp.net RDLC报表入门
Asp.net RDLC 报表入门 这几天帮给同事讲解Asp.net RDLC 报表方面的知识,顺便做个简单教程,在这里分享给大家. 由于图片多又大,写了一半,光上传图片就把我累个半死,所以我教把程放 ...
- Jmeter-7-在命令行中运行Jmeter.
jmeter -n -t D:\Jmeter_result\Script_baidu.jmx -l D:\Jmeter_result\Script_baidu.txt jmeter -n -t D:\ ...
- 【BZOJ】2196: [Usaco2011 Mar]Brownie Slicing
[题意]给定n*m的数字矩阵,要求横着切A-1刀,对每块再分别竖着切B-1刀,是最小子矩阵最大. [算法]二分+贪心 [题解]还记得提高组2015跳石头吗?这道题做法一致,只不过拓展到二维而已. 二分 ...
- .NET中方法的注意事项 明细
1. 方法中return 会终止整个方法段. 而break只能终止当前循环. 2. 方法就是一对可用代码的复用. a . 对于可重用的代码,在vs中选中,右键 重构 提取方法.即可自动封装成一个方 ...
- 01背包入门 dp
题目引入: 有n个重量和价值分别为Wi,Vi的物品.从这些物品中挑选出总重量不超过W的物品,求所有挑选方案中的价值总和的最大值. 分析: 首先,我们用最普通的方法,针对每个物品是否放入背包进行搜索. ...
- niceScroll 简单使用 及 插件API
官方网址[https://nicescroll.areaaperta.com/] 注:效果见官网右侧滚动条 jquery.nicescroll文件下载地址 引入核心文件,插件需要引入1.5.X以上版 ...
- 控制 Cookie 的作用范围
默认时,网站的所有 Cookies 都一起被存储在客户端,并且所有 Cookies 连同网站的任何请求一起被发送到服务器.换句话说,网站中的每个页面都能够为网站获取所有的 Cookies.但是,你能够 ...
- 安装openssl-0.9.8报错out range of signed 32bit displacement .
安装openssl-0.9.8报错out range of signed 32bit displacement http://blog.csdn.net/wangtingyao1990/article ...
- MHA切换过程:
1.监测master的状态Ping(SELECT) succeeded, waiting until MySQL doesn't respond.. 2.当监控发现master异常时发出warning ...