Python类

一、概述:

对象:是一个抽象的概念,表示任意存在的事物,世间万物皆对象,对象是事物存在的实体,如一个人也是一个对象。

通常将对象划分为两个部分,静态部分和动态部分 ,静态部分被称为属性,任何对象都具备自身属性,这些属性不仅是客观存在的,而且是不容忽视的,例如人的性别,动态部分指的是对象的行为,即对象执行的动作,例如人可以跑步。

注意:在Python中,一切皆对象,不仅具体的事物称为对象,字符串、函数也都是对象,说明Python天生就是面向对象的。

类:类是封装对象属性和行为的载体,反过来说,具有相同属性和行为的一类实体称为类,例如,把大雁比喻大雁类,那么大雁类就有了翅膀、爪的属性,飞行、觅食、睡觉的行为,其中的一只大雁被称为类的对象,对象是类的实例类是对象的抽象

二、面向对象程序设计特点

面向对象程序设计三大基本特征:封装、继承、多态

1、封装:

封装是面向对象编程的核心思想,将对象的属性和行为封装起来,其载体就是类,类通常会对用户隐藏实现细节,这就是封装的思想。例如:用户使用计算机,只需要敲击键盘就可以实现一些功能,而不需要知道计算机内部是如何工作的。

采用封装思想保证了类内部数据结构的完整性,使用该类的用户不能直接看到类中的数据结构,只能执行类允许公开的数据,这样避免了外部对内部数据的影响,提高了程序的可维护性。

2、继承:

矩形、菱形、平行四边形都是四边形,四边形与他们具有共同的特性,拥有四条边,只需要将四条边适当的延伸就可以得到上述的各种图形,每个图形都具备四边形的属性和行为,因此四边形类可以看成其他图形的父类,并在此基础上添加了自己的属性和行为(比如平行四边形),Python中之类的实例都是父类的实例,但不可以说父类的实例是子类的实例。

综上所述:继承是实现复用的重要手段,子类通过继承复用了父类的属性和行为,同时添加了子类特有的属性和行为。

3、多态:

将父类对象应用于子类的特征就是多态,比如创建一个螺丝类,有两个属性:粗细和螺纹密度,然后再创建两个类,一个长螺丝类、一个短螺丝类,他们都继承了螺丝类,具有螺丝类的属性(粗细和螺纹密度),还具有不同的特征,一个长、一个短,综上所述:子类继承父类特征的同时,也具备了自己的特征,并且能实现不同的效果,这就是多态的结构。

三、类的定义和使用:

在Python中,类表示具有相同的属性和方法的对象的集合。在使用的时候,需要先定义类,然后创建类的实例,通过类的实例就可以访问类中的属性和方法了。

1、类的定义:

在Python中,类的定义使用class关键字实现,语法格式如下:

class Classname:
    '''类的帮助信息'''
    statement

参数说明:

  1. Classname:定义的类名,如果由多个单词构成,建议通过驼峰命名法进行命令,首字母建议大写
  2. ”’ ”’ 表示帮助信息,也就是注释的意思,说明类的功能
  3. statement:类体,表示此类具体要执行的功能,如果还没想好此类的具体功能,也可以先用pass代替

例如:声明一个类,但是还没有想好此类的具体功能,此时可用pass代替类体,如图:

注意:在定义类的时候,类名建议采用驼峰发,首字母要大写,因为类的实例化和函数调用比较像,如果首字母小写容易跟函数混淆,无法判断是函数还是类(函数一般以小写字母命名)

2、创建类的实例:

class语句本身并不创建任何类的实例,所以在类定义完成后,需要创建类的实例,实例化该类的对象,创建类的实例语法格式如下:

ClassName(parameter)

其中ClassName表示要实例化的类,parameter表示可选参数,当创建一个类的时候,如果没有创建__init__()方法,或者__init__()方法中只有一个self参数的时候,parameter参数可以省略

