DAY8-在地下城寻求邂逅Python是否搞错了什么
文章参考001-面向对象-01-基本概念_哔哩哔哩_bilibili
主编程语言C++转Python中,面向对象篇(51%)
1.面向对象
面向过程注重步骤与过程,顺序调用函数,无固定套路,不适合复杂项目开发
昨天的简单实例-卡片的开发就是一个面向过程的程序
面向对象是更大的封装,在一个对象中封装多个方法,专门应对复杂项目
在完成需求前确定职责
根据职责确定对象
顺序让不同对象调用不同方法
2.封装
类是具有相同特征或者行为的事物统称,类名遵循每个单词首字母大写
特征->属性,行为->方法
对象是由类(模板)创造的具体对象
类中定义了属性与方法,创建的对象就有什么属性和方法,不多不少
class 类名:def 方法1(self,参数列表):passdef 方法2(self,参数列表):pass
方法定义格式几乎与函数一样
引用同样适用,如:变量名=类名(),这个变量就是一个对象
self的作用
表示哪一个对象调用的方法,就是哪一个对象的引用
在封装类内部,self表示当前调用方法的对象自己
在调用方法时不需要传递self参数
所以在方法内部可以通过self.属性的方式来访问对象的属性或者其他对象的方法
在类外部增加属性
使用对象.属性,利用赋值语句即可,如:tom.name="小白"
不过不推荐,因为没有在封装的类内改变
init方法
在使用类名()创建对象时,会自动执行:
为对象分配空间(创建对象)和设置初始值(初始化方法__init__)
init是专门用来定义一个类具有哪些属性的方法
在init内部使用:self.属性名=属性初始值 即可
通过在参数列表中加入其他参数,可以通过参数来改变属性的初始值(和函数一致)
即self.属性名=形参
内置方法与属性
在所有代码执行完才会执行del,如果你想提前删除,也可以在外部使用del
__str__方法必须要返回字符串
一个对象的属性可以是另一个类创建的对象
定义属性时,不知道设置什么初始值,可以设置为None
身份运算符
身份运算符用来比较两个对象的内存地址是否一致,是否是同一个对象的引用
在Python中针对None比较时,建议使用is判断
is判断的是两个变量的引用对象是否是同一个
==判断的是变量的值是否相等
私有属性和私有方法
私有属性/方法在外界不能被直接访问,私有属性在对象内部仍可以正常访问
在属性/方法前加两个下划线即可
比如上文的__init__
3.继承
继承(派生)实现代码的重用,子类(派生类)继承父类(基类)
class 类名(父亲名):pass
传递性:子类拥有父类以及父类的父类中封装的属性与方法
方法的重写:
覆盖:
如果父类封装的方法不能满足子类的需求时,可以对方法进行重写
顾名思义直接重写就好了,调用子类时用的是重写后的方法
拓展:
在子类中重写父类方法
在需要的位置使用:super().父类方法来调用父类方法的执行
在其他位置,针对子类特殊需求编写子类特有的代码实现
子类对象不能访问到父类的私有属性/方法
子类可以通过父类的公共方法间接访问到私有属性和方法
多继承:
class 类名(父类1,父类2....):pass
多继承能让子类有多个父类的属性和方法
避免多继承在不同父类的同名属性和方法
新式类和旧式类:
新式类是以object为基类的类,没有确切的父类时,可以用object作为父类
旧式类(经典类)是不以object为基类的类
新式类和旧式类在多继承时会影响到方法的搜索顺序
4.多态
不同的子类调用相同的父类方法,产生不同的结果
多态可以增加代码灵活性
继承和重写父类为前提
是调用方法的技巧,不会影响到类的内部设计
5.类的结构
由于创建出来的对象是实实在在的,有独立内存空间,
定义的方法只有一份
定义的类属于类对象,这类模板只有一个,实例可以有很多个
可以使用赋值语句定义类属性(在__init__上方)