Python面向对象程序设计

持续更新中

类定义语法

通过“对象。成员”的方式来访问其中的数据或成员方法

class Car:      #定义类
    def infor(self):      #成员方法
        print("This is a car")
#实例化对象
car=Car()
car.infor()

#在Python中,可以使用内置函数instance()来测试一个对象是否为某个类的实例,返回True或False
isinstance(car,Car)

pass表示空语句

class A:
	pass
def demo():
	pass
if 5>3:
	pass

self参数

类的所有实例方法都至少有一个名为self的参数,并且必须是方法的一个形参(如果有多个形参),self参数表示对象本身。在类的实例方法中访问实例属性时需要以self为前缀,但在外部通过对象名方法时并不需要传递这个参数,如果在外部通过类名调用对象方法则需要显式为self参数传递该类的一个对象

类成员与实例成员

1.实例属性:一般在构造方法__init()__()中定义的,定义和使用时必须以self作为前缀;
2.类属性:在类中所有方法之外定义的数据成员

在主程序中(或类的外部),实例属性属于实例(对象),只能通过对象名访问;
而类属性属于类,可以通过类名或对象名访问

在Python中,可以动态地为类和对象增加成员,这一点是和很多面向对象程序设计不同的,也是Python动态类型特点的一种重要体现

import types

class Car:
    price = 100000      #定义类属性
    def __init__(self,c):
        self.color=c        #定义实例属性

car1=Car("Red")
car2=Car("Blue")
print(car1.color,Car.price)
Car.price=199999        #修改类属性
Car.name='QQ'       #增加类属性
car1.color="Yellow"     #修改实例属性
print(car2.color,Car.price,Car.name)
print(car1.color,Car.price,Car.name)

def setSpeed(self,s):
    self.speed=s

car1.setSpeed=types.MethodType(setSpeed,car1)    #动态为对象增加成员方法
car1.setSpeed(50)       #调用对象的成员方法

编译结果:
Python面向对象程序设计_第1张图片

私有对象和公有对象

如果成员名以两个下划线开头但不以两个下划线结尾,则表示是私有对象。
私有对象在类的外部不能直接访问,需要调用对象的公有成员方法来访问,或者通过Python支持的特殊方式来访问

公有对象可以公开使用,既可以在类的内部进行访问,也可以在外部程序中使用

class A:
    def __init__(self,value1=0,value2=0):
        self.value1=value1
        self.__value2=value2        #私有数据对象
    def __setValue__(self,value1, value2):
        self.value1=value1		#这句删除后结果不变
        self.__value2=value2        #在成员方法中访问私有数据对象
    def show(self):
        print(self.value1)
        print(self.__value2)

a=A()
a.value1
a._A__value2

编译结果:
Python面向对象程序设计_第2张图片

在Python中,带下划线的变量名和方法名有特殊的含义,尤其是在类的定义中。
用下划线作为变量名和方法名前缀名和后缀来表示类的特殊成员

  1. _xxx:这样以单下划线开头的对象叫作保护成员,模块中这样的对象默认不能用from module import * 导入
  2. _ _ xxx _ _:前后各两个下划线表示系统预定义的特殊成员,不能随意定义和增加
  3. _ _ xxx:以双下划线开头类中的私有成员,只有该类对象自己能访问,子类对象也不能直接访问这个对象,但在对象外部可以通过“对象名._ 类名 _ _xxx ”这样的特殊方式来访问。PPython中不存在严格意义上的私有成员

方法

在类中定义的方法可以粗略分为四大类:公有方法、私有方法、静态方法和类方法。
公有方法通过对象名直接调用
私有方法不能通过对象名直接调用,只能在属于对象的方法中通过 self 调用或在外部通过 Python 支持的特殊方式来调用。
如果通过类名来调用属于对象的公有方法,需要显式为该方法的 self 参数传递一个对象名,用来明确指定访问哪个对象的数据成员。
静态方法和类方法都可以通过类名和对象名调用,但不能直接访问属于对象的成员,只能访问属于类的成员。
一般将 cls 作为类方法的第一个参数名称,但也可以使用其他的名字(不建议这样做)作为参数,并且在调用类方法时不需要为该参数传递值。例如:

class Root:
    __total=0       #属于类的私有数据对象
    def __init__(self,v):
        self.__value=v
        Root.__total+=1

    def show(self):     #普通实例方法
        print('self.__value:',self.__value)
        print('Root.__tatal:',Root.__total)

    @classmethod        #修饰器
    def classShowTotal(cls):        #类方法
        print(cls.__total)

    @staticmethod
    def staticShowTotal():      #静态方法
        print(Root.__total)     #静态方法可以访问类的成员,但要使用类的名字作为前缀

