类的继承

派生

在子类中重用父类

组合

抽象类

定义:

承指的是类与类之间的关系,是一种什么“是”什么的关系,继承的功能之一就是用来解决代码重用问题.

继承是一种创建新类的方式,在python中,新建的类可以继承一个或多个父类,父类又可以成为基类或超类,新建的类称为派生类或子类.

 # 我们定义的2个英雄都有一些相似的特征和技能.都属于英雄类,那么我们就可以定义个英雄类,然后让英雄继承英雄类的特征和技能

 class Hero:
def __init__(self, name, life_value, aggressivity):
self.name = name
self.life_value = life_value
self.aggressivity = aggressivity def attck(self,enemy):
enemy.life_value -= self.aggressivity class Garen(Hero):
pass class Riven(Hero):
pass print(Garen.__bases__) # 查看Graren的父类.
g1 = Garen("草丛伦", 100, 50)
r1 = Riven("兔女郎", 80, 60)
print(r1.life_value)
# A, 我们通过Garen这个类,来产生一个对象g1.但是Garen这个类中,我们并未定义__init__方法.但是我们也定义成功了,并没有报错.为什么呢?
# B, 因为Garen这个类继承了Hero这个父类中的数据属性和函数属性.

继承类和查看父类

提示:如果没有指定基类,python的类会默认继承object类,object是所有python类的基类,它提供了一些常见方法(如__str__)的实现。

派生

当然子类也可以添加自己新的属性或者在自己这里重新定义这些属性(不会影响到父类),需要注意的是,一旦重新定义了自己的属性且与父类重名,那么调用新增的属性时,就以自己为准了。简单的来说,派生就是子类自己定义自己独有的特征或方法.

继承的实现原理

python到底是如何实现继承的,对于你定义的每一个类,python会计算出一个方法解析顺序(MRO)列表,这个MRO列表就是一个简单的所有基类的线性顺序列表.

>>> F.mro() #等同于F.__mro__
[<class '__main__.F'>, <class '__main__.D'>, <class '__main__.B'>,
<class '__main__.E'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]

所有父类的MRO列表并遵循如下三条准则:

  1. 子类会先于父类被检查
  2. 多个父类会根据它们在列表中的顺序被检查
  3. 如果对下一个类存在两个合法的选择,选择第一个父类

继承的查找:

 #验证多继承情况下的属性查找

 class A:
# def test(self):
# print('from A')
pass class B(A):
# def test(self):
# print('from B')
pass class C(A):
# def test(self):
# print('from C')
pass class D(B):
# def test(self):
# print('from D')
pass class E(C):
# def test(self):
# print('from E')
pass class F(D,E):
# def test(self):
# print('from F')
pass #F,D,B,E,C,A print(F.mro())
# f=F()
# f.test()

查找方式

在PY3中,都是新式类,没有经典类了.

经典类:在py2中.定义一个类.class Her0().如果括号里,没有继承基类object.它就是一个经典类.如果class Hero(object),那么就是一个新式类

py3中.如果一个类没有继承,那么默认继承object.

子类中重用父类

方式1,指名道姓的方式.(不依赖与继承)

 class Hero:
def __init__(self, name, life_value, aggressivity):
self.name = name
self.life_value = life_value
self.aggressivity = aggressivity def attck(self,enemy):
enemy.life_value -= self.aggressivity class Garen(Hero): def __init__(self, name, life_value, aggressivity, weapon):
Hero.__init__(self,name, life_value, aggressivity) # 指名道姓的调用父类中的方法.
self.weapon = weapon def attck(self,enemy):
Hero.attck(self,enemy) # 指名道姓的调用父类中的方法.
print("in Garen class") class Riven(Hero):
pass g1 = Garen("草丛伦", 100, 50,"黑切") print(g1.__dict__) # 查看g1的dict中,已经有了黑切.

指名道姓法

方式2,super()  (依赖于继承)

 # 方式2, super() 依赖继承
class Hero:
def __init__(self, name, life_value, aggressivity):
self.name = name
self.life_value = life_value
self.aggressivity = aggressivity def attck(self,enemy):
enemy.life_value -= self.aggressivity class Garen(Hero): def __init__(self, name, life_value, aggressivity, weapon):
# Hero.__init__(self,name, life_value, aggressivity) # 指名道姓的调用父类中的方法.
# super(Garen,self).__init__(name,life_value,aggressivity)
super().__init__(name,life_value,aggressivity) # 简写
self.weapon = weapon def attck(self,enemy):
# Hero.attck(self,enemy) # 指名道姓的调用父类中的方法.
# super(Garen,self).attck(enemy) # super方法,括号里的Garen的位置是子类的名称,self是生成对象的名称.后面是调用的方法.
super().attck(enemy) # 在py3中,可以简写成这样.
print("in Garen class") class Riven(Hero):
pass g1 = Garen("草丛伦", 100, 50,"黑切")
r1 = Riven("兔女郎瑞文", 80,50)
g1.attck(r1)
print(r1.life_value) print(g1.__dict__) # 查看g1的dict中,已经有了黑切.

