【Python】类

面向对象编程

定义:是一个抽象的模板。
通过关键字class来定义。
class + 类名(object)

class Studentobject

类名首字母一般是大写。object表示该类从哪个类继承下来。

实例

定义:根据类创建出的一个个具体的对象。
实例 = 类名()

bart = Student()

bart指向Studen的实例。
可以给实例绑定属性。

bart.name = ‘Ann’

在创建实例的时候,可以把必须绑定的属性添加进去。通过定义一个特殊的init方法。

def __init__(self, name, score):
    self.name = name
    self.score = score

_init_方法的第一个参数永远是self,表示创建的实例本身,因此,在_init_方法内部,就可以把各种属性绑定到self,因为self就指向创建的实例本
身。有了_init_方法,在创建实例的时候,就不能传入空的参数了,必须传入与_init_方法匹配的参数,但self不需要传,Python解释器自己会把实例变量传进去:

bart = Student('Bart Simpson', 59)
>>>bart.name
'Bart Simpson'
>>>bart.score
59

属性相当于普通函数的参数,在类中定义的函数,第一个参数永远是实例变量self,调用时,不需要传递参数,只需要添加属性。

数据封装

直接在类的内部定义访问数据的函数,相当于把“数据”封装起来了,封装这些数据的函数与类本身是关联的,称之为类的方法。

class Student(object):

    def __init__(self, name, score):
        self.name = name
        self.score = score

    def print_score(self):
        print('%s: %s' % (self.name, self.score))

init和print_score都是类的方法,而print_score是从内部访问数据。

>>> bart.print_score()
Bart Simpson: 59

要调用,直接在实例变量上调用。
实例变量 + .方法

访问限制

从前面Student类的定义来看,外部代码还是可以自由地修改一个实例的name、score属性:

>>> bart = Student('Bart Simpson', 59)
>>> bart.score
59
>>> bart.score = 99
>>> bart.score
99

如果要让内部属性不被外部访问,可以把属性的名称前加上两个下划线,在Python中,实例的变量名如果以开头,就变成了一个私有变量(private),只有内部可以访问,外部不能访问。
如果外部代码要获取name和score怎么办?可以给Student类增加get_name和get_score这样的方法:

class Student(object):
    ...

    def get_name(self):
        return self.__name

    def get_score(self):
        return self.__score

如果又要允许外部代码修改score怎么办?可以再给Student类增加set_score方法:

    def set_score(self, score):
        self.__score = score

在Python中,变量名类似xxx的,也就是以双下划线开头,并且以双下划线结尾的,是特殊变量,特殊变量是可以直接访问的,不是private变量,所以,不能用namescore这样的变量名。

练习

请把下面的Student对象的gender字段对外隐藏起来,用get_gender()和set_gender()代替,并检查参数有效性:

class Student(object):
    def __init__(self, name, gender):
        self.__name = name
        self.__gender = gender

    def get_gender(self):
        return self.__gender

    def set_gender(self, gender):
        self.__gender = gender

bart = Student('Ann', 'male')
if bart.get_gender() !=  'male':
    print('测试失败')
else:
    bart.set_gender('female')
    if bart.get_gender() != 'female':
        print('测试失败')
    else:
        print('测试成功')

测试结果:

测试成功

【注意】
在类的方法中,self.__name = name ,是指绑定属性。
在外部访问下,改变直接在实例后面改变参数, bart.name = ‘Ann’
在外部不可以访问下,利用set改变:
bart.set_gender(‘female’)

继承

已经定义一个class的时候,可以继承某个现有的class,新的class称为子类,被继承的class称为父类。
编写一个class,有一个run()方法:

class Animal(object):
    def run(self):
        print('Animal is running...')

当需要编写子类,Dog和Cat类时,直接从Animal类继承:

class Dog(Animal):
    pass

class Cat(Animal):
    pass

子类中的(object)就是Animal。

class Dog(Animal):
    pass

class Cat(Animal):
    pass

子类中的(object)就是Animal。

继承优点一:父类实现了什么功能,子类就继承了父类全部的功能。

dog = Dog()
dog.run()

cat = Cat()
cat.run()

结果:

Animal is running...
Animal is running...

优点二:可以对代码进行修改,添加一些方法。

class Dog(Animal):

    def run(self):
        print('Dog is running...')

class Cat(Animal):

    def run(self):
        print('Cat is running')

结果:

Dog is running...
Cat is running...

子类和父类存在相同的run()方法时,子类会覆盖父类的方法,执行子类下run()方法。

优点三:获得多态。
需要新编写一个函数:

def run_twice(animal):
    animal.run()

传入Animal的实例时:

>>> run_twice(Animal())
Animal is running...

传入Dog的实例时:

>>> run_twice(Dog())
Dog is running...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值