python面向对象程序的设计

类是对象的基础,对象是类的现实

一、面向对象技术

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()

在执行过程中,类的构造函数将自动执行,不需要调用,而析构函数在类代码执行完毕后,自动执行,回收资源。

在这里插入图片描述

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值