2019-03-27-day020-单继承与多继承
昨日回顾
类的加载顺序
- 类内部的代码什么时候执行?
- 除了方法里面的代码
- 其余的所有内容都是在执行这个文件的时候就从上到下依次执行的
- 不需要调用
- 如果有同名的方法、属性,总是写在后面的会生
class A:
wahaha = 'adGa'
def wahaha(self):
pass
a = A()
print(a.wahaha) # 就是后加载进来的方法覆盖了之前加载的属性
类和对象的命名空间
- 类的命名空间 是在定义类的阶段被加载进来的:
- 静态变量、类变量 —— 直接定义在类中的变量
- 动态变量、方法 —— 定义在类中的函数
- 魔术方法、双下方法
- 内置的方法 :__init__
- 内置的变量 : __dict__
- 对象的命名空间 实例化的时候创建出来的
- 类指针、类对象指针 执行init之前就已经在了
- 对象的属性 是在执行init以及之后被添加的
class Student:
'''这里是对学生类的功能描述'''
print('123')
print(Student.__dict__)
print(Student.__doc__)
print(Student.__class__)
a = 3
b = 2
def fun():
a = 4
def inner():pass
class A:
a = 1
def func(self):
pass
print(a)
print(A.a)
class A: # parameters形参 arguments实参
pass
a = A()
#init这个东西你在定义一个类的时候
#假如没有什么属性是你想添加给对象的,你也可以不写init
- 组合
- 一个类的对象作为另一个类对象的属性
- 两个类
- 人和武器
- 学生和课程
- 圆环和圆
class Student:
def __init__(self,name,age,course):
self.name = name
self.age = age
self.course = course # self.course = python
class Course:
def __init__(self,name,price,period):
self.name = name
self.price = price
self.period = period
python = Course('python',20000,'6 months') # python是一个课程对象
print(python.name)
ju = Student('菊哥',30,python)
#一个类的属性 是一个对象
Student类的course属性 是python对象
#学生的课程属性 和 python对象组合了
#可以通过学生 找到python 可以通过python找到python课程的名字、价格、周期
self.course = python
self.course.name = python.name
print(ju.course.name)
print(ju.course.price)
扩展
ju.name # 字符串
ju.name.strip()
ju是Student类的对象
ju.name是一个字符串 是str的一个对象
Student类 和 str类 组合
ju.age
ju是Student类的对象
ju.age是int的一个对象
Student类 和 int类 组合
今日内容
- 面向对象三大特性
- 继承 *****
- 多态 *
- 封装 *****
- 继承 *****
- 单继承 可以有效的帮我们提高代码的重用性
- 我们写代码的时候
- 多继承
- 规范复杂的功能与功能之间的关系
- 工作原理能够帮助你去看源码
- 面试重点
- 单继承 可以有效的帮我们提高代码的重用性
单继承
class A(类的名字B):
pass
##A就变成了B的儿子
# B是 父类、基类、超类
# A是 子类、派生类
class Parent:
pass
class Son(Parent):
pass
print(Son.__bases__)
##多继承
class Parent1:
pass
class Parent2:
pass
class Son(Parent1,Parent2):
pass
print(Son.__bases__)
为什么要继承
- 两个类
- 猫 :
- 属性 :名字,品种,眼睛的颜色
- 动作 :吃、喝、爬树、抓老鼠
- 狗
- 属性:名字,品种
- 动作 :吃、喝、抓老鼠、拆家
- 猫 :
class Cat(object):
def __init__(self,name,kind,eyes_color):
self.name = name
self.kind = kind
self.eyes_color = eyes_color
def eat(self,food):
print('%s eat %s'%(self.name,food))
def drink(self):
print('%s drink water'%(self.name))
def climb(self):
print('%s climb tree'%(self.name))
def catch(self):
print('%s catch mouse'%(self.name))
class Dog(object):
def __init__(self,name,kind):
self.name = name
self.kind = kind
def eat(self,food):
print('%s eat %s'%(self.name,food))
def drink(self):
print('%s drink water'%(self.name))
def catch(self):
print('%s catch mouse'%(self.name))
def chai(self):
print('%s cha'%(self.name))
class Animal(object):
def __init__(self,name,kind):
self.name = name
self.kind = kind
def eat(self,food):
print('%s eat %s'%(self.name,food))
class Cat(Animal):pass
class Dog(Animal):pass
hua = Cat('小花','橘猫')
print(hua)
print(hua.name)
print(hua.kind)
hua.eat('小鱼干')
hei = Dog('小黑','中华田园犬')
print(hei.name)
print(hei.kind)
hei.eat('单身狗粮')
class Animal(object):
def __init__(self,name,kind):
self.name = name
self.kind = kind
def eat(self,food):
print('%s eat %s'%(self.name,food))
class Cat(Animal):
def __init__(self,name,kind,eyes_color):
self.eyes_color = eyes_color
Animal.__init__(self,name,kind) # 在子类和父类有同名方法的时候,默认只执行子类的方法
# 如果想要执行父类的方法,可以在子类的方法中再 指名道姓 的调用父类的方法
class Dog(Animal):pass
hua = Cat('小花','橘猫','蓝色')
print(hua.__dict__)
当Cat自己拥有__init__的时候,就不再调用父类的了
class Animal:
def __init__(self,name,kind):
self.name = name
self.kind = kind
def eat(self,food):
print('%s eat %s'%(self.name,food))
class Cat(Animal):
def __init__(self,name,kind,eyes_color):
self.eyes_color = eyes_color
# super(Cat,self).__init__(name,kind)
# super().__init__(name,kind) # 相当于执行父类的init方法
# Animal.__init(self,name,kind)
class Dog(Animal):pass
hua = Cat('小花','橘猫','蓝色')
print(hua.__dict__)
class Animal(object):
def __init__(self,name,kind):
self.name = name
self.kind = kind
def eat(self,food):
print('%s eat %s'%(self.name,food))
def drink(self):
print('%s drink water'%(self.name))
def catch(self):
print('%s catch mouse'%(self.name))
class Cat(Animal):
def __init__(self,name,kind,eyes_color):
self.eyes_color = eyes_color # 派生属性
# super(Cat,self).__init__(name,kind)
super().__init__(name,kind) # 相当于执行父类的init方法
# Animal.__init(self,name,kind)
def climb(self): # 派生方法
print('%s climb tree'%self.name)
class Dog(Animal):
def chai(self):
print('%s cha'%(self.name))
hua = Cat('小花','橘猫','蓝色')
hua.eat('小鱼干')
hua.climb()
子类 父类
子类的对象
想要使用某一个名字
- 如果自己有 就用自己的
- 如果自己没有 就用父类的
- 如果父类也没有 就报错
####如果想要使用的名字父类子类都有 - 既想使用子类的,也想使用父类的,那就在子类的方法中使用
- 父类名.方法名(self,参数1,参数2)
- super().方法名(参数1,参数2)
class A:pass
class A(object):pass
print(A.__bases__)
object类
object类是A的父类
#在python3当中,所有的类都继承object类,所有的类都是新式类
#所有的类的类祖宗 都是object
#父类是object的类 —— 新式类
class A(object):
pass
a = A() # 总是要调用init的,如果我们不写,实际上就调用父类object的__init__方法了
人狗大战
class Animal(object):
def __init__(self,name,blood,ad):
self.name = name
self.hp = blood
self.ad = ad
class Dog(Animal):
def __init__(self,name,blood,ad,kind):
super().__init__(name,blood,ad)
self.kind = kind
def bite(self,person):
person.hp -= self.ad
print('%s攻击了%s,%s掉了%s点血' % (self.name, person.name, person.name, self.ad))
class Person(Animal):
def __init__(self,name,hp,ad,sex):
super().__init__(name,hp,ad)
self.sex = sex
def fight(self,dog):
dog.hp -= self.ad
print('%s攻击了%s,%s掉了%s点血'%(self.name,dog.name,dog.name,self.ad))
hei = Dog('小黑',300,20,'哈士奇')
alex = Person('alex',20,1,'不详')
alex.fight(hei)
print(hei.hp)
hei.bite(alex)
print(alex.hp)
抽象
继承
- 组合 :什么有什么
- 继承 :什么是什么的关系
- 先想描述的对象
- 先写出对象所对应的类
- 发现多个类之间有相同的代码
- 把相同的代码提取出来,搞成一个父类
先抽象,再继承
对象 -->类 -->基类
基类 -继承-> 子类 -实例化-> 对象
多继承
各种动物,每一种动物都是一个类
1. 青蛙、天鹅、老虎、鹦鹉
2. 青蛙 :走,游泳
3. 天鹅 :走,游泳,飞
4. 老虎 :走,游泳
5. 鹦鹉 :走,飞,说话
class FlyAnimal:
def fly(self):pass
class SwimAnimal:
def swim(self):pass
def eat():pass
class WalkAnimal:
def walk(self):pass
def eat():pass
class Frog(SwimAnimal,WalkAnimal): pass
class Tiger(SwimAnimal,WalkAnimal):pass
class Swan(FlyAnimal,SwimAnimal,WalkAnimal):pass
class Parrot(FlyAnimal,WalkAnimal):
def talk(self):
pass
- 多继承 是python语言中特有的继承方式
- java语言中不支持多继承的,C#也不支持多继承
- C++支持多继承
多继承和单继承是一样的
- 如果对象使用名字
- 是子类中有的,那么一定用子类的
- 子类没有,可以到多个父类中去寻找
##如果多个和父类都有,那么用谁的
钻石继承问题
class A(object):
def func(self):
print('a')
class B(A):
pass
# def func(self):
# print('b')
class C(A):
pass
# def func(self):
# print('c')
class D(B,C):
pass
# def func(self):
# print('d')
d = D()
d.func()
乌龟继承问题
class A(object):
def func(self):
print('a')
class B(A):
pass
# def func(self):
# print('b')
class C(A):
pass
# def func(self):
# print('c')
class D(B):
pass
# def func(self):
# print('d')
class E(C):
pass
# def func(self):
# print('e')
class F(D,E):
pass
# def func(self):
# print('f')
f = F()
f.func()
广度优先
C3算法
99%的情况都可以用眼睛看出来
但是仍然有1%的情况是看不出来的
C3算法是怎么计算的
class A(object):
def func(self):
print('a')
class B(A):
pass
def func(self):
print('b')
class C(A):
pass
def func(self):
print('c')
class F:
pass
def func(self):
print('f')
class D(A,F):
pass
# def func(self):
# print('d')
class E(B,C,F):
pass
def func(self):
print('e')
class G(C,D):
pass
def func(self):
print('g')
class H(E,G):
pass
def func(self):
print('h')
print(H.mro()) # 就是帮助我们来展示c3算法的继承顺序
C3算法
A= [AO]
B = B ,B节点的父类对应的顺序
B = B ,A节点顺序
B = B ,[AO]
提取第一个点
# 如果从左到右第一个类,
# 在后面的继承顺序中也是第一个,或者不再出现在后面的继承顺序中
# 那么就可以把这个点提取出来,作为继承顺序中的第一个类
B = [AO]
BA = [O]
B这个节点的继承顺序 :[BAO]
C = C,[AO]
C = [AO]
CA = [O]
C这个节点的继承顺序 :[CAO]
l(D) = D + [BAO]
D = [BAO]
[DBAO]
l(E) = E + [CAO]
[ECAO]
L[F] = F,[DBAO],[ECAO]
[F] = [DBAO],[ECAO]
[FD] = [BAO],[ECAO]
[FDB] = [AO],[ECAO]
[FDB] = [AO],[ECAO]
[FDBE] = [AO],[CAO]
[FDBEC] = [AO],[AO]
[FDBECA] = [O],[O]
[FDBECAO]
经典类和新式类
- py2.7 经典类
- 2个图
- 看 C3 mro
- 你自己去网上找一张图
class A(object):
def func(self):
print('a')
class B(A):
pass
def func(self):
super().func()
print('b')
class C(A):
pass
def func(self):
super().func()
print('c')
class D(B,C):
pass
def func(self):
super().func()
print('d')
b = B()
b.func()
#在多继承中,super就只和mro顺序有关系,和父类子类没有关系了
总结
- python的继承
- 提高代码的重用性,减少了代码的冗余
- 单继承
- 子类有的就用子类的
- 没有的就用父类的
- 如果父类子类都想用,super(),父类名.方法名
- 多继承
- 新式类 :继承object
- py2 要主动继承object才是新式类,默认是经典类
- 遵循的是广度优先算法,C3算法
- 有super()的,super遵循mro顺序的
- 有mro()方法
- 经典类 :不继承object
- 多个类之间去寻找方法的时候遵循深度优先
- 没有super方法也没有mro
- 新式类 :继承object
2019-03-27-day020-单继承与多继承的更多相关文章
- 2019.03.27 读书笔记 关于GC垃圾回收
在介绍GC前,有必要对.net中CLR管理内存区域做简要介绍: 1. 堆栈:用于分配值类型实例.堆栈主要操作系统管理,而不受垃圾收集器的控制,当值类型实例所在方法结束时,其存储单位自动释放.栈的执行效 ...
- 2019.03.27【GDOI2019】模拟 T3
题目大意 给出$n$, $p$, 求有多少长度为$n$的排列可以被分成三个上升子序列, 数量对$p$取模, 数据范围 $3 \leq n \leq 500$. 思路 首先让我们考虑如果有一个排列,如何 ...
- python学习 day20 (3月27日)----(单继承多继承c3算法)
继承: 提高代码的重用性,减少了代码的冗余 这两个写法是一样的 Wa('青蛙').walk() #青蛙 can walk wa = Wa('青蛙') wa.walk() #青蛙 can walk 1. ...
- Lua面向对象----类、继承、多继承、单例的实现
(本文转载)学习之用,侵权立删! 原文地址 http://blog.csdn.net/y_23k_bug/article/details/19965877?utm_source=tuicool&a ...
- C++对象模型:单继承,多继承,虚继承
什么是对象模型 有两个概念可以解释C++对象模型: 语言中直接支持面向对象程序设计的部分.对于各种支持的底层实现机制. 类中成员分类 数据成员分为静态和非静态,成员函数有静态非静态以及虚函数 clas ...
- C++在单继承、多继承、虚继承时,构造函数、复制构造函数、赋值操作符、析构函数的执行顺序和执行内容
一.本文目的与说明 1. 本文目的:理清在各种继承时,构造函数.复制构造函数.赋值操作符.析构函数的执行顺序和执行内容. 2. 说明:虽然复制构造函数属于构造函数的一种,有共同的地方,但是也具有一定的 ...
- JAVA之旅(六)——单例设计模式,继承extends,聚集关系,子父类变量关系,super,覆盖
JAVA之旅(六)--单例设计模式,继承extends,聚集关系,子父类变量关系,super,覆盖 java也越来越深入了,大家加油吧!咱们一步步来 一.单例设计模式 什么是设计模式? JAVA当中有 ...
- [2019.03.25]Linux中的查找
TMUX天下第一 全世界所有用CLI Linux的人都应该用TMUX,我爱它! ======================== 以下是正文 ======================== Linu ...
- 2019.03.03 - Linux搭建go语言交叉环境
编译GO 1.6版本以上的需要依赖GO 1.4版本的二进制,并且需要把GOROOT_BOOTSTRAP的路径设置为1.4版本GO的根目录,这样它的bin目录就可以直接使用到1.4版本的GO 搭建go语 ...
- Alpha冲刺(4/10)——2019.4.27
所属课程 软件工程1916|W(福州大学) 作业要求 Alpha冲刺(4/10)--2019.4.27 团队名称 待就业六人组 1.团队信息 团队名称:待就业六人组 团队描述:同舟共济扬帆起,乘风破浪 ...
随机推荐
- 关于final static修饰的常量部署后没有更新的问题
出现问题的场景是这样的: 项目中有个专门放流程Key值常量的类FlowConstants.java,其中这些常量都用了final static 修饰.某天因为修改了流程,相应的key值也改变了,所以直 ...
- html5 meta标签的认知储备
在开发移动或者PC端的时候除了'<meta charset="UTF-8">'这个设置编码格式的meta标签,还有一些其他方面的设置 一.<meta name=& ...
- 安装docker No package docker available
安装docker 时候出现以下问题 yum -y install dockerLoaded plugins: fastestmirrorDetermining fastest mirrors * ba ...
- Slony-I同步复制部署
本次测试环境 IP 10.189.102.118 10.189.100.195 10.189.100.226 PGHOME /usr/local/pgsql /usr/local/pgsql /usr ...
- 0.5px的宽度的边框
方法1: .border { position: relative;} .border:before { content: "";/* 注意这里为双引号 */ ...
- Laravel 更新数据时在表单请求验证中排除自己,检查指定字段唯一性
原文地址:https://moell.cn/article/24 不错的laravel网站 需求场景 修改用户信息时,在表单请求验证中排除当前邮箱所在的记录行,并检查邮箱的唯一性. Laravel版本 ...
- python 自然语言处理(二)____获得文本语料和词汇资源
一, 获取文本语料库 一个文本语料库是一大段文本.它通常包含多个单独的文本,但为了处理方便,我们把他们头尾连接起来当做一个文本对待. 1. 古腾堡语料库 nltk包含古腾堡项目(Project Gut ...
- C++解析七-重载运算符和重载函数
重载运算符和重载函数C++ 允许在同一作用域中的某个函数和运算符指定多个定义,分别称为函数重载和运算符重载.重载声明是指一个与之前已经在该作用域内声明过的函数或方法具有相同名称的声明,但是它们的参数列 ...
- 常用6种type的form表单的input标签分析及示例
<input> 标签用于搜集用户信息. 根据不同的 type 属性值,输入字段拥有很多种形式.输入字段可以是文本字段.复选框.掩码后的文本控件.单选按钮.按钮等等. 在这里博主介绍6中ty ...
- tomcat 线程数与 mysql 连接数综合调优
目前线上系统包含 数据收集+数据分析+中心服务,三个均为 tomcat,共用一个mysql服务. 由于tomcat最大线程数200 *3 =600,最大并发时,会有600个jdbc连接.当然这是极端情 ...