Python之面向对象编程:封装、继承、多态

Python是面向对象编程的语言,具有封装,继承,多态的特性。下面来了解一下如何在Python中进行对象编程。

一、封装

1、定义一个类

首先我们需要了解:类,类对象,实例对象,属性,函数和方法。

类:用于定义表示用户定义对象的一组属性的原型。是对现实世界中一些事物的封装,定义一个类可以采用下面的方式来定义:

注意:类名后面有个冒号。pass语句的地方是用来定义属性和方法的。当一个类定义完之后,就产生了一个类对象。

类对象支持2种操作:引用和实例化。引用操作是通过类对象去调用类中的属性或者方法,而实例化是产生出一个类对象实例,称为实例对象。比如定义了一个People类:


People定义完成之后就产生了一个全局的类对象,可以通过类对象来访问类中的属性和方法。当通过People.name来访问时,People.name中的People称为类对象。当然还可以进行实例化操作:p=People(),这样就产生了一个People的实例对象,由此也可以通过实例对象p来访问属性或者方法(如p.name)。



理解了类,类对象和实例对象的区别之后,我们来了解一下Python中的属性,方法和函数的区别。

在上面代码中注释写明了,name是一个属性,printName()是一个方法,与某个对象进行绑定的函数称作为方法。一般在类里面定义的函数与类对象或者实例对象绑定了,所以称作为方法。而在类外定义的函数一般没有同对象进行绑定,就称为函数。


2、属性

在类中,我们可以定义一些属性,例如:


定义了一个People类,里面定义了name和age属性,默认值分别为‘Flora’和24。在定义类之后,就可以用来产生实例化对象了。p=People()实例化了一个对象p,然后就可以通过p来读取属性了。这里name和age都是公有的,可以直接在类外通过对象名访问。如果想定义成私有的,则需要在前面加2个下划线‘__’.


因为私有属性是不能够在类外通过对象名来进行访问的,所以会报错。在Python中,不管是属性还是方法,都是以属性名称前面的2个下划线来区分公有还是私有。属性名字前面有2个下划线就是私有,没有则是公有。


3、方法

在类中可以根据需要定义一些方法,定义方法采用def关键字,在类中定义的方法至少会有一个参数,一般以名为‘self’的变量作为该参数(用其他名称也可以),而且需要作为第一个参数。看下面的示例:



self可以理解为对象自身的意思,在用某个对象调用该方法时,就将该对象作为第一个参数传递给self。


4、类中内置的方法

在Python中有一些内置的方法,这些方法命名都有比较特殊的地方,以2个下划线开始,2个下划线结束。类中最常用的就是构造方法和析构方法。

析构方法__init__(self,...)在生成对象时调用,可以用来进行一些初始化操作,不需要显示去调用,系统会默认执行。构造方法支持重载,如果用户自己没有定义构造方法,系统就自动执行默认的构造方法。

析构方法__del__(self)在释放对象时调用,支持重载,可以在里面进行一些释放资源的操作,不需要显示调用。

还有一些其他的内置方法:比如__cmp__(),__len()__等。


5、类属性,实例属性,类方法,实例方法以及静态方法

在前面的例子中,我们接触到了类属性:类对象所拥有的属性,它被所有类对象的实例对象所共有,在内存中只存在一个副本。对于公有的类属性,在类外可以通过类对象和实例对象访问。


上述报错是因为,私有的类属性,是不能在类外通过实例对象/类对象来访问的。


实例属性是不需要在类中显示定义的,比如在以下例子中,我们用p.age=24给实例对象p增加了一个实例属性age,赋值为24。这个实例属性是实例对象p所特有的,因此类对象People是不能访问age这个属性的,所以通过类对象People去访问实例属性age就会报错。



另外,我们还可以在实例化对象的时候给age赋值,如下面的例子所示:

例子中同样,类对象People是不能访问实例属性age的



如果需要在类外修改类属性,必须通过类对象去引用然后进行修改。如果通过实例对象去引用,会产生一个同名的实例属性,这种方法修改的是实例属性,不会影响到类属性,并且之后如果通过实例对象去引用该名称的属性,实例属性会强制屏蔽掉类属性,即引用的是实例属性,除非删除了该实例属性。如下面的例子所示:



下面来看类方法,实例方法和静态方法的区别。

