Python基础之面向对象3(继承)
一、继承相关概念
1、语法:
2、定义:
3、优缺点:
4、相关概念:
5、相关内置函数:
6、继承内存图:
7、多继承:
二、多态相关概念
1、定义及作用:
2、重写概念:
3、运算符重载:
定义:让自定义的类生成的对象(实例)能够使用运算符进行操作。
三、基础技能代码:
代码1:
"""
继承语法 -- 方法
财产
皇位 #练习1:定义父类--宠物, 行为:吃
# 定义子类--狗, 行为:防守xx
# 定义子类--鸟, 行为:飞
#创建相应对象,调用相应方法.测试isinstance,issubclass函数
#14:35 """ # 学生 与 老师 在某种概念上是统一的
# 学生是 人
# 老师是 人
# class Person:
def say(self):
print("说") class Student(Person):
def study(self):
print("学习") class Teacher(Person):
def teach(self):
print("教") s01 = Student()
s01.study()
# 可以直接使用父类成员
s01.say() p02 = Person()
p02.say()
# 父类不能使用子类成员
# p02.study() t03 = Teacher()
t03.teach()
# 不能使用"兄弟"类成员
# t03.study() # 判断一个对象是否"兼容"一个类型
print(isinstance(s01,Person)) # True
print(isinstance(s01,Student)) # True
print(isinstance(s01,object)) # True print(isinstance(s01,Teacher)) # False
print(isinstance(p02,Student)) # False # 判断一个类是否"兼容"一个类型
print(issubclass(Student,Person)) # True
print(issubclass(Student,Teacher)) # False
print(issubclass(Student,(Teacher,Person))) # True
print(issubclass(Student,Student)) # True
代码2:
"""
继承语法 -- 数据
# 练习: 定义父类--宠物, 数据:名字
# 定义子类--狗, 数据:工作
# 创建相应对象,画出内存图
""" class Person:
def __init__(self,name):
self.name = name class Student(Person):
def __init__(self,name,score):
# 通过函数,调用父类方法
super().__init__(name)
self.score = score class Teacher(Person):
def __init__(self,name,salary):
super().__init__(name)
self.salary = salary s01 = Student("zs",100)
print(s01.score)
print(s01.name) p02 = Person("ww")
print(p02.name)
代码3:
"""
继承 -- 设计思想
面向对象设计原则
练习:exercise01.py
1. 开闭原则
开放 关闭
对扩展 对修改
允许增加新功能 不允许改变(增加/删除/修改)以前的代码 2. 依赖倒置(抽象)
使用抽象(父类),而不使用具体(子类).
"""
# 老张开车去东北
# 变化:飞机
# 火车
# 汽车
# ....... class Person:
def __init__(self, name):
self.name = name # def go_to(self, str_type, str_pos):
# if str_type == "汽车":
# Car().run(str_pos)
# elif str_type =="飞机":
# Airplane().fly(str_pos)
# # elif xxxxx: def go_to(self, vehicle, str_pos):
"""
写代码期间:
使用的是交通工具的,而不是汽车,飞机等
所以无需判断具体类型
运行期间:
传递具体的对象(汽车,飞机)
:param vehicle:
:param str_pos:
:return:
"""
# 如果传入的对象,不是交通工具,则退出.
if not isinstance(vehicle,Vehicle):
print("传入的不是交通工具")
return
vehicle.transport(str_pos) # class Car:
# def run(self, str_pos):
# print("行驶到", str_pos)
#
#
# class Airplane:
# def fly(self, str_pos):
# print("飞到", str_pos) class Vehicle:
"""
交通工具
"""
def transport(self, str_pos):
# 人为创造一个错误()
raise NotImplementedError()
# print("儿子们,必须有这个方法啊") class Car(Vehicle):
def transport(self, str_pos):
print("行驶到", str_pos) class Airplane(Vehicle):
def transport(self, str_pos):
print("飞到", str_pos) # ....
p01 = Person("老张")
# p01.go_to("汽车", "东北")
p01.go_to(Airplane(),"东北")
四、具体实例:
练习1:
# 练习:手雷爆炸了,可能伤害敌人,玩家.还有可能伤害未知事物(鸭子,树,房子).
# 要求:如果增加了新的事物,手雷代码不变. 17:15 class Grenade:
"""
手雷
""" def __init__(self, atk):
self.atk = atk def explode(self, *args):
"""
爆炸
:return:
"""
for item in args:
if not isinstance(item, Damageable):
print("类型不兼容")
return
item.damage(self.atk) class Damageable:
"""
可以受伤
""" def __init__(self, hp):
self.hp = hp def damage(self, value):
# 约束子类必须具有当前方法
# raise NotImplementedError()
self.hp -= value class Player(Damageable):
def damage(self, value=0):
# self.hp -= value
super().damage(value)
print("碎屏") class Enemy(Damageable):
def damage(self, value):
# self.hp -= value
super().damage(value)
print("播放动画") g01 = Grenade(10)
p02 = Player(100)
e03 = Enemy(50)
g01.explode(p02, e03)
练习2:
"""
有若干个图形(圆形,矩形........)
每种图形,都可以计算面积.
定义图形管理器,记录所有图形,提供计算总面积的方法.
要求:增加新的图形,不改变图形管理器代码.
""" class GraphicManager:
def __init__(self):
# 记录所有图形
self.__graphics = [] def add_graphic(self,g):
if not isinstance(g,Graphic):
return
self.__graphics.append(g) def get_total_area(self):
"""
计算总面积
:return:
"""
total_area = 0
for item in self.__graphics:
total_area += item.get_area()
return total_area class Graphic:
"""
图形
"""
def get_area(self):
pass class Circle(Graphic):
"""
圆形
"""
def __init__(self,radius):
self.radius = radius def get_area(self):
return self.radius ** 2 * 3.14 class Rectangle(Graphic):
"""
矩形
""" def __init__(self, length,width):
self.length = length
self.width = width def get_area(self):
return self.length * self.width manager = GraphicManager()
manager.add_graphic("ok")
manager.add_graphic(Rectangle(2,3))
manager.add_graphic(Circle(5))
# 加断点,调试
print(manager.get_total_area())
练习3:
# 1. 定义父类:武器,数据:攻击力,行为:购买(所有子类都一样).攻击(不知道怎么攻击)
# 定义子类:枪,数据:射速,行为:攻击
# 定义子类:手雷,数据:爆炸范围,行为:攻击
# 创建相应对象,调用相应方法.
# 画出内存图 class Weapon:
"""
武器
"""
def __init__(self,atk):
self.atk = atk def buy(self):
print("购买武器") def attack(self):
# 子类如果没有当前方法,就会报错
raise NotImplementedError() class Gun(Weapon):
"""
枪
"""
def __init__(self,atk,speed):
super().__init__(atk)
self.att_speed = speed def attack(self):
print("开枪啦") class Grenade(Weapon):
"""
手雷
""" def __init__(self, atk, range):
super().__init__(atk)
self.explode_range = range def attack(self):
print("爆炸啦") g01 = Gun(10,0.1)
g01.buy()
g01.attack() grenade01 = Grenade(50,10)
grenade01.buy()
grenade01.attack()
练习4:
# 2. 一家公司,有如下几种岗位:
# 普通员工:底薪
# 程序员:底薪 + 项目分红
# 销售员:底薪 + 销售额
# 定义员工管理器,记录所有员工,提供计算总薪资方法.
# 要求:增加新岗位,员工管理器代码不做修改.
# 体会:依赖倒置
class EmployeeManager:
"""
员工管理器
""" def __init__(self):
self.__all_employee = [] def add_employee(self, employee):
if not isinstance(employee, Employee):
return
self.__all_employee.append(employee) def get_total_salary(self):
"""
计算总薪资
:return:
"""
total_salary = 0
for item in self.__all_employee:
# 编码期间:item 认为是员工
# 运行期间:item 实际是具体员工
total_salary += item.get_salary()
return total_salary class Employee:
"""
员工类
作用:代表具体员工,隔离员工管理器与具体员工的变化.
""" def __init__(self, name, salary):
self.name = name
self.base_salary = salary def get_salary(self):
return self.base_salary class Programmer(Employee):
"""
程序员
""" def __init__(self, name, salary, bonus):
super().__init__(name, salary)
self.bonus = bonus def get_salary(self):
# return self.base_salary + self.bonus
# 扩展重写
return super().get_salary() + self.bonus class Salesmen(Employee):
"""
销售员
""" def __init__(self, name, salary, sale_value):
super().__init__(name, salary)
self.sale_value = sale_value def get_salary(self):
return super().get_salary() + self.sale_value * 0.05 manager = EmployeeManager()
manager.add_employee(Employee("zs",3000))
manager.add_employee(Programmer("xp",4000,10))
manager.add_employee(Programmer("xx",99999,6135138))
manager.add_employee(Salesmen("pp",3000,500)) re = manager.get_total_salary()
print(re) #练习:老王转岗
# 销售 --> 程序员
lw = Salesmen("老王",3000,500)
lw = Programmer("老王",8000,100000) # 重新创建新对象,替换引用.好比是开除"老王",招聘新"老王"
# 要求:对象部分改变,而不是全部改变.
练习5:
class Employee:
"""
员工类
""" def __init__(self, name,job):
self.name = name
# 成员变量的类型是岗位
self.job = job def calculate_salary(self):
"""
使用岗位,计算薪资.
:return:
"""
return self.job.get_salary() class Job:
"""
岗位
"""
def __init__(self,salary):
self.base_salary = salary def get_salary(self):
return self.base_salary class Programmer(Job):
"""
程序员
""" def __init__(self,salary, bonus):
super().__init__(salary)
self.bonus = bonus def get_salary(self):
# return self.base_salary + self.bonus
# 扩展重写
return super().get_salary() + self.bonus class Salesmen(Job):
"""
销售员
""" def __init__(self,salary, sale_value):
super().__init__(salary)
self.sale_value = sale_value def get_salary(self):
return super().get_salary() + self.sale_value * 0.05 #练习:老王转岗
# 销售 --> 程序员
# 继承关系
# lw = Salesmen("老王",3000,500)
# lw = Programmer("老王",8000,100000) # 重新创建新对象,替换引用.好比是开除"老王",招聘新"老王"
# 要求:对象部分改变,而不是全部改变. lw = Employee("老王",Salesmen(3000,500))
print(lw.calculate_salary())
# 转岗
lw.job = Programmer(8000,100000)
print(lw.calculate_salary())
练习6:
"""
内置可重写函数 """ class Wife:
def __init__(self,name,age):
self.name = name
self.age = age def __str__(self):
# 返回给人看
return "奴家叫:%s,年芳:%d"%(self.name,self.age)
def __repr__(self):
# 返回给解释器看
return 'Wife("%s",%d)'%(self.name,self.age) w01 = Wife("金莲",25)
print(w01)# 将对象转换为字符串
# re = eval("1 + 5")
# print(re)
# w02 = eval('Wife("金莲",25)')
# w03 = eval(input(""))
#创建了新对象
w02 = eval(w01.__repr__())
print(w02)
w01.name ="莲莲"
print(w02.name)
练习7:
# 练习: 重写 StudentModel 类 __str__ 方法 与__repr__方法
# 创建学生对象,创建学生对象列表.分别print class StudentModel:
def __init__(self, name="", age=0, score=0, id=0):
self.id = id
self.name = name
self.age = age
self.score = score def __str__(self):
return "我的编号是:%d,姓名是:%s,年龄是:%d,成绩是:%d."%(self.id,self.name,self.age,self.score) def __repr__(self):
return 'StudentModel("%s",%d,%d)'%(self.name,self.age,self.score) s01 = StudentModel("zs",24,100)
s02 = eval(s01.__repr__())
print(s02)
print(s01)
list01 = [s01,s02]
print(list01)
练习8:
"""
运算符重载
""" # print("a" + "b")
class Vector:
"""
向量
"""
def __init__(self, x):
self.x = x def __str__(self):
return "向量的x变量是:%s"%self.x # 对象 +
def __add__(self, other):
return Vector(self.x + other) # + 对象
def __radd__(self, other):
return Vector(self.x + other) # 累加:在原有对象基础上进行操作,不创建新对象.
def __iadd__(self, other):
self.x += other
return self def __lt__(self, other):
return self.x < other v01 = Vector(10)
v02 = v01 + 5
# print(v02)
# 练习:实现向量类 与 整数 做 减法/乘法运算 17:25
v03 = 5 + v01
# print(v03)
v04 = v01 + v02
# print(v04)
# 练习:实现整数 与 向量 做 减法/乘法运算
# 向量 向量 list01 = [1]
list02 = list01 + [2]
print(list01)
list01 += [2]
print(list01) print(id(v01))
# 累加含义:在原有对象基础上,增加新值
v01 += 1
print(v01)
print(id(v01))
# 练习:实现向量类 与 整数 做 累计减法/累计乘法运算 print(v01 < 2)
Python基础之面向对象3(继承)的更多相关文章
- Python 基础 四 面向对象杂谈
Python 基础 四 面向对象杂谈 一.isinstance(obj,cls) 与issubcalss(sub,super) isinstance(obj,cls)检查是否obj是否是类 cls ...
- python基础,函数,面向对象,模块练习
---恢复内容开始--- python基础,函数,面向对象,模块练习 1,简述python中基本数据类型中表示False的数据有哪些? # [] {} () None 0 2,位和字节的关系? # ...
- (转)Python成长之路【第九篇】:Python基础之面向对象
一.三大编程范式 正本清源一:有人说,函数式编程就是用函数编程-->错误1 编程范式即编程的方法论,标识一种编程风格 大家学习了基本的Python语法后,大家就可以写Python代码了,然后每个 ...
- 自学Python之路-Python基础+模块+面向对象+函数
自学Python之路-Python基础+模块+面向对象+函数 自学Python之路[第一回]:初识Python 1.1 自学Python1.1-简介 1.2 自学Python1.2-环境的 ...
- 二十. Python基础(20)--面向对象的基础
二十. Python基础(20)--面向对象的基础 1 ● 类/对象/实例化 类:具有相同属性.和方法的一类人/事/物 对象(实例): 具体的某一个人/事/物 实例化: 用类创建对象的过程→类名(参数 ...
- python语法学习面向对象之继承
python语法学习面向对象之继承 转载自:http://www.cnblogs.com/Joans/archive/2012/11/09/2757368.html 只要涉及到面向对象,”类“是必须出 ...
- 转 python语法学习面向对象之继承
传送门 python语法学习面向对象之继承 只要涉及到面向对象,”类“是必须出现的一个代名词. 类和对象是面向对象编程的两个主要方面.类创建一个新类型,而对象是这个类的实例. 类的一些概念: 包括初始 ...
- python基础(24):面向对象三大特性一(继承)
1. 继承 1.1 什么是继承 继承是一种创建新类的方式,在python中,新建的类可以继承一个或多个父类,父类又可称为基类或超类,新建的类称为派生类或子类. python中类的继承分为:单继承和多继 ...
- Python之路【第六篇】python基础 之面向对象(一)
一.三大编程范式 1.面向过程编程 2.函数式编程 3.面向对象编程 二.编程进化论 1.编程最开始就是无组织无结构,从简单控制流中按步写指令 2.从上述的指令中提取重复的代码块或逻辑,组织到一起(比 ...
- Python高手之路【十一】python基础之面向对象
创建类和对象 面向对象编程是一种编程方式,此编程方式的落地需要使用 “类” 和 “对象” 来实现,所以,面向对象编程其实就是对 “类” 和 “对象” 的使用. 类就是一个模板,模板里可以包含多个函数, ...
随机推荐
- java学习笔记06-条件语句
java条件语句 if...else 单独使用if if(布尔表达式){ 如果布尔表达式为true,执行花括号里的代码 } public static void main(String[] args) ...
- 【转】详解web.xml中元素的加载顺序
顺序为: context-param --> listeners --> filters --> servlets(如DispatcherServlet等) 详见<https: ...
- TableView+Button
local MainScene = class("MainScene", cc.load("mvc").ViewBase) function MainScene ...
- 2、阿里云ECS发送邮件到腾讯企业邮箱(ECS默认不开启25端口)
阿里云ECS默认禁用25端口导致发邮件失败. 方法一: 使用shell脚本发送邮件,需要配置mailx 1.安装软件 yum install mailx 2.配置 vim /etc/mail.rc在文 ...
- 远程链接mysql
一. 设置账户密码 1. 创建用户:CREATE USER 'jiang'@'%' IDENTIFIED BY '1'; //%表示所有端口 2. 授予权限: GRANT ALL PRIVILEGES ...
- Python利用os模块批量修改文件名
初学Python.随笔记录自己的小练习. 通过查阅资料os模块中rename和renames都可以做到 他们的区别为.rename:只能修改文件名 renames:可以修改文件名,还可以修改文件上 ...
- Org mode无法生成LaTeX公式预览图片
最近需要在Cygwin平台下的Emacs Org mode中生成LaTeX数学公式的预览图片,从而得到图文并貌的笔记与任务管理文档.但当我执行org-toggle-latex-fragment命令后却 ...
- mysql的if用法解决同一张数据表里面两个字段是否相等统计数据量。
MySQL的使用用法如下所示:格式:if(Condition,A,B)意义:当Condition为true时,返回A:当Condition为false时,返回B.作用:作为条件语句使用.mysql的i ...
- 利用Skywalking-netcore监控你的应用性能
Skywalking SkyWalking开源项目由吴晟于2015年创建,同年10月在GitHub上作为个人项目开源. SkyWalking项目的核心目标,是针对微服务.Cloud Native.容器 ...
- 强制.net 程序以32位模式运行
You can modify the PE header of the executable (using the "Corflags.exe" .NET Framework SD ...