1.概述
python也是一个面向对象的编程语言,能够进行对象编程。我们要做的就是熟悉面向对象编程的规则,学会类的使用方法。
2.类与对象
在进行面向对象编程之前,我们先要了解面向对象编程中几个重要的术语:类、类对象、实例对象、属性函数和方法。
类是对现实世界中一些事物的封装:
格式:
class className:
block
block里面可以定义属性和方法
2.1 创建一个类对象
# 定义了一个Person类
class Person:
#定义一个属性
name = 'xiaoming'
age = 12
# 定义一个方法
def printname(self):
print(self.name,self.age)
p = Person() # 类定义好后,可以进行实例化操作,p就是person的实例对象,实例对象是根据类模板生成的一个内存实体,有确定的数据与内存地址。
# 可以通过两种方式来访问类:
# 格式:className.attribute,className.method 例如:Person.name 通过类的名称来访问
# 格式:instanceobiects.attribute,instance.method 例如:p = Person() p.name 使用类的实例对象来访问
print(Person.name,Person.age)
print(p.name,p.age)
其结果是:
xiaoming 12
xiaoming 12
2.2 修改类的属性
案例一:
# 修改类的属性必须使用类的名称访问,不能使用对象实例访问,
class Person:
#定义一个属性
name = 'xiaoming'
age = 12
p = Person()
q = Person()
print(p.name,p.age)
print(Person.name,Person.age)
print('---------')
# 修改实例对象的属性,示例对象属性的改变并不会改变类的属性,
p.name = 'xiaohong'
print(p.name,p.age)
print(Person.name,Person.age)
print('---------')
# 改变类的属性,实例对象的属性也会随之改变
Person.name = 'K'
print(q.name,q.age)
print(Person.name,Person.age)
print('---------')
其结果是:
xiaoming 12
xiaoming 12
---------
xiaohong 12
xiaoming 12
---------
K 12
K 12
案例二:
# 修改实例对象的属性,如果这个属性不存在就添加一个新属性,如果这个属性存在,则修改原来的属性,
class Person:
#定义一个属性
name = 'xiaoming'
age = 12
m = Person()
print(m.name,m.age)
# 修改实例对象的属性
m.age = 20
m.city = 'china'
print(m.name,m.age,m.city)
print(Person.name,Person.age)
print('-----------')
# 修改类的属性
print(Person.name,Person.age)
Person.name = 'K'
Person.country = 'wuhan'
print(Person.name,Person.age,Person.country)
print(m.name,m.age,m.city,m.country)
其结果是:
xiaoming 12
xiaoming 20 china
xiaoming 12
-----------
xiaoming 12
K 12 wuhan
K 20 china wuhan
2.3 类的访问权限
前面我们所定义的name和age都是公有的,但是也可以在类外通过对象名访问,如果想定义成私有的,则需要在前面加两个下划线’__',
私有只能在类中通过类的方法访问
class Person:
#定义一个属性
__name = 'xiaoming'
__age = 12
def show():
print(Person.__name,Person.__age)
Person.show()
print(Person.name,Person.age)
其结果是:
xiaoming 12
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
~\AppData\Local\Temp/ipykernel_5984/4178776923.py in <module>
12
13 Person.show()
---> 14 print(Person.name,Person.age)
AttributeError: type object 'Person' has no attribute 'name'
3.类的方法
类中除了类属性之外还有函数方法方法,方法包括以下三种:实例方法、类方法、静态方法,
class Person:
name = 'xioaming'
age = 24
# 实例方法:实例方法不需要修饰,但是参数是self
def instanceShow(self):
print(self.name,self.age)
# 类方法:类方法需要使用@classmethod来修饰,而且第1个参数一般命名为cls
@classmethod
def classShow(cls):
print(cls.name,cls.age)
# 静态方法:静态方法需要@staticmethod使用来修饰,不需要向函数传递任何参数,
@staticmethod
def staticShow():
print(Person.name,Person.age)
p = Person()
p.instanceShow()
# 类调用实例方法,将p传递给函数的self参数,
Person.instanceShow(p)
Person.classShow()
# 对象调用类方法,
p.classShow()
Person.staticShow()
# 对象调用静态方法,
p.staticShow()
其结果是:
xioaming 24
xioaming 24
xioaming 24
xioaming 24
xioaming 24
xioaming 24
4.对象初始化
面向对象编程总会在对象实例化的时候做一些初始化工作,这些工作都是自动完成的,有默认的函数被调用,这个默认的方法就是构造函数,对程序进行初始化,与之相对应的是析构函数,释放被创建的对象。两个函数都是系统默认的,如果用户没有定义,则会调用系统的方法。
class Person:
# 构造方法:__init__(self,......) 生成对象时调用可以用来进行一些初始化工作,不需要自己调用,系统会默认执行,
def __init__(self,n):
print('__init__:',self,n)
self.name = n
# 析构方法:__del__(self) 在释放对象时调用,可以在里面进行一些释放资源的操作,不需要显示调用,
def __del__(self):
print('__del__:',self)
def show(self):
print(self,self.name)
p = Person('xiaoming')
p.show()
print(p)
其结果是:
__init__: <__main__.Person object at 0x000002DBF4E57040> xiaoming
__del__: <__main__.Person object at 0x000002DBF4E51640>
<__main__.Person object at 0x000002DBF4E57040> xiaoming
<__main__.Person object at 0x000002DBF4E57040>
4.1 对象的初始化
构造函数是建立对象实例的自动调用函数,我们可以在这个函数中为实例对象初始化属性值.
class Person:
def __init__(self,n,g,a):
self.name = n
self.gender = g
self.age = a
def show(self):
print(self.name,self.gender,self.age)
p = Person('hong','male',20)
p.show()
其结果是:
__del__: <__main__.Person object at 0x000002DBF4E57040>
hong male 20
4.2 构造函数的重载
Python中只允许有一个构造函数,我们可以通过设置构造函数的默认参数,实现不同对象的初始化,实现构造函数的重载。实现不同初始化的要求,
class Person:
def __init__(self,n='',g='male',a=0):
self.name = n
self.gender = g
self.age = a
def show(self):
print(self.name,self.gender,self.age)
a = Person('hong')
b = Person('hong','female')
c = Person('hong','female','25')
a.show()
b.show()
c.show()
其结果是:
hong male 0
hong female 0
hong female 25
5.类的派生与继承
对象的一个很大特点是累可以被扩展和继承,缩短了我们编码的时间。
定义一个student类,它可以从person类中继承name gender和age,同时他也有自己的属性,
格式:class className(className): 括号中为要继承的类
继承类构造函数,属性方法的继承,
class Person:
def __init__(self,name,gender,age):
self.name = name
self.gender = gender
self.age = age
def show(self,end='\n'):
print(self.name,self.gender,self.age,end=end)
class Student(Person):
def __init__(self,name,gender,age,major,dept):
# 从person中继承属性,继承类构造函数,必须得显示调用才可以,
Person.__init__(self,name,gender,age)
# Student自己的属性
self.major = major
self.dept = dept
def show(self):
# 继承person中的方法,如果基类中有这个方法,新的类定义同样的方法,则方法以新的类方法为主,我们称新类的方法重写了基类的方法,
# 新的类也可以新增自己的方法
Person.show(self,' ')
print(self.major,self.dept)
s = Student('hong','male',21,'people','first')
s.show()
其结果是:
hong male 21 people first
属性方法的继承案例:
# 属性方法的继承
class Person:
def __init__(self,name,gender,age):
self.name = name
self.gender = gender
self.age = age
def show(self,end='\n'):
print(self.name,self.gender,self.age,end=end)
def display(self,end='\n'):
print(self.name,self.gender,self.age,end=end)
class Student(Person):
def __init__(self,name,gender,age,major,dept):
Person.__init__(self,name,gender,age)
self.major = major
self.dept = dept
def show(self):
Person.show(self,' ')
print(self.major,self.dept)
def setName(self,name):
self.name = name
s = Student('hong','male',21,'people','first')
# show方法被新的类重写,基类的方法失效
s.show()
s.display()
s.setName('ming')
s.show()
s.display()
其结果是:
hong male 21 people first
hong male 21
ming male 21 people first
ming male 21