面向对象有三大特征:多态(对应方法覆写)、封装、继承(对应方法重载),这个在Java中已经说得很详细了,这里面只是介绍Python在这三个特性方面的实现。

1 创建自定义类

  Python和Java一样使用class关键字来创建对象。语法格式如下:

class 类名:
  def 方法名1(参数列表):
    pass

  从上述语法来看,类必须使用class关键字来定义,接着是类名,然后使用pass占位。

一个例子如下:

class Person:
def getName(self):
print 'My name is AIQI'
def getAge(self):
print 'My age is 27'
def getHoppy(self):
print 'My hobby is love you'
>>> import Person
>>> person = Person.Person()
>>> person.getName()
My name is AIQI
>>> person.getAge()
My age is 27
>>> person.getHoppy()
My hobby is love you

实例应用

myStr = raw_input('Please input one object:')
class MyWorld:
#define one person method
def printPerson(self):
self.myTalk = 'I can speak'
self.myLimbs = 'I can move'
print 'I am a person so,I can %s, %s' % (self.myTalk, self.myLimbs)
#define one pig method
def printPig(self):
self.myTalk = 'Hengheng...'
self.myWeight = 'I am fat'
print 'I am a pig so,%s, %s' % (self.myTalk, self.myWeight)
if __name__ == '__main__':
myWorld = MyWorld()
if myStr == 'Person':
myWorld.printPerson()
elif myStr == 'Pig':
myWorld.printPig()
else:
print 'No this object'

运行结果:

Please input one object:Person
I am a person so,I can I can speak, I can move

2 属性和方法

  类是忧属性和方法组成的,属性是对数据的封装,方法是对行为的描述。在Java中,属性和方法都有访问权限控制符,在python中没有这样的封装级别控制符,在Python中,构造函数、析构函数、私有属性方法、公有属性方法都是通过名称的约定来辨别的。如果函数、方法或者属性的名称以两个下划线开始,则说明为私有类型。相反,如果没有以两个下划线开始,则表示为公有属性。在Java中还有一个受保护的类型修饰符protected 在python中不存在这种类型。
  在python中也有静态属性和实例属性。实例属性即以self作为前缀的属性,如果在类的方法中定义的变量没有使用self作为前缀声明,那么该变量就是一个普通的局部变量。

2.1 类属性

class Fly:
#define one class attribute
price = 23
def __init__(self):
self.direction = 'To Paris'
speed = 32
if __name__ == '__main__':
print Fly.price
fly = Fly()
print fly.direction
Fly.price = fly.price + 10
print 'fly,fly away'
print 'the price increase:' + str(fly.price)
myFly = Fly()
print myFly.price
输出结果:
23
To Paris
fly,fly away
the price increase:33
33

  另外方法中的局部变量speed是不能被实例及类来引用的

2.2 私有属性

  将公有的实例属性direction修改成私有__direction

class Fly:
#define one class attribute
price = 23
def __init__(self):
self.__direction = 'To Paris'
self.speed = 32
if __name__ == '__main__':
print Fly.price
fly = Fly()
print fly.__direction
Fly.price = fly.price + 10
print 'fly,fly away'
print 'the price increase:' + str(fly.price)
myFly = Fly()
print myFly.price
输出结果:
23
Traceback (most recent call last):
File "Fly.py", line 10, in <module>
print fly.__direction
AttributeError: Fly instance has no attribute '__direction'

  显然报错了,也就是私有的属性不能被实例化对象访问。Python提供了直接访问私有属性的方式
实例化对象名._类名__私有属性名

class Fly:
#define one class attribute
price = 23
def __init__(self):
self.__direction = 'To Paris'
self.speed = 32
if __name__ == '__main__':
print Fly.price
fly = Fly()
print fly._Fly__direction
Fly.price = fly.price + 10
print 'fly,fly away'
print 'the price increase:' + str(fly.price)
输出结果:
23
To Paris
fly,fly away
the price increase:33

2.3 数据属性

  数据属性不需要预先定义,当数据属性初次被使用时,即被创建并赋值。

class DataAttribute:
pass
if __name__ == '__main__':
data = DataAttribute()
data.name = 'I am not defined'
print data.name
输出结果:I am not defined

2.4 内置属性

  前面已经提到的__doc__就是内置属性。