super方法

 class A:
def f1(self):
print("from A")
super().f1() #在这里调用super().f1()的时候.基于的是C这个类的mro列表进行查找的.并不是说,在A类中调用super,就是在A类中,查找A的父类中的f1方法 class B:
def f1(self):
print("from B") class C(A,B):
pass print(C.mro())
i = C()
i.f1() # 查找f1的是,都是基于对象i来进行查找的.如果i里没有f1方法.那么就去它的类中查找,如果类中没有,就去类所继承的父类中按照mro列表查找.

super继承验证

组合

软件重用的重要方式除了继承之外还有另外一种方式,即:组合

组合指的是,在一个类中以另外一个类的对象作为数据属性,称为类的组合.

组合与继承都是有效地利用已有类的资源的重要方式。但是二者的概念和使用场景皆不同,

1.继承的方式

通过继承建立了派生类与基类之间的关系,它是一种'是'的关系,比如白马是马,人是动物。

当类之间有很多相同的功能,提取这些共同的功能做成基类,用继承比较好,比如老师是人,学生是人

2.组合的方式

用组合的方式建立了类与组合的类之间的关系,它是一种‘有’的关系,比如教授有生日,教授教python和linux课程,教授有学生s1、s2、s3...

 class People:
"""定义人类"""
school = "luffycity"
def __init__(self, name, age, sex):
self.name = name
self.age = age
self.sex =sex class Teacher(People):
"""定义一个人教师类"""
def __init__(self, name, age, sex, level, salary):
super().__init__(name, age, sex)
self.level = level
self.salary = salary def teach(self):
print("%s is teaching" % self.name) class Students(People):
"""定义一个学生类"""
def __init__(self, name, age, sex, grade):
super().__init__(name, age, sex)
self.grade = grade def learn(self):
print("%s is learning" % self.name) class Course:
"""定义一个课程类"""
def __init__(self, course_name, course_price, course_period):
self.course_name = course_name
self.course_price = course_price
self.course_period = course_period def tell_info(self):
print("课程名:%s, 课程价格:%s, 课程周期:%s" % (self.course_name, self.course_price, self.course_period)) class Bron_date:
"""定义一个生日类"""
def __init__(self, year, mon, day):
self.year = year
self.mon = mon
self.day = day
def tell_info(self):
print("生日:%s年%s月%s日" % (self.year, self.mon, self.day)) # t1 = Teacher("alex", 22, "男", "一级", 100000)
#生成一个stu1的学生对象
stu1 = Students("杰克", 18, "男", "python全栈开发")
#生成一个python的课程对象
python = Course("python", 8999, "6mons")
# 把python对象赋给stu1.course.学生stu1有课程.这里就是组合
stu1.course = python
#输入sut1的课程信息

组合实例

抽象类

如果说类是从一堆对象中抽取相同的内容而来的,那么抽象类就是从一堆类中抽取相同的内容而来的,内容包括数据属性和函数属性。

作用:

抽象类规范了子类的属性或者方法的定义规范.

抽取子类相似的属性或特征,组成一个新的类.就叫抽象类,抽象类只能被继承,不能被实例化.

  抽象类,归一化
import abc
# 生成一个抽象类,需要借助abc这个模块.
class Animal(metaclass=abc.ABCMeta): # 抽取子类相似的属性或特征,组成一个新的类.就叫抽象类,抽象类只能被继承,不能被实例化.
@abc.abstractmethod #加上这个装饰器,子类在继承抽象类的时候,必须有run,eat的方法.
def run(self):
pass
@abc.abstractmethod
def eat(self):
pass class People(Animal):
def run(self):
print("people is running.")
def eat(self):
print("people is eating") class Dog(Animal):
def run(self):
print("dog is running") def eat(self):
print("dog is eating")
class Pig(Animal):
def run(self):
print("pig is running") # def eat(self): # 如果我们注释掉这行,就无法正常实例化一个对象,因为缺少一个eat方法.
# print("pig is eating") p1 = People()
d1 = Dog()
p1 = Pig() p1.run()
d1.run()
p1.run()

生成抽象类

