过一遍Python基础---Day4之面向对象

目录

  • 文章声明⭐⭐⭐
  • 让我们开始今天的学习吧!
    • 面向对象⭐⭐⭐


文章声明⭐⭐⭐

  1. 该文章为我(有编程语言基础,非编程小白)的 Python自学笔记
  2. 知识来源为 Python官方文档 / 菜鸟教程 ,归纳为自己的语言与理解记录于此
  3. 不出意外的话,我大抵会 持续更新
  4. 想要了解前端开发(技术栈大致有:Vue2/3、微信小程序、uniapp、HarmonyOS、NodeJS、Typescript)与Python的小伙伴,可以关注我!谢谢大家!

让我们开始今天的学习吧!

面向对象⭐⭐⭐

首先,我们先借着菜鸟教程的定义来大致过一遍面向对象的定义:

  • 类(Class): 用来描述具有相同的属性和方法的对象的集合,它定义了该集合中每个对象所共有的属性和方法,对象是类的实例
  • 方法:类中定义的函数
  • 类变量:类变量在整个实例化的对象中是公用的,类变量定义在类中且在函数体之外,类变量通常不作为实例变量使用
  • 数据成员:数据成员为类变量或者实例变量,是用于处理类及其实例对象的相关的数据
  • 方法重写:如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写
  • 局部变量:定义在方法中的变量,只作用于方法中的变量
  • 实例变量:在类的声明中,属性是用变量来表示的,这种变量就称为实例变量,实例变量就是一个用 self 修饰的变量。
  • 继承:即一个派生类(derived class)继承基类(base class)的字段和方法,继承也允许把一个派生类的对象作为一个基类对象对待,例如,有这样一个设计:一个Dog类型的对象派生自Animal类
  • 实例化:创建一个类的实例,类的具体对象。
  • 对象:通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法

然后,阐述一下我的个人理解(可能不完善不准确,大家看看就完事儿了)

我所理解的面向对象,只不过是一种解决问题的思路,例如我现在是一个创世主,我要开始制作一个世界了。

我选择面向对象的思路来创造,于是我决定先创建动物(基类),我捏了狗、鸟、虎(狗、鸟、虎都属于动物的派生类,都属于动物这一大类派生出来的一小类)…我捏了哪些狗呢?我捏了拉布拉多、哈士奇、柯基(拉布拉多、哈士奇、柯基都是狗这个类的具体实例,都称之为狗这个类的对象)…创建完了动物,我便继续创建植物、人类…我甚至还创造了天气(类),我创造了下雨、打雷、大雾、烈日炎炎(这些都属于天气这个类的具体实例,即天气这个类的对象)…

很快一个世界变创建好了,我为什么会选择这个流程来创建世界呢?因为面向对象这个思路的优势在于,归纳总结事物的共同点,方便批量的生成有着共同点但也各不相同的事物,拿上述的例子来思考,我创建动物这个类是因为动物都有着吃、呼吸、运动等共同特征,我把这些共同点汇聚在一起,再创造动物岂不是很方便?于是我创建了狗、鸟、虎等动物派生类,它们的共同点就是吃、呼吸、运动等,只不过数值不同,狗吃50(满饱食度为100),鸟吃20,虎吃90,在编程世界里是不是可以用(eatAbility = 50、eatAbility = 20、eatAbility = 90)来表示呢?运动方式也不同,狗和虎是爬行,鸟是飞行,在编程世界里是不是可以用(action=‘move’、action=‘fly’)来表示呢?上述的eatAbility、action即为类中的属性,不仅如此,我们还可以继续派生,狗这个类可以派生出拉布拉多、哈士奇、柯基等更为具体的类,它们作为狗也都有着共同点(犬吠、吃骨头…)和不同点(性格不同、智商不同、长相体型不同…)

我们先创建一个简单的类,解释器中代码如下:

>>> class MyInfo:
...     """自我介绍类"""
...     name='Richie' # 属性
...     age=22 # 属性
...     def sayHello(self): # 方法
...             print('Hello,' + self.name)
...
>>> mine = MyInfo() # 实例化类
>>> print(mine.name) # 访问类的属性
Richie
>>> print(mine.age) # 访问类的属性
22
>>> mine.sayHello() # 访问类的方法
Hello,Richie

类有一个名为 __init__() 的特殊方法(构造方法),该方法在类实例化时会自动调用, __init__() 方法可以有参数,参数通过 __init__() 传递到类的实例上,解释器中代码如下:

