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.团队信息 团队名称:待就业六人组 团队描述:同舟共济扬帆起,乘风破浪 ...
随机推荐
- Runable和Thread
Java多线程 java中有两种实现多线程的方式: 1. 一种是通过继承Thread类,同时重写run()方法.但是java中,只允许单继承,也就是一个类只能继承一个父类,使得该方式具有一定的局限性, ...
- js中去掉字符串的空格、回车换行
//例如下面这个json串,中间的\n表示换行 var str = "{' retmsg':'success ',\n' trans_date':' 20170906'}"; co ...
- hashCode会出现负数吗,答案是肯定的
先来普及一下基本数据类型的长度: unsigned int 0-4294967295 int -2147483648-2147483647 unsigned long 0-429496 ...
- git相关知识(github,idea等的配置)
本地git提交文件到github上: 1.在github上创建项目 2.使用git clone https://github.com/xxxxxxx/xxxxx.git克隆到本地 3.编辑项目 4.g ...
- Hadoop格式化 From hu-hadoop1/192.168.11.11 to hu-hadoop2:8485 failed on connection exception: java.net.
192.168.11.12:8485: Call From hu-hadoop1/192.168.11.11 to hu-hadoop2:8485 failed on connection excep ...
- iOS 如何优化项目
原文 前言 在项目业务趋于稳定的时候,开发完迭代需求后,我们可能会无所适从,进入一段空白期,但是对于攻城狮来说闲暇不是件好事,所以我们可能总想学点什么,却又没有头绪.这个时候我们就可以考虑完善和优化我 ...
- Java Web(六) JSP
现在的Java Web开发已经很少使用JSP脚本了,业务逻辑都交给Servlet处理,JSP只负责显示视图,所以接下来的内容就对JSP脚本不做叙述了... JSP概述 JSP全名为Java Serve ...
- CAD绘制栏杆5.10
REC绘制一个矩形,(40,40)回车.通过它的中点移动到扶手的中点用移动工具把它往右边稍微移动.在三维图中EXT命令拉伸它,拉到扶手底面.如图选择三维扶手,右击,加栏杆,选择我们绘制的栏杆,单元宽度 ...
- 请问微信小程序let和var以及const有什么区别
在JavaScript中有三种声明变量的方式:var.let.const. var:声明全局变量,换句话理解就是,声明在for循环中的变量,跳出for循环同样可以使用. [JavaScript] 纯文 ...
- IDE 版本
BDS 5 2007 D11 VER180 and VER185 RAD Studio 8 XE D15 VER 220 RAD 18 XE 10.1 Berlin D24 VER310 St ...