例如:上面定义的大雁类,此时可以对类进行实例化,如图:

3、创建__init__()方法

在创建完类之后,可以手动创建一个__init__()方法,该方法是一个特殊的方法,类似java语言中的构造方法,每当创建一个类的实例的时候,Python都会自动执行此方法,__init__()方法必须包含一个self参数,并且必须是第一个参数,self参数是一个指向实例本身的引用,用于访问类中的属性和方法,在方法调用时会自动传递实际参数self,因此在__init__()方法中只有一个参数时,在创建类的实例的时候就不要指定实际参数了,__init__的主要作用就是初始化类,比如设置参数,非必要可不写

例如:在大雁类中定义__init__()方法,如图:

打印结果如图所示:

在定义__init__()方法的时候,除了必须的self外,还可以定义多个参数,多个参数之间通过逗号分隔,如图:

注意:上面的self参数是必须的,但是不一定必须是self这个单词,用其他单词也是一样,只是习惯上用self,例如可以使用abc、efg都是可以的。

4、创建类的成员并访问

类的成员主要由实例方法和数据成员组成,在类中创建了类的成员后,可以通过类的实例进行访问。

创建实例方法并访问:

所谓实例方法是指在类中定义的函数,此函数是一种在类的实例上操作的函数,同__init__()方法一样,此实例方法的第一个参数也必须为self(不一样非要self这个单词,习惯上写成self),语法格式如下:

def functionName(self,parameter):
    block

参数说明:

  1. functionName:函数名,一般以小写字母开头,采用驼峰命名法
  2. self:必选参数,表示类的实例,不一样非要用self这个单词。
  3. parameter:用户指定除了self参数以外的参数,多个参数用逗号分隔
  4. block:方法体,用于实现具体的功能。

注意:实例方法和Python的函数主要区别是:函数实现的是某一独立的功能,实例方法实现的是类中的功能,是类的一部分,方法中有self,函数中没有self

实例方法创建后,可以通过类的实例名和点(.)操作符进行访问,语法格式如下:

instanceName.functionName(parameter)

参数说明:

  1. instanceName:表示创建的实例名
  2. functionName:表示类中的实例方法名(实例名调用此方法)
  3. 调用的时候传递的参数,与定义实例方法时参数个数相同

例如:在创建大雁类后,创建实例方法fly,并调用,如图:

打印结果如下:

注意:在创建实例方法时也可以像创建函数的时候一样为参数指定默认值,但被设置默认值后的参数必须位于最后面,例如上面的def fly(self,flyhtigh=”1000m”),这样在调用的时候就不需要传递参数了。

创建数据成员并访问:

数据成员是指在类中定义的变量,即属性,根据定义的位置可以分为类属性和实例属性。

类属性

是指定义在类中,并且在函数体外的属性,类属性可以在所以实例之间共享值,也就是在所有实例化的对象中公用,类属性可以通过类名称或者实例名访问。

例如:定义一个大雁类,并定义三个类属性,如图:

下面通过一个例子演示类属性在类的所有实例之间共享值的应用

例如:定义一个大雁类,其中有四个类属性,前三个表示大雁特征,第四个表示实例编号,再定义一个构造方法,在此方法中将实例编号执行加1操作,打印四个类属性的值,然后通过for循环创建4个类的实例,如图:

在Python中除了可以通过类名称访问类属性,还可以动态的为类和对象添加属性,例如,在上图中的例子上添加一个beak属性,并通过类实例访问该属性,如图:

注意:除了可以动态的为类和对象添加属性,还可以动态修改类的属性,修改后的属性作用于类的所有实例。

实例属性:

实例属性是指定义在类的方法中的属性,只作用于当前实例中。

例如:定义一个大雁类,并定义三个实例属性,记录大雁的特征,如图:

注意:实例属性只能通过实例名进行访问,如果通过类名访问将报错

实例属性也可以通过实例名更改,与类属性不同,通过实例名修改属性后,不影响另一实例中相应实例属性的值。