>>> class People:
...     def __init__(self,name,age):
...             self.name = name
...             self.age = age
...
>>> me = People('Richie',22)
>>> print(me.name,me.age)
Richie 22

self代表类的实例,而非类,类的方法与普通的函数只有一个特别的区别:它们必须有一个额外的第一个参数名称, 按照惯例它的名称是 self

>>> class Test:
...     def prt(self):
...             print(self)
...             print(self.__class__)
...
>>> t = Test()
>>> t.prt()
<__main__.Test object at 0x00000174163AF080>
<class '__main__.Test'>

从上面执行结果可以很明显的看出,self 代表的是类的实例,代表当前对象的地址,而 self.class 则指向类
self 不是 python 关键字,我们把他换成别的名也是可以正常执行的,但是建议使用self来表示

在完善一下类,解释器中代码如下:

>>> class People:
...     name='' # 基本属性
...     age=0 # 基本属性
...     __weight = 0 # 两个下划线开头,声明该属性为私有,不能在类的外部被使用或直接访问
...     def __init__(self,name,age,weight):
...             self.name = name
...             self.age = age
...             self.__weight = weight
...     def speak(self):
...             print(self.name)
...             print(self.age)
...             print(self.__weight)
...             self.__selfFunction()
...     def __selfFunction(self): # 两个下划线开头,声明该方法为私有方法,只能在类的内部调用 ,不能在类的外部调用
...             print('我的私有属性')
...
>>> mine = People('Richie',22,65)
>>> mine.name
'Richie'
>>> mine.age
22
>>> mine.__weight # 私有属性,在类外部无法直接进行访问
AttributeError: 'People' object has no attribute '__weight'
>>> mine.speak()
Richie
22
65
我的私有属性
>>> mine.__selfFunction() # 报错

子类(派生类 DerivedClassName)会继承父类(基类 BaseClassName)的属性和方法,解释器中代码如下:

>>> class People:
...     name=''
...     age=0
...     __weight = 0
...     def __init__(self,name,age,weight):
...             self.name = name
...             self.age = age
...             self.__weight = weight
...     def speak(self):
...             print(self.name)
...             print(self.age)
...             print(self.__weight)
...
>>> class Student(People): # 单继承示例
...     score = 0
...     def __init__(self,name,age,weight,score):
...             People.__init__(self,name,age,weight) # 调用父类的构造函数
...             self.score = score
...     def speak(self): # 覆盖重写父类的方法
...             print(self.name)
...             print(self.age)
...             print(self.score)
...
>>> s = Student('Richie',22,65,87)
>>> s.speak()
Richie
22
87

多继承,需要注意圆括号中父类的顺序,若是父类中有相同的方法名,而在子类使用时未指定,python从左至右搜索,即方法在子类中未找到时,从左到右查找父类中是否包含方法,解释器中代码如下:

>>> class People:
...     name=''
...     age=0
...     __weight = 0
...     def __init__(self,name,age,weight):
...             self.name = name
...             self.age = age
...             self.__weight = weight
...     def speak(self):
...             print(self.name)
...             print(self.age)
...             print(self.__weight)
...
>>> class Student(People):
...     score = 0
...     def __init__(self,name,age,weight,score):
...             People.__init__(self,name,age,weight)
...             self.score = score
...     def speak(self):
...             print(self.name)
...             print(self.age)
...             print(self.score)
...
>>> class Speaker():
...     topic = ''
...     name = ''
...     def __init__(self,topic,name):
...             self.name = name
...             self.topic = topic
...     def speak(self):
...             print(self.name)
...             print(self.topic)
...
>>> class Sample(Speaker,Student): # 多继承
...     num = 0
...     def __init__(self,name,age,weight,score,topic,num):
...             student.__init__(self,name,age,weight,score)
...             speaker.__init__(self,topic,name)
...             self.num = num
... 
>>> test = Sample("Richie",22,65,87,'Python',100)
>>> test.speak()   # 方法名同,默认调用的是在括号中参数位置排前父类的方法,此处调用的是Speaker里的speak()方法
Richie
Python

方法重写,如果你的父类方法的功能不能满足你的需求,你可以在子类重写你父类的方法,解释器中代码如下:

>>> class Parent:
...     def pFunction(self):
...             print("Parent's function")
...
>>> class Child(Parent):
...     def pFunction(self):
...             print("Child's function")
...
>>> c = Child()
>>> c.pFunction() # 子类调用重写方法
Child's function
>>> super(Child,c).pFunction() # 用子类对象调用父类已被覆盖的方法
Parent's function

你可能感兴趣的:(关于Python,python,开发语言)