class FatherClass:
def __init__(self):
self.built = 'I am the method __init__ \'s attribute'
class SonClass(FatherClass):
def accept(self):
self.acceptAttribute = "I am the attribute of SonClass's method accept"
if __name__ == '__main__':
f = FatherClass()
s = SonClass()
print "Inherite attribute from father class:", s.built
print "the tuple formed by base class:", SonClass.__bases__
print "the dict formed by neizhi:", s.__dict__
print s.__module__
print s.__doc__
print SonClass.__name__
输出结果:
Inherite attribute from father class: I am the method __init__ 's attribute
the tuple formed by base class: (<class __main__.FatherClass at 0x7f8d92e4ea10>,)
the dict formed by neizhi: {'built': "I am the method __init__ 's attribute"}
__main__
None
SonClass

说明:上面代码中,使用内置属性__bases__来输出其父类组成的元组。__dict__属性用例输出子类实例属性组成的字典,__module__属性用来输出当前运行的模块名称,__doc__属性用来输出doc文档,而__name__属性用例输出当前对象的类名。

2.5 类的方法

  类似属性,方法也有类方法和实例方法,定义规则相同,在Java中用static来定义,而python中没有static关键字,而是使用函数staticmethod()或者@staticmethod指令的方式来定义静态方法。

2.5.1 类方法

class Methods:
@staticmethod
def myMethod():
print 'This is a static method'
def __myMethod():
print 'This is a private method'
def getMyMethod():
print 'I willbe converted to static method'
conversion = staticmethod(getMyMethod)
conPrivate = staticmethod(__myMethod)
if __name__ == '__main__':
methods = Methods()
methods.myMethod()
Methods.myMethod()
#访问转换为静态方法后的原有方法
methods.conversion()
Methods.conversion()
methods.conPrivate()
Methods.conPrivate()
输出结果:
This is a static method
This is a static method
I willbe converted to static method
I willbe converted to static method
This is a private method
This is a private method

  上面代码中,在类Methods中分别声明了一个静态方法myMethod,一个私有方法__myMethod和一个普通方法getMyMethod,然后用函数staticmethod()将普通方法getMyMethod转换为静态方法conversion,将私有方法__myMethod转换为静态方法conPrivate

2.5.2 内置方法

  有许多类内置的方法,这些方法可能会被封装起来被别的函数调用。

下面介绍几个重要的__init__方法
1.__init__方法
  这个方法在Python中是构造函数,与Java不同的是,Java中的构造函数和类名是一样的,Python中不必如此,实际上构造函数更严谨的说法是初始化函数,所以__init__还是可以的。

class People:
def __init__(self, name):
self.name = name
def sayHi(self):
print 'Hello, My name is:', self.name
p = People('AiQi')
p.sayHi()
输出结果:Hello, My name is: AiQi

2.__del__方法
  __del__方法的主要作用是释放被占用的资源,在Python中是析构函数。
  所谓析构函数是:析构函数(destructor) 与构造函数相反,当对象脱离其作用域时(例如对象所在的函数已调用完毕),系统自动执行析构函数。析构函数往往用来做“清理善后” 的工作(例如在建立对象时用new开辟了一片内存空间,应在退出前在析构函数中用delete释放)。

class Room:
count = 0
def __init__(self, name):
self.name = name
print 'Initing, name is %s' % self.name
Room.count += 1
def __del__(self):
print '%s say byebye:' % self.name
Room.count -= 1
if Room.count == 0:
print 'I am the last one'
else:
print 'There is %d persons left' % Room.count
def sayHi(self):
print 'Hello,My name is %s ' % self.name
def howMany(self):
if Room.count == 1:
print 'I am the last one'
else:
print 'There is %d persons left' % Room.count
if __name__ == '__main__':
room = Room('AiQi')
room.sayHi()
运行结果:
Initing, name is AiQi
Hello,My name is AiQi
I am the last one
Initing, name is Ren
Hello,My name is Ren
There is 2 persons left
AiQi say byebye:
There is 1 persons left
Ren say byebye:
Exception AttributeError: "'NoneType' object has no attribute 'count'" in <bound method Room.__del__ of <__main__.Room instance at 0x7fc513263200>> ignored
AiQi say byebye:
Exception AttributeError: "'NoneType' object has no attribute 'count'" in <bound method Room.__del__ of <__main__.Room instance at 0x7fc5132631b8>> ignored

3. __new__方法
  __new__方法在创建对象时被调用,返回当前对象的一个实例。看起来和__init__方法没有什么区别。实际上,__init__方法在创建完对象之后才被调用,对当前对象的实例进行初始化,而__new__方法则是在创建对象时被调用的。

class MyNew:
def __init__(self):
print ("__init__")
def __new__(self):
print ("__new__")
if __name__ == '__main__':
myNew = MyNew()

