Python也是一种面向对象的编程语言。 现在,让我们进入Python的面向对象编程世界吧。 但是,在正式进行python的面向对象编程时,首先需要了解python类的知识。
类是实现Python支持继承的新类型对象的部件,也是Python面向对象编程(OOP )的主要工具。
使用名为class语句的新语句在PYthon中创建类。
1、面向对象有三个特点:
套装软体
继承人
多态性
2、什么是班?
类(Class ) :描述具有相同属性和方法的对象的集合。 定义集合中每个对象共有的属性和方法。 对象是类的实例。 概述一下,类是一个包含大量使用内置对象类型进行处理的函数的包。 类旨在创建和管理对象,并支持继承。 这是代码定制和重用的机制。
从具体的编程角度来看,类是Python的程序组成部分,而类是封装逻辑和数据的另一种方法,正如我们在前面提到的函数和模块一样。 类有三个重要的独特点,它们在创建新对象时非常有用。
多个实例
班级基本上是创造对象的工厂。 每次调用类时,都会生成一个独立命名空间的新对象。 类生成的每个对象都可以读取类的属性,并获取每个对象各自的命名空间存储数据。
通过继承定制
类还支持OOP继承。 可以通过在类外部重新定义属性或添加没有属性的方法来扩展类。 更一般地,类可以创建命名空间的层次结构。 此层次结构定义类在该结构中创建的对象使用的变量名称。 从类生成的所有实例都继承该类的所有属性和方法。
运算符重载
通过提供特定的协议方法,类可以定义对某些内置运算作出响应的对象。 例如,从类创建的对象可以进行切片、级联和索引等运算。 Python提供了几个可以在类中使用的挂接,可以中断和实现任何嵌入式运算。
3、编班
使用class语句创建新类。 class后面以类的名称、括号中的基类(可以有多个基类)和冒号结尾。
classclassname(baseclass,) :
' optionalclassdocumentationstring ' #类的文档字符串
class_suite #类
class_suite由类成员、方法和数据属性组成。
类的帮助信息可以在ClassName.__doc__中找到。
类定义实例:
#! /usr/俊逸的发卡/python
#编码=utf-8
类封装(对象) :
#所有员工基类
empCount=0
def __init__(self,name,salary ) :
#类的构造函数
self.name=name
self.salary=salary
Employee.empCount =1
defdisplaycount (自) :
#类方法
print 'total employee ',Employee.empCount
efdisplayemployee(self ) :
print 'name : ',self.name,',salary : ',self.salary
说明:
empCount变量是一个类变量,也称为静态变量,其值在类的所有实例之间共享。 可以在内部类或外部类中使用Employee.empCount访问。
第一个init ) )方法用作类的构造函数或初始化方法,每次创建类的实例时都会调用该方法。 如果未显示此方法的定义,则缺省情况下将给出空方法。
类方法中参数的self表示实例本身,相当于java的this指针。 此外,类中的所有方法都需要self,并且必须写在第一个参数位置。
所有类都继承基类object。
4、创建实例对象
要创建类的实例,可以使用类的名称,并在__init__方法中接受参数。
为类创建特定对象。 每次从类生成实例时,Python都会自动调用名为__init__的方法,也称为类的生成方法,用于初始化数据。 新实例照常传递给__init__的self参数。 此方法也由类继承。
如果要在上面的类中创建实例:
EMP1=employee('Joy ',10000 ) )。
EMP2=employee('Sr ',10000 ) ) ) ) ) ) ) )。
如果定义的类没有要初始化的参数,则在创建实例时不需要传递参数。
5、类变量
Python的类变量也称为类的静态成员变量,类变量在整个实例化对象中是公共的。 类变量在类中定义,并在函数之外。 类变量通常不用作实例变量,其值在此类的所有实例之间共享。
类变量紧接在类名之后定义,相当于java和c
的static变量实例变量在__init__里定义,相当于java和c++的普通变量
class Parent(object): # define parent class
parentAttr = 100
def __init__(self):
print "Calling parent constructor"
parentAttr变量就是一个类变量。
6、实例变量
实例变量在__init__里定义,相当于java和c++的普通变量,只作用于当前类的实例。实例变量前面需要加上self关键字。如:
class Person(object):
id = 12 #类静态成员在这儿定义,注意缩进
def __init__(self,name):
self.name = name #类的实例变量
self.__inName = 'ads' #类的实例变量
而在类的实例方法中定义的变量,叫局部变量。
7、类方法和静态方法
类方法和静态方法很想,在调用时,都不需要产生类的实例去调,而是可以直接使用类的名字去调。
但是它们也是有区别的:类方法传参时需要把类本身的实例(cls,指向该类本身)传进入,而静态方法则不需要传任何实例,只有普通参数。
class Person(object):
id = 12 #类静态成员在这儿定义,注意缩进
def __init__(self,name):
self.name = name
self.__inName = 'ads'
@classmethod #类方法定义,用注解方式说明
def up( cls,a ): #这儿是cls,不是self
print cls,cls.__name__
return a+1
@staticmethod #类静态方法定义,用注解方式说明
def down( b): #静态方法不需要self,cls变量
id = 13
return b-1
调用:
print Person.up(20)
print Person.down(15)
8、方法重载
有时候,我们可能需要在同一个类中定义几个功能类似但参数不同的方法。
方法的重载(overloading)是允许在一个类的定义中,多个方法使用相同的方法名。
如果你学过C++、JAVA或者是其他面向对象编程语言,你会发现Python中的重载与其他面向对象编程语言在使用上是有区别,其实可以这么说Python在形式上是不支持重载。下面先以JAVA为例,讲解一下方法重载。
重载是指在同一类中一个方法名被用来定义多个方法。
方法的重载是面向对象编程语言多态性的一种形式,它实现了java的编译时多态,即由编译器在编译时刻确定具体调用哪个被重载的方法。函数重载大大提高了代码重用率和程序员开发效率。
重载方法的名称是不同的,但在方法的声明中一定要有彼此不相同的成份,以使编译器能够区分这些方法。因此JAVA中规定重载的方法必须遵循下列原则:
方法的参数表必须不同,包括参数的类型或个数,以此区分不同方法体;
方法的返回类型、修饰符可以相同,也可以不同。
public void println()
public void println(char x)
public void println(char x, int x)
(1).Python方法重载
而对于Python来说,虽然它形式上不支持函数重载。但Python也是一门面向对象语言,自然也不会丢弃函数重载这特性。Python中实现函数重载的方法非常特别。首先,Python本身是动态语言,方法的参数是没有类型的,当调用传值的时候才能确定参数的类型,所以想通过参数类型的不同来实现函数重载是不可行了。那到底怎么实现Python的重载呢?
参数类型行不通了,那我们考虑通过参数数量来试试。Python中针对函数参数个数有一个很好使的功能就是缺省参数。
利用重载机制可以进行如下定义:
def println(str1, time = 1) :
print str1 * time
通过设置缺省参数,就可以实现Python中的函数重载。
(2).Python运算符重载(重写)
在Python中,运算符重载的方式很简单,每个类都会有默认内置一些运算符方法,只要重写这个方法,就可以实现针对该运算符的重载。例如下面是重载加法操作:
class Vector(object) :
def __init__(self, a, b) :
self.a = a
self.b = b
def __str__(self):
return 'Vector (%d, %d)' % (self.a, self.b)
def __add__(self,other) :
return Vector(self.a + other.a, self.b + other.b)
x = Vector(3,7)
y = Vector(1, -10)
print x + y
执行结果:
Vector (4, -3)
上面的实例重写了类的加法操作,你也可以重写其他的方法。
9、方法重写
在类层次结构中,当子类的成员变量与父类的成员变量同名时,子类的成员变量会隐藏父类的成员变量;当子类的方法与父类具有相同的名字、参数列表、返回值类型时,子类的方法重写(overriding)了父类的方法,在父类定义的方法就被隐藏。“隐藏”的含义是,通过子类对象调用子类中与父类同名的变量和方法时,操作的是这些变量和方法是在子类中的定义。子类通过成员变量的隐藏和方法的重写可以把父类的状态和行为改成为自身的状态和行为。
重写是指子类重写父类的成员方法。子类可以改成父类方法所实现的功能,但子类中重写的方法必须与父类中对应的方法具有相同的返回值、方法名和参数列表。也就是说要实现重写,就必须存在继承。
方法重写必须遵守的原则:
子类中重写方法的返回值类型必须与父类中被重写方法的返回值类型相同。
子类中重写方法的访问权限不能缩小。
子类中重写方法不能抛出新的异常。
方法重写是现实对象运行时多态的基础。
形状类:
class Shape(object):
def __init__(self,x):
self.x = x
self.rx = 10
def area(self,x):
pass
圆类(继承形状类):
class Circle(Shape):
def __init__(self,x):
#super(Circle,self).__init__(x)
#Shape.__init__(self,x)
pass
def area(self,x):
print 'in circle'
return 3.14 * x ** 2
圆类继承了形状类,并且重写了父类的构造方法和求面积的方法。并且在子类重写父类构造方法时,以父类方法作为一个基础,子类中只是对其做一个扩展,这个时候就会要调用父类的构造方法时,有三种方法:
方法一:(比较灵活)
super(Circle,self).__init__(x) 方法二: Shape.__init__(self,x) 方法三: 子类不定义自己的构造方法时,默认就会调用父类的构造方法。
注意:
super只能用于构造方法中。
如果你的父类不能满足你的需求,你就可以在子类中重写父类的方法,常见重写的父类的方法有: