继承,派生
时间:2019-10-10
本文章向大家介绍继承,派生,主要包括继承,派生使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
目录
继承
什么是继承
继承指的是新建类的方法,新建的类称之为子类或派生类;
子类继承的类为父类,也称之为基类或超类。
继承的特征
子类可以继承父类的属性(特征与技能),并且可以派生出自己的属性(特征与技能)
为什么要继承
继承的目的是为了减少代码的冗余(减少代码量)
如何实现继承
- 首先要确定谁是父类,谁是子类
- 在定义类时,子类+(),()内写父类,实现继承
class 父:
pass
class 子(父):
pass
class Parent1:
pass
class Parent2:
pass
class Sub1(Parent1):
pass
class Sub2(Parent1, Parent2):
pass
# 查看继承的父类: __bases__, 用来查找当前类的父类
print(Sub1.__bases__) # (<class '__main__.Parent1'>,)
print(Sub2.__bases__) # (<class '__main__.Parent1'>, <class '__main__.Parent2'>)
注:一个子类可以继承多个父类,这是python独有的,其他语言只能一个子类继承一个父类
继承与抽象
如何寻找继承关系
想要寻找继承关系,首先要先抽象,再继承
抽象:抽象指的是抽取相似的地方
- 先抽象(抽象思想)
- 奥巴马 ---> 人类 ---> 动物类
- 猪坚强 ---> 猪类 ---> 动物类
- 阿黄 ---> 狗类 ---> 动物类
- 抽象定义动物类,为父类
- 再继承(程序中)
- 奥巴马对象 ---> 调用人类 ---> 继承动物类
- 猪坚强对象 ---> 调用猪类类 ---> 继承动物类
- 阿黄对象 ---> 调用狗类 ---> 继承动物类
继承的关系
- 对象是特征与技能的结合体
- 类是一系列相同对象的特征与技能的结合体
- 继承是一系列形同类的特征与技能的结合体
class People:
school = 'oldboy'
def __init__(self, name, age, sex):
self.name = name
self.age = age
self.sex = sex
class Teacher(People):
def change_score(self):
print(f'{self.name}老师正在该分数。。。')
class Student(People):
def choose_course(self):
print(f'{self.name}同学正在选课。。。')
tea1 = Teacher('tank', 18, 'male')
stu1 = Student('小明', 18, 'male')
tea1.change_score()
stu1.choose_course()
'''
tank老师正在该分数。。。
小明同学正在选课。。。
'''
对象属性的查找顺序
- 对象查找属性会先从对象的名称空间中查找。
- 若对象没有,则从类中查找
- 若当前类是子类,并且没有对象找的属性,就去父类中查找
- 若父类中也没有机会报错
注:对象查找属性,若子类有,不管父类有没有,以子类的为准
验证查找顺序:
class Foo:
def f1(self):
print('Foo.f1')
def f2(self):
print('Foo.f2')
self.f1()
class Soo(Foo):
def f1(self):
print('Soo.f1')
soo_obj = Soo()
soo_obj.f2()
'''
Foo.f2
Soo.f1
'''
首先soo_obj
从对象自身找,没有去子类Soo中找,没找到,再去父类Foo中找,找到了打印'Foo.f2',接着就是self.f1()
,self就是对象本身,按照对象---> 子类--->父类的顺序找,再子类Soo中找到了打印'Soo.f1'
派生
派生指的是子类继承父类的属性,并且派生出新的属性。
子类派生出新的属性,若与父类的属性相同,则以子类的为准。
继承是谁与数的关系,指的是类与类的关系,子类与父类是从属关系
派生方法一(类调用)
直接通过父类.__init__
,把__init__
当作普通函数使用。
class People:
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):
People.__init__(self, name, age, sex)
self.level = level
self.salary = salary
class Student(People):
def __init__(self, name, age, sex, course):
People.__init__(self, name, age, sex)
self.course = course
def choose_course(self):
print(f'{self.name} is choosing {self.course}')
tea1 = Teacher('tank', 18, 'male', 9, '3.0')
stu1 = Student('小明', 18, 'male', 'python')
stu1.choose_course()
'''
小明 is choosing python
'''
派生方法二(super)
- super是一个特殊的类,在子类中调用super()会得到一个特殊的对象,通过"."指向父类的名称空间
super().__init__
(不用为self传值)
class People:
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
class Student(People):
def __init__(self, name, age, sex, course):
super().__init__(name, age, sex)
self.course = course
def choose_course(self):
print(f'{self.name} is choosing {self.course}')
tea1 = Teacher('tank', 18, 'male', 9, '3.0')
stu1 = Student('小明', 18, 'male', 'python')
stu1.choose_course()
新式类与经典类
- 在python2中,才会有新式类与经典类之分
- 在python3中,所有的类都是新式类
新式类
- 继承object的类都是新式类
- python3中,子类不继承自定义的类,默认继承object
经典类
在python2中,凡是没有继承object的类都是经典类
mro查看继承顺序
mro(): 是python内置的函数,用来查看当前类的继承顺序,在多继承的情况下
class A:
pass
class B:
pass
class C(A, B):
pass
print(C.mro())
# [<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>]
钻石继承(菱形继承)
在多继承的情况下形成钻石继承
- 经典类: 深度优先
- 新式类: 广度优先
修改json数据格式
import json
from datetime import datetime
from datetime import date
dic = {
'name': 'tank',
'today1': date.today(),
'today2': datetime.today()
}
class MyJson(json.JSONEncoder):
def default(self, o):
# 判断o是否是datetime的一个实例
if isinstance(o, datetime): # instance 是python内置的函数,可以传两个参数,判断参数一是否是参数二的一个实例
return o.strftime('%Y-%m-%d %X')
elif isinstance(o, date):
return o.strftime('%Y-%m-%d %X')
else:
# 继承父类default方法的功能
return super().default(self, o)
res = json.dumps(dic, cls=MyJson) # cls=None, 默认指向的是原json的JSONEncoder
print(res)
'''
{"name": "tank", "today1": "2019-10-10 00:00:00", "today2": "2019-10-10 17:00:20"}
'''
原文地址:https://www.cnblogs.com/setcreed/p/11650266.html
- MySQL排序内部原理探秘
- Uva----------(11078)Open Credit System
- 学习HTML5之塔克大战(详细记录)
- 学习HTML5之新特性标签一览(详细)
- poj----(1251)Jungle Roads(最小生成树)
- poj-------(2240)Arbitrage(最短路)
- MySQL在线DDL修改表结构的简单经验分享
- HDUOJ-----(1162)Eddy's picture(最小生成树)
- hduoj----1142A Walk Through the Forest(记忆化搜索+最短路)
- java设计之简单的JAVA计算器
- Java之线程———GUI线程(包含打字游戏和计时器俩个GUI实列)
- la----3695 City Game(最大子矩阵)
- poj------(3468)A Simple Problem with Integers(区间更新)
- hdu-------(1698)Just a Hook(线段树区间更新)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- SAP CRM状态字段下拉列表里数据的填充原理
- SAP CRM订单状态管理的一些重要的数据库表
- Angular应用的依赖注入调试
- 给Angular应用增添搜索Search功能
- Angular应用一个创建场景的问题分析
- WPF 最简逻辑实现多指顺滑的笔迹书写
- WPF 如何确定应用程序开启了 Pointer 触摸消息的支持
- Hexo-Matery主题美化
- uniapp onPullDownRefresh 下拉刷新小坑
- Windows服务器常用配置
- SAP CRM订单数据库表CRMD_SHIPPING的填充原理
- 使用art-template模板引擎渲染数据
- SAP CRM索引数据库表CRMD_ORDER_INDEX的更新原理
- 将自己的nodeJS项目分享到npm上
- react中使用prop-types检测props数据类型