Day 5-2 类的继承和派生,重用的更多相关文章

  1. [C++]类的继承与派生

    继承性是面向对象程序设计的第二大特性,它允许在既有类的基础上创建新类,新类可以继承既有类的数据成员和成员函数,可以添加自己特有的数据成员和成员函数,还可以对既有类中的成员函数重新定义.利用类的继承和派 ...

  2. 模块的封装之C语言类的继承和派生

    [交流][微知识]模块的封装(二):C语言的继承和派生 在模块的封装(一):C语言的封装中,我们介绍了如何使用C语言的结构体来实现一个类的封装,并通过掩码结构体的方式实 现了类成员的保护.这一部分,我 ...

  3. 09--c++ 类的继承与派生

    c++ 类的继承与派生   一.基本概念 1.类的继承,是新的类从已有类那里得到已有的特性.或从已有类产生新类的过程就是类的派生.原有的类称为基类或父类,产生的新类称为派生类或子类.   2.派生类的 ...

  4. C++学习笔记:07 类的继承与派生

    课程<C++语言程序设计进阶>清华大学 郑莉老师) 基本概念 继承与派生的区别: 继承:保持已有类的特性而构造新类的过程称为继承. 派生:在已有类的基础上新增自己的特性(函数方法.数据成员 ...

  5. 4-13 object类,继承和派生( super) ,钻石继承方法

    1,object 类 object class A: ''' 这是一个类 ''' pass a = A() print(A.__dict__) # 双下方法 魔术方法 创建一个空对象 调用init方法 ...

  6. Python基础(16)_面向对象程序设计(类、继承、派生、组合、接口)

    一.面向过程程序设计与面向对象程序设计 面向过程的程序设计:核心是过程,过程就解决问题的步骤,基于该思想设计程序就像是在设计一条流水线,是一种机械式的思维方式 优点:复杂的问题的简单化,流程化 缺点: ...

  7. 对C++类的继承和派生的理解

    C++中的继承是类与类之间的关系,是一个很简单很直观的概念,与现实世界中的继承类似,例如儿子继承父亲的财产. 1.继承(Inheritance)可以理解为一个类从另一个类获取成员变量和成员函数的过程. ...

  8. Python3 面向对象-类的继承与派生

    1.什么是继承? 继承是一种创建新类的方式,新建的类可以继承一个或多个父类(python支持多继承),父类可称为基类或超类,新建的类称为派生类和或子类. 子类会遗传父类的属性,从而解决代码重用问题. ...

  9. C++——类的继承(派生)

    类的继承就是子类可以拥有父类的成员变量和成员函数 //public 修饰的成员变量 方法 在类的内部 类的外部都能使用//protected: 修饰的成员变量方法,在类的内部使用 ,在继承的子类中可用 ...

随机推荐

  1. vue源码分析—数据绑定

    放进沙里附件拉萨就发牢骚:剑飞:啊撒

  2. Java基础知识点(二)

    前言:Java的基础知识点不能间断. 1.Array和ArrayList的区别 关于Array的用法,参看:http://blog.csdn.net/b_11111/article/details/5 ...

  3. UVA690-Pipeline Scheduling(dfs+二进制压缩状态)

    Problem UVA690-Pipeline Scheduling Accept:142  Submit:1905 Time Limit: 3000 mSec  Problem Descriptio ...

  4. UVA140-Bandwidth(搜索剪枝)

    Problem UVA140-Bandwidth Time Limit: 3000 mSec  Problem Description Given a graph (V, E) where V is ...

  5. 解决vaio s13笔记本 ubuntu重启卡屏问题

    终端 sudo gedit /etc/default/grub 找到GRUB_CMDLINE_LINUX_DEFAULT="quiet splash",添加内核启动参数reboot ...

  6. 【转】js中通过docment.cookie获取到的内容不完整! 在浏览器的application里的cookie里可以看到完整的cookie,个别字段无法通过document.cookie获取。 是否有其他办法可以获取到??

    js中通过docment.cookie获取到的内容不完整!在浏览器的application里的cookie里可以看到完整的cookie,个别字段无法通过document.cookie获取.是否有其他办 ...

  7. mysql 数据库磁盘占用量统计

    查看某个表的磁盘占用量 select (data_length+index_length)/1024/1024 M from information_schema.tables where table ...

  8. nginx+tomcat9+redisson+redis+jdk1.8简单实现session共享

    一.环境安装 由于资源限制,在虚拟机中模拟测试,一台虚拟机,所有软件均安装到该虚拟机内 安装系统:CentOS Linux release 7.4.1708 (Core) CentOS安装选择版本:B ...

  9. JS中AOP的实现和运用

    在编写js的时候,我们有时会遇到针对某种场景做处理,比如在方法开始的时候校验参数,执行方法前检查权限,或是删除前给出确认提示等等.这些校验方法.权限检测.确认提示,规则可能都是相同的,在每个方法前去调 ...

  10. JavaScript原生秒表、计时器

    可以开始.暂停.清除. 效果图: 下面贴代码: <!DOCTYPE html> <html lang="en"> <head> <meta ...