4.__setitem__方法
  _setitem__专用方法的含义是进行赋值时,创建字典对象

class MySetitem:
def __setitem__(self, key, value):
print 'key=%s, value=%s' % (key, value)
mySetitem = MySetitem()
mySetitem['a'] = 'Alice'
mySetitem['b'] = 'Quinta'
mySetitem['c'] = 'Amy'
执行结果:
key=a, value=Alice
key=b, value=Quinta
key=c, value=Amy

5.__getitem__方法
  __getitem__用于返回字典的值。这两个方法和java的setter和getter方法是类似的。
6.__delitem__方法
  __delitem__方法是在调用"del 实例对象[key]"语句时调用。

class MyDelitem:
def __delitem__(self, key):
print 'delete item:%s' % key
myDelitem = MyDelitem()
del myDelitem['dcy']
输出结果:delete item:dcy

7.__cmp__方法
  这个内置方法被封装用于给==比较累实例时候进行调用。

class MyCmp:
def __cmp__(self, other):
print '__cmp__ is called'
return 0
if __name__ == '__main__':
mycmp1 = MyCmp()
mycmp2 = MyCmp()
print mycmp1 == mycmp2
输出:
__cmp__ is called
True

2.6 方法的动态特性

  python语言是一种完全面向对象的动态语言,主要体现在:可以动态添加类的方法,将某个已经定义的方法添加到类中。如果类本身已经有了同名的方法,那么将会替换掉类中的方法体。

class_name.method_name = exist_name
class Yesterday:
pass
def today(self):
print 'Today is a nice day'
if __name__ == '__main__':
Yesterday.yesterday = today
yes = Yesterday()
yes.yesterday()
输出结果:Today is a nice day

3 继承

  继承是子类继承父类的属性和方法,python中没有extends关键字,用括号

class class_name(father_class_name)
一个例子:

3.1 super调用父类方法

  python支持用super关键字来调用父类的方法

'''
Created on 2013-8-6 @author: Landau
'''
class Father:
def __init__(self):
print 'I am the __init__ of father'
print 'Use later'
class Son(Father):
def __init__(self):
print 'I am the __init__ of son'
Father.__init__(self)
b = Son()

  我们也可以使用super关键字来实现上面的功能

3.2 多继承

  python允许多重继承。语法格式如下:
class class_name(fatherclass1_name,fatherclass2_name)
  多继承是这样的,比如一个人,眼睛像妈妈,肤色像爸爸。这就是多继承。

3.3 类的命名空间

  类和类成员的名称是丰富的,为了描述一个具体的对象,需要对类和类成员进行设计,在设计类和类成员过程中,难免会出现类的名称或类成员中的方法相同的情况,这样就会造成代码混乱,从而使代码的可读性降低。使用命名空间可以解决此问题。
  在java中,我们只要把类放到各自的包中,就可以避免类的名称或者类成员重复了,我们可以认为package是java的命名空间。
  在python中,定义类时,所有位于class语句中的代码都在特殊的命名空间中执行,该命名空间被称为类命名空间(class namespace)。这个类命名空间不仅可以被类中所有成员访问,还可以被类的实例方法访问。

3.4 继承检查

  python提供了内建的issubclass函数用于继承检查

  issubclass函数的第一个参数是子类,第二个参数是可能的父类,类似还有一个函数isinstance,用于检查一个对象是不是一个类的实例,第一个参数是对象,第二个参数是可能的类。

3.5 新式类

  新式类是指从python2.2开始引入的类。通常情况下,从object或者其他内置类型衍生的类,都被称为新式类。
__slots__类属性
  这个类属性用于替代__dict__属性
  __slots__是一个类变量,可以由一系列对象组成,使用所有合法标识构成的实例属性的集合来表示。它也可以是一个列表、元组或可迭代对象,总之,任何试图创建一个其名不在__slots__中的实例属性的操作都将引发AttributeError异常,而且实例属性必须初始化。
  一般情况下,__slots__类属性在class语句顶层设置。下面通过一个例子说明:

class MyLimiter(object):
__slots__ = 'my_name', 'my_age', 'my_hobby'
if __name__ == '__main__':
x = MyLimiter()
x.my_name = 'AiQi'
print x.my_name 

