Python程序开发——第六章 类与对象
Posted 晚风(●•σ )
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python程序开发——第六章 类与对象相关的知识,希望对你有一定的参考价值。
目录
一、类
(一)类、对象
Python是一种面向对象语言,面向对象有两个概念,分别是类和对象。
类是对多个对象的共同特征的抽象描述,可以说类是对象的模板
。
对象是类的实例
,用于描述现实中的个体。
(二)类的定义
根据类与对象的关系,我们知道创建对象之前需先定义类,类中可以定义数据成员和成员函数,前者用于描述对象特征,称为属性,后者用于描述对象行为,称为方法,类中的方法的第一个参数必须为self
,这种方法也叫实例方法
,只能通过类实例化的对象进行调用。
class 类的名称
属性名称=属性值
def 方法名称(self): #self是一个指向对象的默认参数,类中必须包含参数 self, 且为第一个参数。
方法体
例如,下列代码定义了一个类,名称为Way,该类包含一个属性number_way、一个方法world():
class Way:
number_way = 3
def world(self):
print("hello world!")
(三)对象的创建和使用
创建对象:
对象名称=类名称()
访问对象成员:
对象名称.属性
对象名称.方法()
例如,创建一个Way类的对象a,访问该对象成员:
class Way:
number_way = 3
def world(self):
print("hello world!")
a = Way()
print(a.number_way)
a.world()
输出结果如下:
二、限制对象访问
(一)定义私有成员、方法
定义类中的属性和方法默认为公有属性
和公有方法
,该类中的对象可以任意访问类中的公有成员和公有方法,可以通过将成员和方法定义为私有,即私有成员和私有方法,从而限制对象对类的访问
。
通过在类成员名称或类方法名称前面加上双下划线__
限制成员的访问,即定义为私有成员和私有方法,如下:
class Way:
__number_way = 3
def __world(self):
print("hello world!")
(二)访问私有成员、方法
这里要注意,实例化的对象是无法直接访问类中的私有成员和私有方法的,它们都可通过公有方法中的参数self调用
。
例如,下列python代码,定义了一个私有成员__number_way和一个私有方法__world()以及一个公有方法get_way():
class Way:
__number_way = 3
def __world(self): # 私有方法
print("hello world!")
def get_way(self): # 公有方法
print(f"number_way的值为:{self.__number_way}") # 私有成员通过公有方法中的指代类本身的默认参数self访问
self.__world() # 私有方法通过公有方法中的指代类本身的默认参数self访问
a = Way()
a.get_way()
输出结果如下:
三、构造方法和析构方法
类中有两个名为 __init__()
和__del__()
的特殊方法,它们分别是构造方法
和析构方法
,该两种方法在类创建
和销毁
时会自动调用
。
(一)构造方法
每个定义的类中都有一个默认的__init__()构造方法,如果在定义类时未定义,则系统会调用默认的构造方法,而如果用户在定义时显式地定义了构造方法,则会调用该定义的构造方法。
可以通过无参构造方法
和有参构造方法
来分别对该方法创建的对象赋予相同
的初始值和不同
的初始值。
注:这里按照参数的有无分为两种构造方法,但除了self,因为类中必须包含参数 self, 且为第一个参数。
下列python代码,Triangle类中显式地定义了带参数的构造方法和一个get_s()方法:
class Triangle:
def __init__(self, bottom, high):
self.bottom = bottom
self.high = high
def get_s(self):
s = (self.bottom * self.high) / 2.0
print(f"三角形的面积为:{s}")
S = Triangle(1.5, 2)
print(S.bottom, S.high)
S.get_s()
运行结果如下:
(二)析构方法
对象被清理时,系统会自动调用析构方法,即对象在内存中被释放时自动触发执行__del__()析构方法
。
下列python代码,Triangle类中显式地定义了带参数的构造方法和一个get_s()方法以及一个析构方法,析构方法打印输出__del__()方法被调用:
class Triangle:
def __init__(self, bottom, high):
self.bottom = bottom
self.high = high
print("__init__()方法被调用")
def __del__(self):
print("__del__()方法被调用")
def get_s(self):
s = (self.bottom * self.high) / 2.0
print(f"三角形的面积为:{s}")
S = Triangle(1.5, 2)
print(S.bottom, S.high)
运行结果如下,可知道对象在被销毁时自动调用了__del__()析构方法:
四、类方法和静态方法
(一)类方法
类方法通过装饰器@classmethod修饰
,它的第一个参数并非类本身self,而是cls
。
与实例方法不一样,它既可由类实例化的对象调用,也可由类调用,且类方法可以修改类属性
,而实例方法不能。
如下代码,通过对象名称调用类方法,直接通过类调用类方法且通过类方法修改类属性word的值:
class GetW:
word = "hello world!"
@classmethod
def print_word(cls):
print(f"{cls.word}")
cls.word = "HELLO WORLD!" # 类方法修改类属性的值为HELLO WORLD!
A = GetW() # 创建一个GetW类的对象A
print("通过类实例化的对象调用:")
A.print_word()
print("通过类调用:")
GetW.print_word()
运行结果如下:
(二)静态方法
首先静态方法与类方法一样,既可由类实例化的对象调用,也可由类调用。静态方法没有self参数,是通过装饰器@classmethod修饰
。
由于没有默认参数,所以它无法使用默认参数来访问类成员。
下列python代码:
class Get:
number = 0
@staticmethod
def print_number():
print(f"{Get.number}")
A = Get()
A.print_number()
Get.print_number()
运行结果如下:
五、继承
类和类可以继承,继承(派生)的类的称为派生类或子类
,被继承的类称为基类或父类
。
由于是继承下来的,所以派生类具有基类的所有属性和方法,继承的格式如下:
class 派生类名称(基类名称):
例如,下列python代码,定义了基类Employee和子类teacher,通过class Teacher(Employee)来继承基类Employee中的属性和方法,另外派生类中还有自己定义的属性和方法:
class Employee:
place = "office"
def get_word(self):
print(f"{self.place}")
class Teacher(Employee): # 继承Employee类
student_num = 50 # 子类自己定义的属性
def get_word_num(self): # 子类自己定义的方法
print(f"教师办公地点为{self.place}")
print(f"学生人数为{self.student_num}")
A = Teacher()
print(Teacher.place) # 子类继承了父类的属性,所以子类有父类的属性
A.get_word() # 子类继承了父类的方法,所以子类有父类的方法
print(Teacher.student_num) # 输出子类自己定义的属性
A.get_word_num() # 调用子类自己定义的方法
输出结果如下,可以看出继承基类后,派生类既可以调用自己的方法,也能调用所继承基类中的方法:
(一)多继承
多继承指一个派生类继承多个基类,多继承的格式为class 派生类(基类1,基类2……)
。
(二)派生类方法重写
当基类中的方法无法满足派生类中的要求时,可以重写
基类的方法,重写后的基类原方法并未改变。
例如下列python代码,派生类teacher中重写基类中的get_word()方法:
class Employee:
place = "office"
@classmethod
def get_word(cls):
print(f"{cls.place}")
class Teacher(Employee):
student_num = 50
def get_word(self):
print(f"{self.student_num}")
A = Teacher()
Employee.get_word()
A.get_word()
Employee.get_word()
运行结果如下,重写基类中的get_word()方法后,并未改变该方法:
(三)super()函数
可以通过super()函数,在派生类重写基类的方法后,仍可调用基类中的方法。
下列python代码:
class Employee:
place = "office"
@classmethod
def get_word(cls):
print(f"{cls.place}")
class Teacher(Employee):
student_num = 50
def get_word(self):
print(f"{self.student_num}")
print("使用super()函数调用基类中的方法:")
super().get_word()
A = Teacher()
A.get_word()
运行结果如下,可以看到通过super()函数调用已经被派生类teacher重写的基类方法get_word():
六、多态
多态指不考虑对象类型并使用该对象,让具有不同功能的函数使用相同的函数名称,从而通过函数名称调用不同功能的函数。
下列python代码,通过Person类中的get_word()方法中的name参数,传给name参数是目标类的实例对象即调用该类的get_word()方法:
class Person:
def get_word(self, name):
name.get_word()
class Employee:
def get_word(self):
print("职工")
class Teacher(Employee):
def get_word(self):
print("教师")
class Professor(Employee):
def get_word(self):
print("教授")
A = Person()
A.get_word(Employee())
A.get_word(Teacher())
A.get_word(Professor())
运行结果如下:
以上是关于Python程序开发——第六章 类与对象的主要内容,如果未能解决你的问题,请参考以下文章