测试奇谭,BUG不见。

这一场主讲python的面向对象部分——封装、多态和继承

目的:掌握Python面向对象的三个核心概念。

封装

01 什么是封装?

封装的目的是,保护隐私。通俗的讲:不想让别人知道你的东西。

于是,便有了两个概念:普通属性(变量)和私有属性(变量)。

02 为什么要用封装?

当你不希望外界可以直接修改一些数据时。

比如用户的身份证号等信息属于用户的隐私,肯定不能直接暴露给外界直接访问或修改,那么就不能把它作为普通属性,应该作为私有属性。

03 怎么使用封装?

看下面这个例子就够了。

# !/usr/bin/python
# -*- coding:utf-8 -*-
class User:
def __init__(self, name, id_card):
# 普通属性
self.name = name
# 私有属性(双下划线)
self.__id_card = id_card def get_id_card(self):
return self.__id_card class Student(User):
def init(self, name, id_card):
# 普通属性
self.name = name
# 私有属性
self.__id_card = id_card # 实例化一个User类
user = User('张三', 511011199505050101)
stu = Student('李四', 511011199505050808) #print(user.__id_card)
# 不能直接访问私有属性,会报错:AttributeError: 'User' object has no attribute '__age'
print(user.get_id_card())
# 可以通过成员方法去访问私有属性 print(user._User__id_card)
# 也可以通过 “_类名__私有属性名” 进行访问

多态

01 什么是多态?

  • 多态指同一个实体同时具有多种形式。
  • 它是面向对象程序设计(OOP)的一个重要特征。
  • 同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果。
  • 多态一般要通过继承和重写方法去实现。

太难理解?

说简单点:一类事物(动物)有多种形态(猫,狗,猪等)。

02 有什么用?

增加了程序的灵活性和扩展性,不论对象怎么变,调用方式不变。

太难理解?

那先了解下Python的多态实现,再来理解。

首先,Python 的多态是基于鸭子类型实现。

什么是鸭子类型?

如果一种动物只要行为有相似性,那么我们就可以认为是鸭子。

比如:鸭子会走路和游泳,是鸭子;人也会走路和游泳,也是“鸭子”

class duck():
def walk(self):
print('I walk, i am a duck') def swim(self):
print('i swim,i am a duck') class person():
def walk(self):
print('i walk like a duck') def swim(self):
print('i swim like a duck') def watch_duck(a):
a.walk()
a.swim() small_duck = duck()
watch_duck(small_duck)
# I walk, i am a duck
# i swim,i am a duck
duck_like_man = person()
watch_duck(duck_like_man)
# i walk like a duck
# i swim like a duck

watch_duck接收这个类的对象,但并没有检查对象的类型,便直接调用对象的walk和swim方法。

多态的灵活性和扩展性,便在于它关注的是调用对象如何被使用,而并不关注对象本身是什么。

即,我只关心你是否会走路和游泳,而不关心你究竟是谁。

说回灵活性和拓展性。当你再想增加一个类,比如狗,它也会走路和游泳 。

你只需要增加一个Dog类就可以了。

class Dog():
def walk(self):
print('i walk like a duck') def swim(self):
print('i swim like a duck')

继承

01 继承和重载

什么是继承?

动物需要吃和喝,猫继承自动物,则猫会吃和喝。

什么是重载?

动物需要吃和喝,猫继承自动物,则猫会吃和喝,但是猫喝水是用舔的,因此需要特殊处理(重载)一下。

class Animal:
def eat(self):
print("animal eat")
def drink(self):
print("animal drink") class Cat(Animal):
def drink(self):
print("cat drink by lick") cat = Cat()
cat.eat()
cat.drink()

02 多继承

什么是多继承?

小花是一个大学生(继承自学生),在校期间,她兼职做家教(继承自老师),于是,小花有两个能力(学习和教书)。

继承顺序(MRO查找)

Python支持多继承,但是有继承顺序:

菱形继承【类似广度优先查找】

class D:
def get(self):
print("I'm D") class B(D):
pass class C(D):
def get(self):
print("I'm C") class A(B, C):
pass
a = A()
a.get()
# I'm C

树型继承【类似深度优先查找】

class O:
def get(self):
print("I'm O")
class P:
def get(self):
print("I'm P")
class Z(O):
pass
class Y(P):
pass
class X(Z, Y):
pass
x = X()
x.get()
# I'm O

Python用C3算法处理多继承问题,我们可以用 _mro_ 来查看继承顺序。

print(A.__mro__)
# (<class '__main__.A'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.D'>, <class 'object'>)
print(X.__mro__)
# (<class '__main__.X'>, <class '__main__.Z'>, <class '__main__.O'>, <class '__main__.Y'>, <class '__main__.P'>, <class 'object'>)

一如既往,做个总结

01 封装可以理解为保护隐私;

02 多态的关键是鸭子类型,明白了鸭子类型,理解多态不再困难;

03 继承可用,但多继承需要慎用,如果你非用不可,那必须得研究清楚继承的层次结构;

04 以上三点,是面向对象的核心,也是你日后工作中,会经常用到的,so,它们很重要。

最新文章

  1. SpringMVC 入门
  2. mybatis调用存储过程 无参、带有输入输出参数,输出游标类型的 存储
  3. 神经网络及其PID控制
  4. Opera浏览器导出收藏到Chrome,和几个Chrome的一些小技巧
  5. array_filter、array_map、array_walk解释
  6. Filestream 使用简单步骤
  7. Bundle文件的创建和使用(二)
  8. Struts2文件下载
  9. 高性能Server---Reactor模型-----Socket
  10. Static Final用法
  11. 十大众筹PC:硅谷新生代如何打造下一代计算机
  12. [C#错误] 未找到类型或命名空间名称&quot; &quot; (是否缺少 using 指令或程序集引用?)
  13. 《收藏》对servlet原理讲解特别详细
  14. 【公告】关于8.8MIP组件审核平台故障的说明
  15. java 根据某个数字,计算前后多少天的具体日期
  16. 《学习之道》第八章孤军奋战or组队合作
  17. Struts2源码解析-----转载
  18. 【原创】大数据基础之Hadoop(2)hdfs和yarn最简绿色部署
  19. tensorflow(1) 基础: 神经网络基本框架
  20. 洛谷AC破百题纪念!

热门文章

  1. Tornadofx学习笔记(4)——IconTextFx开源库,整合5000+个字体图标
  2. CF1082A Vasya and Book 题解
  3. ElasticSearch 使用
  4. java 图形化小工具Abstract Window Toolit :画笔Graphics,画布Canvas(),弹球小游戏
  5. java 输入输出IO流 字节流| 字符流 的缓冲流:BufferedInputStream;BufferedOutputStream;BufferedReader(Reader in);BufferedWriter(Writer out)
  6. libevent源码学习(6):事件处理基础——event_base的创建
  7. JAVA上传文件到FTP上
  8. 【LeetCode】1056. Confusing Number 解题报告(C++)
  9. 【LeetCode】350. Intersection of Two Arrays II 解题报告(Java & Python)
  10. 【剑指Offer】不用加减乘除做加法 解题报告(Java)