类是对象的基础,对象是类的现实
文章目录
一、面向对象技术
1.类与对象
类(class)和 对象(object)
类是客观事物的抽象,而对象是类的一个名词
1)类
类 | 属性(成员变量) |
---|---|
类 | 方法(成员函数) |
假如小狗定义为一个类Dog,在Dog中的属性就要反映所有小狗的共同特征,如毛色,体型,品种等。方法就是类描述对象所共有的功能、实现某种功能的函数。在Dog类中,看家、奔跑、吃食就是方法。
2)对象
所谓对象就是以类为模板创建出来的,可以在内存中运行的实体。根据类来创建对象的方法就是实例化操作,而用户产生的对象也称作类的一个实例化操作。
2.面向对象的特点
采用面向对象程序设计模式可以提高程序设计的效率,提高代码的安全性和可维护性。面向对象的这些优点主要是通过继承、封装、多态来实现的。
- 继承
子类能自动取得父类中定义的属性和方法 - 封装
封装的目的是提高代码的独立性和安全性。封装可以保护定义在泪中的属性,在任何类之外是我程序不能对类中的属性进行定义与修改。只有类中的成员函数菜可以访问类中的属性。 - 多态
多态的目的是实现接口复用。封装完毕后,类外的程序需要使用类提高接口函数来访问数据。接口复用就是一个功能接口,根据实例不同,执行不同的操作。
二、python中的类
1.类定义
方法1:
class<类名称>:
语句1
语句2
...
语句n
class Empty:
pass
方法2:
class<类名称>:
<属性名称>=<属性取值>
def<方法名称>(self):
<方法语句>
2.类实现
类实例化操作格式如下:
<实例对象>=<类名称>()
访问语法的格式:
<实例对象>.<属性名称>
<实例对象>.<方法名>([<参数序列>])
class MyRect:
a=0
b=0
#a,b分别是两个属性名称,并且分别赋初值为0
def getLen(self):
#定义了getlen()的 方法 用于计算周长
L=2*(self.a+self.b)
return L
def getS(self):
#定义了getS()的 方法 用于计算面积
S=self.a*self.b
return S
'''以上是类的定义,但类定义后不能运行的。如果需要实现类中的方法,
用户必须对类进行实例化操作,通过类来创建对象,由对象来实现类中的方法'''
rect=MyRect() #这里的rect是生成的类的对象名称,用户可以使用该实例来访问类中的属性和方法
rect.a=20
rect.b=10
print("a=",rect.a,"b=",rect.b)
print("L=",rect.getLen())
print("S=",rect.getS())
三、类的属性
分类
- 按照申明属性的位置分,分为类属性和实例属性
- 按照访问属性的权限不同,分为共有属性和私有属性
1.类属性
class CAttribute:
"""定义了有两个属性的类"""
a = 10
b = 20
t1 = CAttribute()
'''生成一个实例t1'''
print("实例1访问:", t1.a, t1.b) # a=10,b=20
print("直接访问", CAttribute.a, CAttribute.b) # a=10,b=20
t1.a = 100 # 通过实例修改属性值,只在该实例中有效,离开该实例候无效
CAttribute.b = 300 # 通过名称修改属性值
print("实例1访问", t1.a, t1.b) # a=100,b=300
print("直接访问", CAttribute.a, CAttribute.b) # a=10,b=300
t2 = CAttribute()
'''重新生成实例2'''
print("实例1访问", t1.a, t1.b) # a=100,b=300
print("实例2访问", t2.a, t2.b) # a=10,b=300
print("直接访问", CAttribute.a, CAttribute.b) # a=10,b=300
2.实例属性
用户定义实例属性时,必须要有两个要点:
- 必须在类的构造方法内定义实例属性,通常情况下默认在类的构造方法__init__()方法中定义属性。
- 定义实例属性时,属性名称前要有self关键字
self.<属性名称>=<属性取值>
import self as self
class IAttribute():
def __init__(self):
self.name="月月"
self.age=17
"""上面四行代码定义了一个类,该类有一个构造函数,在函数中定义了两个实例属性name和age"""
t1=IAttribute() #通过实例来访问属性,读取实力属性的取值
print(t1.name+'今年'+str(t1.age)+"岁。")
t1.name="王明" #修改实力属性的值,只在本实例中有效。
t1.age=19
print(t1.name+"今年"+str(t1.age)+"岁")
t2=IAttribute()
print(t2.name+"今年"+str(t2.age)+"岁")
# print(IAttribute.name) #使用用户名访问实例属性会报错
3.公有属性和私有属性
无论是类属性还是实例属性,按照访问权限不同,可以把它们分为公有属性和私有属性两类。
用普通的方式定义的都是公有属性,无论是类中的方法还是类外的函数可以直接访问公有属性。
而私有属性只有在类中定义的方法可以放问,类之外的函数不能直接访问私有属性。
私有属性定义时,需要双下划线引导,用以和普通属性区分。
eg:__name=“xiaoming”
class PriAttribute:
__name = "齐七七"
def getName(self):
print(self.__name)
t = PriAttribute()
print(PriAttribute.__name)
编译结果可以看出类外函数访问类中的私有属性,系统会触发异常。
4.特殊属性
属性名称 | 属性含义 |
---|---|
name | 类名称 |
doc | 类文档名称 |
base | 列表类型,记录所有父类名称 |
dict | 字典类型,记录类中所有属性 |
class | 类对象的类型 |
四、 python类的方法
python类的方法是定义在类中函数。根据调用方式,方法分为实例方法、类方法和静态方法。
根据访问权限,方法可以分为公有方法和私有方法。
1.实例方法、类方法、静态方法
所有定义在类中的方法,如果可以访问类中的属性,成为类方法;
反之,不能访问类中属性的方法成为静态方法,实例方法只能被实例对象调用。
1) 实例方法
“用户在定义实例方法时,需要为实例方法至少指定一个参数self,该参数用于绑定调用实例方法的实例对象,,绑定工作系统自动完成”
用户在类中定义实例方法的方式:
def<方法名称>(self,[<参数列表>)
<方法语句>
用户可以使用实例来调用实例方法,调用方式:
<实例>=<类名称>()
<返回对象>=<实例>.<实例方法名称>([<参数列表>])
用户也可以使用类名称来调用实例方法,但是在按照名称调用过程中,必须将实例对象作为类的参数
调用方法:
<实例>=<类名称>()
<返回对象>=<类名称>(<实例>[,<参数列表>])
class Method():
a=100
def add(self,n):
self.a=self.a+n #add方法将a的值自加100
def list(self):
print(self.a) #list将方法a打印
"""定义了Method类,类中定义了一个类变量a,两个实例方法"""
print("t1:")
t1=Method()
t1.add(100) #利用实例调用方法
t1.list()
print("t2:")
t2=Method()
Method.add(t2,200)
Method.list(t2) #利用类名称调用实例方式
不同实例调用同一个实例方法,彼此不会影响。一般情况下尽量使用实例的方式来调用实例方法。
2)类方法
在程序设计的过程中,有时用户需要处理的对象是类本事,而不是类中的属性和方法。
用户可以利用类名称或类实例来调用类方法。在类方法中,用户可以访问类中声明的属性内容。
用户在声明类方法时,需要使用以下语句:
@classmethod
def classmethodname(self):
<方法语句>
像self这样的参数用户至少要提供一个,表示这是类方法,取值可以是 self、obj、cls等。通常使用cls,
而在调用该方法时可以省略参数
类方法的调用可以通过类名称调用,也可以通实例调用类中实例方法。
通过实例调用静态方法的方式:
<实例名>=<类名>()
[<返回对象>]=<实例名>.<类方法名称>([<参数列表>])
通过类名称来调用静态方法:
[<返回对象>]=<类名称>.<类方法名称>([<参数列表>])
类方法与静态方法相比,主要的区别是用户可以使用类方法直接访问类中的属性。
在类中有一个名为AddCount的方法,请统计在程序中,该方法被调用了多少次。
class CMethod(): #申明一个CMethon的类
count=0 #定义一个类属性
@classmethod
def AddCount(cls):
cls.count=cls.count+1
print("AddCount","调用了",cls.count,"次") #类方法,定义一个能将count+1的方法名为AddCount()
CMethod.AddCount()
CMethod.AddCount()
CMethod.AddCount() #按名称调用类方法
t=CMethod() #定义一个实例
t.AddCount() #按实例调用类方法
3)静态方法
静态方法是定义在类中的一个特殊方法
语法格式:
@staticmethod
def staticname():
<方法语句>
静态语句虽然定义在类中,但不能访问类中定义属性。所以,在编程实践过程中,静态方法与所在类没有什么逻辑关系,把静态方法放入类中,仅仅是为了将一组函数放在一起,用户方便管理而已。
静态方法的参数可以为空。
通过实例来调用静态方法:
<实例名>=<类名>()
[<返回对象>]=<实例名>.<实例方法名称>([<参数列表>])
通过类名称来调用静态方法:
<实例名>=<类名>()
[<返回对象>]=<类名称>.<实例方法名称>([<参数列表>])
class SMethon():
a=10
b=20
@staticmethod
def add(m,n): #静态方法,输入两个参数
return m+n
@staticmethod
def otheradd(self): #静态方法,属性作为参数
return self.a+self.b
print("利用类名称调用方法")
ret=SMethon.add(100,200)
print(set)
print("利用类实例调用方法")
t=SMthod()
ret=SMethon.add(1000,2000)
print(ret)
print("访问类中属性")
ret=SMethon.add(SMthod.a,SMethon.b)
print(ret)
ret=t.otheradd()
print(ret)
用户节以利用类名称调用,也可以使用类实例调用类中的静态方法;用户可以为静态方法提供参数,也可以将类属性的值作为参数提供给静态函数;静态函数不能访问类属性,指的是在定义静态方法时不能使用类属性。
2.公有方法和私有方法
默认情况下,定义的方法都是公有方法;定义私有方法的格式:
def__<方法名称>([<参数列表>])
<方法列表>
注意私有方法的名称必须是双下划线引导
比较公有方法和私有方法
class PrivMethod:
def __PrivMethod(self):
print("这是一个私有方法")
def PubMethod(self):
self.__PrivMethod()
print("这是一个公有方法")
t=PrivMethod()
t.PubMethod()
t.__PrivMethod()
类中的方法可以调用私有方法,而类外的方法只能调用公有方法
面向对象的程序设计中,一般属性设置为私有,而方法设置为公有
3.构造方法和析构方法
在Python中,类的 私有方法 有两个重要方法,一个是构造方法,一个是析构方法。
1)构造方法
通常情况下,Python中的类在创建实例时,会自动执行构造方法,该方法的主要作用是对数据进行初始处理。
def __init__(self):
<方法语句>
在构造方法中至少需要一个参数self,如果需要,可以增加其他参数。
2)析构方法
通常情况下,在Python类实例执行完毕后,自动执行析构方法,该方法的主要任务是完成垃圾清理。
def __del__(self):
<方法语句>
面向对象的程序设计中,一般属性设置为私有属性,而方法设置为公有的实例方法。但是属性初始化赋值都是在构造函数中进行。
class Myclass():
def __init__(self,name,age):
print("构造函数执行")
self.name=name
self.age=age
def List(self):
print(self.name,"is",self.age,"old")
def __del__(self):
print("析构函数执行")
t=Myclass("王林",18)
t.List()
在执行过程中,类的构造函数将自动执行,不需要调用,而析构函数在类代码执行完毕后,自动执行,回收资源。