r=Root(3)
r.classShowTotal()      #通过对象调用类方法
r.staticShowTotal()     #通过对象来调用静态方法
r.show()        #通过对象来调用对象的公有成员方法

rr=Root(5)
Root.classShowTotal()
Root.staticShowTotal()

Root.show()     #试图通过类名直接调用
Root.show(r)        #但是通过这种方法来调用方法并访问实例成员
Root.show(rr)       #通过类名调用实例方法时为self参数显示传递对象名

编译结果:
Python面向对象程序设计_第3张图片

属性

class Test:
    def __init__(self,value):
        self.__value=value

    @property       #修饰器,定义属性
    def value(self):        #只读,无法修改和删除
        return self.__value

t=Test(3)
t.value
t.value=5       #只读属性不允许修改值

t.v=5       #动态增加新成员,和只读属性
t.v

del t.v     #动态删除成员
del t.value     #试图删除对象的只读属性,失败
t.value

下面的代码把属性设置为可读、可修改,而不允许删除

class Test:
    def __init__(self,value):
        self.__value=value

    def __get(self):        #访问属性时调用的方法
        return self.__value

    def __set(self,v):      #修改属性时调用的方法
        self.__value=v

    value=property(__get,__set)     #修饰器,定义可读可写属性

    def show(self):     #普通成员方法
        print(self.__value)

t=Test(3)
t.value     #允许读取属性值

t.value=5		#允许修改属性值
t.value

t.show()		#属性对应的私有变量也得到了相应的修改
del t.value		#试图删除属性,失败

当然,也可以将属性设置为可读、可修改、可删除

class Test:
    def __init__(self,value):
        self.__value=value

    def __get(self):
        return self.__value

    def __set(self,v):
        self.__value=v

    def __del(self):    #删除属性时调用的方法
        del self.__value    #删除对应的私有数据成员

    value=property(__get,__set,__del)

    def show(self):
        print(self.__value)

t=Test(3)
t.show()
t.value
t.value=5
t.show()
t.value

del t.value     #删除对象属性及其对应的私有数据成员
t.value
t.show()

t.value=1
t.value
t.show()

继承机制

示例: 在派生类中调用基类方法
首先设计Person类,然后以Person为基类派生Teacher类,分别创建Person类和Teacher类的对象,并在派生类对象中调用基类方法

class Person(object):
    def __init__(self,name='',age=20,sex='man'):
        self.setName(name)
        self.setAge(age)
        self.setSex(sex)

    def setName(self,name):
        if not isinstance(name,str):        #判断name是不是string类型
            print('name must be string')
            return
        self.__name=name

    def setAge(self,age):
        if not isinstance(age,int):
            print('age must be int')
            return
        self.__age=age

    def setSex(self,sex):
        if sex not in('man','woman'):
            print('sex must be "man"or"woman"')
            return
        self.__sex=sex

    def show(self):
        print('Name:',self.__name)
        print('Age:',self.__age)
        print('Sex:',self.__sex)

class Teacher(Person):      #派生类
    def __init__(self,name='',age=30,sex='man',departmant='Computer'):
        super(Teacher, self).__init__(name, age, sex)
        #也可以使用下面的形式对基类数据成员进行初始化
        #Person.__init__(self, name, age, sex)       #使用基类方法进行初始化
        self.setDepartment(departmant)

    def setDepartment(self,department):
        if not isinstance(department,str):
            print('department must be a string.')
            return
        self.__department=department

    def show(self):
        super(Teacher, self).show()
        print('Department:',self.__department)

if __name__=='__main__':
    zhangsan=Person('Zhangsan San')
    zhangsan.show()
    lisi=Teacher('Li Si',32,'man','Math')
    lisi.show()
    lisi.setAge(40)
    lisi.show()

编译结果:

Python面向对象程序设计_第4张图片

为了更好地理解Python类的继承机制,再来看下面的代码,并认真体会构造方法、私有方法和普通公开方法的继承原理

class A(object):
    def __init__(self):
        self.__private()
        self.public()

    def __private(self):
        print('__private() method in A')

    def public(self):
        print('public() method in A')

class B(A):     #注意,类B没有定义构造方法
    def __private(self):
        print('__private() method in A')

    def public(self):
        print('public() method in B')

b=B()
dir(B)

class C(A):
    def __init__(self):     #显示定义构造方法,覆盖率A类中的构造方法
        self.__private()
        self.public()

    def __private(self):
        print('__private() method in C')

    def public(self):
        print('public() method in C')

c=C()
dir(c)

dir() 函数不带参数时,返回当前范围内的变量、方法和定义的类型列表;带参数时,返回参数的属性、方法列表。

你可能感兴趣的:(Python,python)