面向对象基本概念2--继承、多态
- 1.继承基本概念
- 2.子类重写父类方法
- 2.1完全重写
- 2.2扩展父类方法--super()
- 3.多继承
- 4.新式类和旧式类
- 5.多态基本概念
- 6.类属性、类方法-@classmethod
- 6.1类属性
- 6.2类方法@classmethod
- 7.静态方法@staticmethod
- 8.案例分析
本系列博文来自学习《Python基础视频教程》笔记整理,视屏教程连接地址:http://yun.itheima.com/course/273.html
面向对象三大特性:封装(定义类的准则)、继承(实现代码的重用)、多态(增加代码的灵活度)
1.继承基本概念
继承 实现代码的重复的使用,将多个类的共有方法封装在父类中,个性类从父亲类中继承共有方法,再封装自己独特的方法就行。
概念:子类拥有父类的所有属性和方法,不需要再次开发,子类要做的就是根据自己的职责,封装特有的属性和方法。
语法:
class 子类名(父类名):
pass
专业术语:子类(派生类)、父类(基类)、继承(派生)
继承的特性:传递性,子类继承了父类及其父类的父类的所有公有属性和公有方法。
子类对象不能直接访问父类的私有属性和私有方法
子类对象需要通过 父类 的公有方法 间接调用父类的 私有属性 和 私有方法
2.子类重写父类方法
2.1完全重写
子类继承自父类,父类的方法不能满足 子类方法 的要求,就需要在子类中对父类方法进行重新编写。
具体实现:在子类中定义一个和父类名字一样的方法,写上需要实现的功能就可以了。
如果子类重写父类方法,在调用时,会调用子类重写的方法
2.2扩展父类方法–super()
子类的方法实现 需要 在父类方法的基础上 进行扩展。
具体实现:在子类中重写父类方法,在需要的位置使用super().父类方法执行父亲类方法的功能,代码的其他位置,针对子类的需求,编写子类特有的代码实现。
super()是一个特殊的类,用来重写父类方法时,调用在父类中封装的方法实现
Python3.x 使用 super().父亲类方法名
Python2.x 使用 super(子类名, self).父类方法名
Python2.0早期版本中没有super()这个类,需要调用父类的方法,需要用父类名.方法(self)
在3.0中支持这种方法,但是不推荐使用父类名.方法(selg)的调用方式。因为父类名改变,之后的调用需要全部替换,不够优雅。
3.多继承
单继承:子类有一个父类
多继承:子类有多个父类 ,即可以继承多个父类的属性和方法。
语法:
class 子类名(父类名1,父类名2)
注意事项:两个父类中封装的方法名相同,同名方法调用的顺序没那么明显。多个父类应该避免同名方法的情况,使程序更加简单和易读取。
python 中的MRO-method resolution order-方法解决顺序:在多继承中判断方法属性的调用路径。可以利用 类名.__mro__ 查看方法的调用顺序(双下划线)。
类名.__mro__
依照小括号中列的顺序 依次 往后查找所调用方法的顺序(“object”所有Python类的基类)。
4.新式类和旧式类
“object”所有Python类的基类,拥有自己的属性和方法,这些属性和方法以双下划线开头和结尾内置属性和方法(可以使用dir查看对应的属性和方法)
dir(对象名)
新式类:以 object 为基类的类,会有许多object封装的内置属性和方法。pyhon3.x会默认创建的类继承至object 类
旧式类:不以object为基类的类,新式类与旧式类的方法搜索顺序是不同的。
python 2.x的版本,需要明示写明继承object。否者为旧式类
class A(object):
pass
养成一个习惯:当一个类没有父类时,都让它继承至object类,确保这个类是新式类。
5.多态基本概念
多态:不同的子类对象,调用相同的父类方法,产生不同的执行结果。
多态使用的两个前提:继承、对父类方法的重写。
不同对象的属性存放在不同的内存空间中,对象的方法与属性的存储方式不同。
一个类在内存中创建的多个对象的方法在内存中只有一份,在调用方法时,将 调用方法的 对象的引用 传递给方法的self 参数,那么self就可以通过对象引用来获取对象属性。
=》对象内存空间中存储该对象的属性
=》类的存储空间中存储各个对象的方法
对象被创建之后,内存中就只有一个对象的实实在在的存在–实例
对象=实例、创建对象=实例化
类是一个特殊的对象,定义一个类 就等于 创建了一个类对象。由类对象 创建的对象 称为 实例对象。类对象有自己的属性和方法:类属性和类方法。
6.类属性、类方法-@classmethod
此前所说的方法和属性都属于实例方法和属性,下面介绍的是类属性和类方法,以及静态方法。
6.1类属性
例如:记录这个类创建了多少类对象,每个对象创建时会自动调用__init__方法,那么在初始化方法中改变计数器的值,就能知道这个类创建了多少对象。
属性名=属性值
class Tool(object):num=0def __init__(self,name):self.name=nameTool.num+=1
Python中的属性获取机制
变量.属性名 在属性值的获取中,使用向上查找机制。
类属性的访问:
类名.类属性名
类创建的对象名.类属性名
推荐使用类名访问方式,避免和对象属性的混淆现象,可能会造成在对象外为对象添加一个属性的混淆。
6.2类方法@classmethod
定义类方法
class Tool(object):num=0@classmethoddef show_tool_count(cls):print("工具对象的数量%d"%cls.num)def __init__(self,name):self.name=nameTool.num+=1
类名.方法名 就能调用该方法。(不用实例化该对象?)
7.静态方法@staticmethod
在开发程序时,要在类中封装方法,这个方法可以为类方法,也可以为实例方法
要访问实例属性的方法–实例方法
要访问类属性的方法–类方法
如果一个方法既不需要访问实例属性,也不需要访问实例方法,那么这个方法可以封装为静态方法。
静态方法不需要传递第一个参数(self,cls),通过类名.方法名来调用方法(不需要创建对象就能调用静态方法)
class Dog(object):@staticmethoddef run():print("小狗要跑步。。")
Dog.run()
8.案例分析
要求:开发一个游戏类
属性:历史最高分(类属性)、玩家姓名(实例属性)
方法:
显示帮助信息–静态方法
显示历史最高分–类属性
开始当前玩家的游戏–实例方法
实例属性+类属性=》定义实例方法