Python面向对象之多态、封装
一、多态
超过一个子类继承父类,出现了多种的形态。
例如,动物种类出现了多种形态,比如猫、狗、猪
class Animal:pass
class Cat(Animal):pass
class Dog(Animal):pass
class Pig(Animal):pass
Python是处处有多态,因为新式类都是继承object
多态的定义:一个类表现出的多种形态,通过继承来实现,一个父类有多个子类。再简化的说法就是“有多种形式”,就算不知道变量(参数)所引用的对象类型,也一样能进行操作,来者不拒。
count(),repr() 这类就是多态的代表
在java中的表示:在一个函数中需要给参数指定数据类型,如果这个地方可以接收两个以上类型的变量,那么这些类型应该有一个父类,这个父类是所有子类对象的类型
在python中:函数的参数不需要指定数据类型,所以不需要通过继承的形式来统一一组数据类型,换句话说 所有的对象其实都是object类型,所有在python中处处是多态。
经典类和新式类都有多态
from abc import ABCMeta,abstractmethod class Animal(metaclass=ABCMeta):
@abstractmethod
def talk(self):pass class Cat(Animal):
def talk(self):
print('喵喵')
class Dog(Animal):
def talk(self):
print('汪汪') c = Cat()
c.talk()
d = Dog()
d.talk() '''
喵喵
汪汪
'''
代码中有 Cat 和 Dog 两个类,都继承了类 Animal,它们都有 talk() 方法,输入不同的动物名称,会得出相应的结果。
鸭子类型:
在程序设计中,鸭子类型(英语:duck typing)是动态类型的一种风格。在这种风格中,一个对象有效的语义,不是由继承自特定的类或实现特定的接口,而是由当前方法和属性的集合决定。这个概念的名字来源于由 James Whitcomb Riley 提出的鸭子测试,“鸭子测试”可以这样表述:“当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。”
定义:不是明确的通过继承实现的多态,而是通过一个模糊的概念来判断这个函数能不能接收这个类型的参数
python中通过鸭子类型来体现多态:比如len(),print()
二、封装
广义的封装:
定义一个类,把所有的属性和方法都放在类里面
为了只有这个类的对象才能使用定义在类中的方法,其他都用不了
狭义上上的封装:
把一个变量藏在类里,在类的外部不能引用私有变量,只有类的内部能使用
class A:
__x = 0 # 私有的静态变量
定义一个类,执行的时候把类的内容读完才开辟类的空间,所有类的内容加载的时候就完成了
class A:
__x = 0 # 私有的静态变量
print('AAA') '''
AAA
'''
定义类的内存机制:
① 类中的静态变量和方法名在程序加载的过程中就已经执行完毕了,不需要等待调用
② 在类加载完成之前,类的名字还没出现在内存空间中
③ 私有的静态属性可以在类的内部使用,用来隐藏某个变量的值
当私有变量在存储时会做了变形:_类名__私有变量
类名.变形的私有变量可以取值,但是从编程规范的角度上出发,不能在类的外部使用私有的变量
class Course:
__name = 'python' # 变形:_Course__name print(Course.__dict__) # 查看类里所有的属性和变量
print(Course._Course__name) # python,不建议使用这方法取值 '''
{'__module__': '__main__', '_Course__name': 'python', '__dict__': <attribute '__dict__' of 'Course' objects>, '__weakref__': <attribute '__weakref__' of 'Course' objects>, '__doc__': None}
python
'''
定义私有变量的原因:
① 不想让使用者看到这个值
② 不想让使用者修改这个值
③ 让使用者修改这个值的时候做一些限制:保证了数据的安全
④ 有些方法或者属性不希望被子类继承
不想让使用者修改这个值
class University:
def __init__(self,name,site):
self.__name = name # 定义了私有属性
self.__site = site # 定义了私有属性 def name(self): # 定义方法返回值
return self.__name def site(self): # 定义方法返回值
return self.__site uni = University('哈佛大学','马萨诸塞州剑桥市')
print(uni.name()) # 调用类提供的方法取值
print(uni.site()) # 调用类提供的方法取值
print(uni.name) # 类对象的方法的内存地址
print(uni) # 类对象的内存地址
uni.name = '剑桥大学' # 在类对象里添加了name的值
print(uni.__dict__) '''
哈佛大学
马萨诸塞州剑桥市
<bound method University.name of <__main__.University object at 0x00000209EBDE7E48>>
<__main__.University object at 0x00000209EBDE7E48>
{'_University__name': '哈佛大学', '_University__site': '马萨诸塞州剑桥市', 'name': '剑桥大学'}
'''
让使用者修改这个值的时候做一些限制
class Supermarket:
__discount_coupon = 1000
def __init__(self,name,price):
self.name = name
self.__price = price # 定义私有变量 def price(self): # 获取变量值的方法
if self.__price > 5999:
return self.__price - Supermarket.__discount_coupon
else:
return self.__price def change_price(self,new_price): # 改变变量值的方法
if isinstance(new_price,int):
self.__price = new_price
else:
print('价格修改失败') ap = Supermarket('IPhone',6000)
print(ap.price()) # 通过方法获得私有变量的值
ap.change_price(3000) # 通过方法改变私有变量的值
print(ap.price()) '''
5000
3000
'''
类中的私有成员:
① 私有的静态属性
② 私有的对象属性
③ 私有的方法
私有变量在类的外部不能被定义,因为在类的内部带__ 定义私有变量都会变形,在外部被定义不会变形
class Language:
__China = 'chinese' # 发生变形 '_Language__China': 'chinese' print(Language.__dict__)
Language.__Korea = 'Korean' # 在类的外部定义不会发生变形 __Korea': 'Korean'
print(Language.__dict__) '''
{'__module__': '__main__', '_Language__China': 'chinese', '__dict__': <attribute '__dict__' of 'Language' objects>, '__weakref__': <attribute '__weakref__' of 'Language' objects>, '__doc__': None}
{'__module__': '__main__', '_Language__China': 'chinese', '__dict__': <attribute '__dict__' of 'Language' objects>, '__weakref__': <attribute '__weakref__' of 'Language' objects>, '__doc__': None, '__Korea': 'Korean'}
'''
私有变量不能被继承
# 封装前
class A:
def __init__(self,name):
self.name = name class B(A):
def get_name(self):
print(self.name) b = B('haha')
b.get_name() '''
haha
''' # 封装后
class A:
def __init__(self,name):
self.__name = name class B(A):
def get_name(self):
print(self.__name) b = B('haha')
b.get_name() AttributeError: 'B' object has no attribute '_B__name'
私有成员的特点:
① 不能在类的外部被调用,只能在类的内部被调用(在类的内部变形了,_类名__变量名)
② 不能被子类继承
三、property 内置函数
装饰器的使用:所有的装饰器函数、方法、类的上一行直接@装饰器的名字
装饰器的分类:
① 装饰函数
② 装饰方法
③ 装饰类
property 是一个装饰器函数
@property 是装饰方法的,将一个方法伪装成一个属性,相当于调用方法是不需要加括号
class A:
def __init__(self,name):
self.__name = name @property
def name(self):
return self.__name a = A('小明')
print(a.name) '''
小明
'''
Python面向对象之多态、封装的更多相关文章
- Python面向对象三要素-封装(Encapsulation)
Python面向对象三要素-封装(Encapsulation) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.封装概述 将数据和操作组织到类中,即属性和方法 将数据隐藏起来,给 ...
- Python面向对象之多态
多态 面向对象三大特性 封装 根据职责将属性和方法封装到一个抽象的类中:--定义类的准则 继承 实现代码的重用,相同的代码不需要重复的编写:--设计类的技巧:子类针对自己的需求,编写特定的代码: 多态 ...
- python 面向对象之多态与绑定方法
多态与多态性 一,多态 1,多态指的是一类事物有多种形态(python里面原生多态) 1.1动物有多种形态:人,狗,猪 import abc class Animal(metaclass=abc.AB ...
- Python 面向对象5 多态
一.多态 多态性(polymorphisn)是允许你将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作,简单的说就是一句话:允许将 ...
- python 面向对象三大特性(封装 多态 继承)
今天我们来学习一种新的编程方式:面向对象编程(Object Oriented Programming,OOP,面向对象程序设计)注:Java和C#来说只支持面向对象编程,而python比较灵活即支持面 ...
- Python 面向对象 组合-多态与多态性-封装-property
面向对象-组合 1.什么是组合 组合指的是某一个对象拥有一个属性,该属性的值是另外一个类的对象 class Foo: xxx = 111 class Bar: yyy = 222 obj = Foo( ...
- python面向对象中的封装、继承、多态
封装 可以简单的理解为隐藏一切可以隐藏的实现细节,只向外界提供简单的编程接口.我们在类中定义的方法其实就是把数据和数据的操作封装起来了,在我们创建了对象之后,只需要给对象发送一个消息(调用方法)就可以 ...
- Python面向对象三大特性(封装、继承、多态)
封装 类中把某些属性和方法隐藏起来,或者定义为私有,只在类的内部使用,在类的外部无法访问,或者留下少量的接口(函数)供外部访问:从上一篇文章中的私有属性与私有方法中的代码体现了该特性. class m ...
- Python之路【第十篇】:Python面向对象之多态、多态性
阅读目录 一 多态 多态指的是一类事物有多种形态 动物有多种形态:人,狗,猪 import abc class Animal(metaclass=abc.ABCMeta): #同一类事物:动物 @ab ...
随机推荐
- Django架站的16堂課
Django架站的16堂課-活用Django+Web+Framework快速构建移动网站 目录 第1堂 网站开发环境的建立 1 1.1 网站的基础知识 1 1.1.1 网站的运行流程 1 1.1.2 ...
- response.getWriter().write的用法
/** * 获取手机验证码的方法 */ var loopObjBindMobil = null; var secondsBindMobil = 0; function hqBindYzm(moblie ...
- python flask框架学习(三)——豆瓣微信小程序案例(二)整理封装block,模板的继承
我们所要实现的效果: 点击电影的更多,跳转到更多的电影页面:点击电视剧的更多,跳转到更多的电视剧页面. 三个页面的风格相同,可以设置一个模板,三个页面都继承这个模板 1.在指定模板之前,把css放在一 ...
- lodop和c-lodop通过打印状态和任务不在队列获取打印成功
之前的博文有通过判断pirnt的返回值,判断加入队列算打印成功,建议使用这种简单的判断方法.此外还有其他判断方法,例如通过PRINT_STATUS_OK判断,但是这个状态不是所有打印机能支持这种判断成 ...
- 【redis】 windows 32x 64x
下载地址:http://files.cnblogs.com/files/dtdxrk/redis_win.zip
- iOS 多线程的简单理解(1) 方式 :同步 异步
最近遇到特别糟糕的面试,过程中提到多次对多线程的处理问题,并没有很好的给予答复和解决,所以在这里做个简单的备案: 期望能更加了解和熟练使用 多线程技术: 下面都是自己的总结,如果存在不对的,或者不足, ...
- context.xml文件配置
<?xml version='1.0' encoding='utf-8'?> <Context> <WatchedResource>WEB-INF/web.xml& ...
- Duration和Period的区别--通俗易懂
在jdk1.8以后,对表示日期时间的类型进行了重新分类,这里出现了2个新的类,Duraction 和Period Duraction表示:时间的区间,用来度量秒和纳秒之间的时间值 Period表示:一 ...
- [转帖]时间序列数据库 (TSDB)
时间序列数据库 (TSDB) https://www.jianshu.com/p/31afb8492eff 0.3392019.01.28 10:51:33字数 5598阅读 4030 背景 2017 ...
- IdentityServer4 学习二
进入identityserver4的官网:https://identityserver.io/ 找到文档 从overview下开始按照官方文档练习: 安装自定义模板 dotnet new -i Ide ...