类方法:是类对象所拥有的方法,需要修饰器‘@classmethod’ 来标识其为类方法,对于类方法,第一个参数必须是类对象,一般以‘cls’作为第一个参数(当然可以用其他名称的变量作为其第一个参数,但是大部分人都习惯以‘cls’ 作为第一个参数的名称,因此最好用‘cls’),能够通过实例对象和类对象去访问。



类方法还有一个用途就是可以对类属性进行修改。下面例子显示,在用类方法对类属性修改后,通过类对象和实例对象访问都发生了变化。


实例方法:在类中最常定义的成员方法,它至少有一个参数并且必须以实例对象作为其第一个参数,一般以名为‘self’的变量作为第一个参数(当然也可以以其他名称的变量作为第一个参数)。在类外实例方法只能通过实例对象去调用,不能通过其他方式去调用。



静态方法:需要通过修饰器‘@staticmethod’来进行修饰,静态方法不需要多定义参数。


对于类属性和实例属性,如果在类方法中引用某个属性,该属性必定是类属性,而如果在实例方法中引用某个属性(不做更改),并且存在同名的类属性,此时若实例对象有该名称的实例属性,则实例属性会屏蔽类属性,即引用的是实例属性;若实例对象没有该名称的实例属性,则引用的是类属性;如果在实例方法中更改某个属性,并且存在同名的类属性,此时若实例对象有该名称的实例属性,则修改的是实力属性,若实例对象没有该名称的实例属性,则会创建一个同名称的实例属性。想要修改类属性,如果在类外,则可以通过类对象修改;如果在类里面,只有在类方法中进行修改。

从类方法和实例方法以及静态方法的定义形式就可以看出来,类方法的第一个参数是类对象cls,那么通过cls引用的必定是类对象的属性和方法;而实例方法的第一个参数是实例对象self,那么通过self引用的可能是类属性,也有可能是实例属性,不过在存在相同名称的类属性和实例属性的情况下,实例属性的优先级更高。静态方法中不需要额外定义参数,因此在静态方法中引用类属性的话,必须通过类对象来引用。


二、继承

在Python中,如果需要的话,可以让一个类去继承一个类,被继承的类称为父类或者超类,也可以称作为基类,继承的类称为子类。并且Python支持多继承,能够让一个子类有多个父类。

在Python中类的继承定义基本形式如下:


在定义一个类的时候,可以在类名后面紧跟一对括号,在括号中指定所继承的父类,如果有多个父类,多个父类名之间用逗号隔开。以大学里的学生和老师举例,可以定义一个父类UniversityMember,然后类Student和类Teacher分别继承UniversityMember:


在大学中的每个成员都有姓名和年龄,而每个学生有学号和分数这2个属性,老师有教工号和工资这2个属性,从上面的代码中可以看到:

1)在Python中,如果父类和子类都重新定义了构造方法__init__(),在进行子类实例化的时候,子类的构造方法不会自动调用父类的构造方法,必须在子类中显示调用;

2)如果需要在子类中调用父类的方法,需要以[父类名.方法]这种方式调用,以这种方式调用的时候,注意要传递self参数过去;

3)对于继承关系,子类继承了父类所有的公共属性和方法,可以在子类中通过父类名来调用,而对于私有的属性和方法,子类是不进行继承的,因此在子类中是无法通过父类名来访问的;

4)对于多重继承,比如:class subClass(SuperClass1,superClass2)。此时有一个问题就是如果subClass没有重新定义构造方法,它会调用哪个父类的构造方法?这里记住一点:以第一个父类为中心。如果subClass重新定义了构造方法,需要显示去调用父类的构造方法,此时调用哪个父类构造方法由你自己决定;若subClass没有重新定义构造方法,则只会执行第一个父类的构造方法。并且若superClass1和superClass2中有同名的方法,通过子类的实例化对象去调用该方法时调用的是第一个父类中的方法。


三、多态

多态即多种形态,在运行时确定其状态,在编译阶段无法确定其类型,这就是多态。Python中的多态和Java以及C++中的多态有点不同,Python中的变量是弱类型的,在定义时不用指明其类型,它会根据需要在运行时确定变量的类型(个人觉得这也是多态的一种体现),并且Python本身是一种解释性语言,不进行预编译,因此它就只有在运行时确定其状态,故也有人说Python是一种多态语言。在Python中很多地方都可以体现多态的特性,比如内置函数len(object),len函数不仅可以计算字符串的长度,还可以计算列表、元组等对象的数据个数,这里在运行时通过参数类型确定其具体的计算过程,正式多态的一种体现。



注意:本文来源于:


  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值