例如:定义一个大雁累,其中定义实例属性,并创建两个实例,实例1更改了实例属性的值,实例2并没有被影响,如图:

5、访问限制:

在类的内部可以定义属性和方法,在类的外部可以调用属性和方法来操作数据,从而隐藏类内部复杂的业务逻辑,但是Python中没有对属性和方法的访问权限进行限制,为了保证类内部的属性和方法不被外部所访问,可以在属性或方法前添加单下划线(_var)、双下划线(__var)、或者首尾添加双下划线(__var__),从而限制访问权限,他们的作用说明如下:

  1. 双下划线表示定义特殊方法,一般是系统定义名字,如__init__()
  2. 以单下划线开头的表示保护类型的成员(protected),只允许类本身和子类进行访问,不能使用from module import * 导入
  3. 双下划线表示私有(private)类型的成员,只允许定义该方法的类本身进行访问,而且也不能通过类的实例进行访问,但是可以通过类的实例名._类名__属性或方法的方式进行访问

例如1:定义一个大雁类,定义一个单下划线属性(保护),定义构造方法,如图:

从上图中可以看出,保护属性可以通过实例名进行调用。

例如2:定义大雁类,定义私有属性(双下划线),定义构造方法,如图:

四、属性:

1、创建用于计算的属性:

在Python中,可以通过@property(装饰器)将一个方法转换成属性,从而实现用于计算的属性,将方法转化为属性后可直接通过方法名来访问方法,而不需要再添加一对小括号(),从而让代码更加简洁。语法格式如下:

@property
def mothodname(self):
    block

参数说明:

  1. mothodname:方法名,一般用小写字母开头,该名称最后将作为创建的属性名。
  2. self:必须参数,表示类的实例
  3. block:方法体,用于实现具体的功能,通常以return语句结束,用于返回计算的结果。

例如:定义矩形类,定义构造方法,创建实例属性,并通过@property装饰器将方法转化为属性,最后通过实例名调用转化后的属性打印矩形面积,如图:

注意:通过@property转换后的属性不能重新赋值,如果重新赋值,将抛出异常

五、继承:

在编写类的时候,并不一定每次都要从空白开始写,当编写的类和另一个已经存在的类之间存在一定的继承关系时,就可以通过继承来达到代码重用的目的,提高开发效率。

1、继承的语法:

在程序设计中实现继承,表示这个类拥有它继承的类的所有公有成员或者受保护成员,被继承的类称为父类或者基类,新的类称为子类或者派生类。通过继承不仅可以实现代码的复用,还可以通过继承来理顺类与类之间的关系。

在Python中,在定义类语句的时候,可以在类名右侧小括号中将要继承的基类括起来,从而实现类的继承,语法格式如下:

class ClassName(baseclass):
    '''类的帮助信息'''
    statement

参数说明:

  1. ClassName:用于指定类名
  2. baseclass:指定要继承的基类,可以有多个基类,类名之间用逗号分隔,如果不指定,默认使用Python对象的根类object
  3. ”’类的帮助信息”’:说明此类的功能是什么,类似注释功能
  4. statement:类体,表示此类实现的功能,如果没有想好具体功能,可以先用pass语句代替。

例如:定义水果类作为基类,定义类属性用于保存水果的颜色,定义harvest()方法,在定义Apple类和orange类,这两个类继承水果类,最后创建Apple类和orange类的实例,并调用harvest()方法,如图:

2、方法重写:

基类的成员都会被子类继承,当基类中的某个方法不适用于子类的时候,就需要在子类中重写基类的方法,下面重写Apple方法,如图:

3、子类中调用基类的__init__()方法:

在子类中定义__init__()方法时,默认不会调用基类的__init__()方法,如果要让子类可以调用基类的__init__()方法,需要进行必要的初始化,通过super()函数调用基类的__init__()方法,如图:

标签