Python程序设计6——面向对象的更多相关文章

  1. Python进阶(十三)----面向对象

    Python进阶(十三)----面向对象 一丶面向过程编程vs函数式编程vs面向对象编程 面向过程: ​ 简而言之,step by step 一步一步完成功能,就是分析出解决问题所需要的步骤,然后用函 ...

  2. python基础_面向对象进阶

    @property装饰器 之前我们讨论过Python中属性和方法访问权限的问题,虽然我们不建议将属性设置为私有的,但是如果直接将属性暴露给外界也是有问题的,比如我们没有办法检查赋给属性的值是否有效.我 ...

  3. python基础_面向对象

    面向对象定义 把一组数据结构和处理它们的方法组成对象(object),把相同行为的对象归纳为类(class),通过类的封装(encapsulation)隐藏内部细节,通过继承(inheritance) ...

  4. (转)Python成长之路【第九篇】:Python基础之面向对象

    一.三大编程范式 正本清源一:有人说,函数式编程就是用函数编程-->错误1 编程范式即编程的方法论,标识一种编程风格 大家学习了基本的Python语法后,大家就可以写Python代码了,然后每个 ...

  5. Python学习之面向对象基础

    python的面向对象和以前学的c++,Java都是一般,大同小异,面向对象基础先谈谈类的构造,编写,属性和方法的可见性等等 1.定义类,创建和使用对象 #定义类 class Student(obje ...

  6. 20184302 2019-2020-2 《Python程序设计》实验一报告

    20184302 2019-2020-2 <Python程序设计>实验一报告 课程:<Python程序设计> 班级: 1843 姓名: 李新锐 学号:20184302 实验教师 ...

  7. 20184302 2019-2020-2 《Python程序设计》实验四报告

    20184302 2019-2020-2 <Python程序设计>实验四报告 课程:<Python程序设计> 班级: 1843 姓名: 李新锐 学号:184302 实验教师:王 ...

  8. Python程序设计(第3版)PDF高清完整版免费下载|百度网盘

    百度网盘:Python程序设计(第3版)PDF高清完整版免费下载 提取码:48u4 内容简介 本书是面向大学计算机科学专业第一门程的教材.本书以Python语言为工具,采用相当传统的方法,强调解决问题 ...

  9. 实验一 Python程序设计入门

    学号20184307 2019-2020-2 <Python程序设计>实验1报告 课程:<Python程序设计> 班级: 1843 姓名: 章森洋 学号:20184307 实验 ...

随机推荐

  1. 搭建了一个Apache+Php+MySQL的服务器。要如何通过Apache发布网站使得其他的电脑可以通过局域网访问?

         源址: 1.网站的代码放在文件夹“www”下: 2.配置apache允许他人访问网站:在wamp/apache/apache版本/conf的httpd.conf文件修改代码如下: Optio ...

  2. POJ - 2079:Triangle (旋转卡壳,求最大三角形)

    Given n distinct points on a plane, your task is to find the triangle that have the maximum area, wh ...

  3. Java 参数的和

    public class CommandParamter { public static void main(String[] args) { // TODO Auto-generated metho ...

  4. eclipse Git & maven 安装

    JDK安装请自行百度. Maven是免安装的.压缩包解压完成后.如解压后放在D:\Server\maven下.接下来配置maven的环境变量: 系统变量:MAVEN_HOME = D:\Server\ ...

  5. To Java程序员:切勿用普通for循环遍历LinkedList(转)

    ArrayList与LinkedList的普通for循环遍历 对于大部分Java程序员朋友们来说,可能平时使用得最多的List就是ArrayList,对于ArrayList的遍历,一般用如下写法: p ...

  6. Kerberos的hive链接问题

    javax.security.auth.login.LoginException: Checksum failed 之前碰到过类似的问题,都是因为服务器端的keytab问题:多半是因为重新生成了key ...

  7. Spring Boot自定义配置与加载

    Spring Boot自定义配置与加载 application.properties主要用来配置数据库连接.日志相关配置等.除了这些配置内容之外,还可以自定义一些配置项,如: my.config.ms ...

  8. MySQL 5.6 date 与 string 的转换和比较

    我们有张表,表中有一个字段 dpt_date ,SQL 类型为 date,表示离开日期. 我们将 dpt_date 与字符串 ‘2016-03-09’ 进行比较,发现效率低于 dpt_date 转换为 ...

  9. Oracle data guard学习

    Oracle data guard学习:三思笔记 Data guard 1data guard结构: data guard是一个集合,由一个primary数据库(生产数据库)和一个或多个standby ...

  10. 远程摄像头软件mjpg-streamer使用指南

    转 自:http://bbs.hdchina.org/viewthread.php?tid=94749 mjpg-streamer 可以通过文件或者是HTTP方式访问linux UVC兼容摄像头.可以 ...