类的定义
这一节我们看一下python的类
如果有其它高级语言基的话,很简单理解类,对象等概念,我们直接进入主题。
python中类的定义:
class ClassName:
'类的帮助信息' #类文档字符串
class_suite #类体
我们看到,类定义的类名后面也是需要有冒号的。
趁热打铁,我们先小试大刀
class Person:
career=None
name="Tom"
def __init__(self, name, age,career):
self.name = name
self.age = age
Person.career=career
def toString(self):
print("name = " + self.name + ", age = " + str(self.age)+",carrer="+Person.career+",class name="+Person.name)
print(self.__class__)
person = Person("liuguoyan",12,"teacher")
person.toString()
#打印结果:
name = liuguoyan, age = 12,carrer=teacher,class name=Tom
<class '__main__.Person'>
通过上面的简单例子我们可以学到以下的几个知识点:
1:python有类变量,上面的career就是一个类变量,各实例共享
2:所有的方法,在定义时都需要加一个self的参数,但是在调用时不需要传。
3:构造方法以init来定义,和php中的__construct()方法极其相似
4:成员变量,不需要定义,直接使用就好,和成员方法同级的都是实例变量
5:可以使用self.class来打印出来类名,这是一些预置的类内部属性,方便使用。
构造方法
构造方法在上面的例子中我们已经看到了,python的构造方法是init的一个内置函数。
注意点:
构造方法的第一个参数是self,定义方式如下
def __init__(self[,param1,param2...]):
成员变量(属性)
python中的成员属性很有意思,不需要提前定义。这也是需要我们注意的一个地方。
这个和其它高级语言的使用上,区别还是很大的。如下例:
class Car:
def __init__(self):
pass #这里注意空语句的使用
def run(self):
print(self.brand+"速度是"+str(self.speed))
car = Car()
car.brand="Audi"
car.speed=120
car.run()
#打印结果:Audi速度是120
属性的一些操作方法:
getattr(obj, name[, default]) : 访问对象的属性。
hasattr(obj,name) : 检查是否存在一个属性。
setattr(obj,name,value) : 设置一个属性。如果属性不存在,会创建一个新属性。
delattr(obj, name) : 删除属性。
类变量
类变量我们也知道,它是实例间共享的。使用方法是用类名调用。
还是拿上面的例子我们来做个简单的说明:
class Car:
host=None
def __init__(self,host):
Car.host=host
def run(self):
print(self.brand+" 来自 "+Car.area +" 是("+Car.host+")旗下子公司")
car = Car("大众")
Car.area="德国"
car.brand="Audi"
car.run()
说明:
·类变量可以声明在类内部,注意要初始化,如None
·类变量也可以直接在调用处使用,直接ClassName.类属性进行赋值
内置类属性
我们上面说到了成员和类变量,我们看一下类有哪些内置属性。
我们取来自别的教程的一个例子来说明:
class Employee:
'所有员工的基类'
empCount = 0
def __init__(self, name, salary):
self.name = name
self.salary = salary
Employee.empCount += 1
def displayCount(self):
print "Total Employee %d" % Employee.empCount
def displayEmployee(self):
print "Name : ", self.name, ", Salary: ", self.salary
print "Employee.__doc__:", Employee.__doc__
print "Employee.__name__:", Employee.__name__
print "Employee.__module__:", Employee.__module__
print "Employee.__bases__:", Employee.__bases__
print "Employee.__dict__:", Employee.__dict__
#打印结果
Employee.__doc__: 所有员工的基类
Employee.__name__: Employee
Employee.__module__: __main__
Employee.__bases__: ()
Employee.__dict__: {'__module__': '__main__', 'displayCount': <function displayCount at 0x10a939c80>, 'empCount': 0, 'displayEmployee': <function displayEmployee at 0x10a93caa0>, '__doc__': '\xe6\x89\x80\xe6\x9c\x89\xe5\x91\x98\xe5\xb7\xa5\xe7\x9a\x84\xe5\x9f\xba\xe7\xb1\xbb', '__init__': <function __init__ at 0x10a939578>}
我们观察到了什么?
很明了,内置属性都是类属性。dict包含了本类中的类变量,如上面的empCount,它是一个类属性,但并没包含实例属性。
成员权限控制
python中不像别的高级语言,如php,java等,它们都有自己的访问控制的关键字。在python中,使用下划线“_”来实现这个目的。
单下划线、双下划线、头尾双下划线说明:
foo: 定义的是特殊方法,一般是系统定义名字 ,类似 init() 之类的。
_foo: 以单下划线开头的表示的是 protected 类型的变量,即保护类型只能允许其本身与子类进行访问,不能用于 from module import *
__foo: 双下划线的表示的是私有类型(private)的变量, 只能是允许这个类本身进行访问了。
私有成员与公有成员
公有成员,不加下划线
私有成员,双下划线“__”
如下:
class Car:
def __init__(self):
self.__core = 4
self.brand = "Audi"
car = Car()
print(car.brand)#打印出"Audi"
又#报错 AttributeError: 'Car' object has no attribute '_core'
我们看到 print(car.brand)是可以正常打印的,因为它是公有属性
print(car.brand)报错,说访问不到这个属性。因为它是私有的。
那么私有变量我们如何访问呢?正常来讲,好的程序,是无需我们访问私有成员的,但是我们一定要访问,可以通过"实例._ClassName+私有成员"访问,举一下栗子:
class Car:
def __init__(self):
self.__core = 4
self.brand = "Audi"
car = Car()
print(car.brand)
print(car._Car__core)
#打印结果
Audi
4
公有方法,私有方法,静态方法
公有方法我们就不多说了
私有方法需要在方法前加双下划线
静态方法,需要加注解:@staticmethod(静态方法只能访问静态属性,这个学过高级语言的人,都知道)
class Car:
Host = None
def __init__(self):
self.brand = "Audi"
Car.Host = "大众"
def __getHost(self):
return Car.Host
def printInfo(self):
print(self.brand + "属" + self.__getHost() + "旗下产品")
@staticmethod
def getHost(): #静态变量不需要传self
return Car.Host
car = Car()
car.printInfo()
print(Car.getHost())
print(car._Car__getHost())
#打印结果:
Audi属大众旗下产品
大众
大众
通过上面的例子我们知道了以下几点:
·私有成员常规下不可以访问,但是强行可以通过(实例._ClassName+私有方法)访问
·静态方法不需要传self参数,需要用 @staticmethod来做注解
类的继承
类继承的定义
python是多继承,可以继承多个类,这一点和java以及php不同。
class SubClassName (ParentClass1[, ParentClass2, ...]):
单继承:
class Car:
def __init__(self,brand):
self.brand = brand
class Audi(Car):
def __init__(self,brand):
super().__init__(brand)
def printInfo(self):
print("我的车是一个"+self.brand)
audi = Audi("audi")
audi.printInfo()
对于单继承,我们如果要重写构造,就要调用一下父类的构造。
super().init(param)
多继承:
如下例:
class Car:
def __init__(self,brand):
self.brand = brand
class Vehicle:
def __init__(self,wheel):
self.wheel = wheel
class Audi(Car,Vehicle):
def __init__(self,brand,wheel):
Car.__init__(self,brand)
Vehicle.__init__(self,wheel)
def printInfo(self):
print("我的车是一个"+self.brand+" ,它的轮子是"+str(self.wheel))
audi = Audi("audi",4)
audi.printInfo()
#打印结果
我的车是一个audi ,它的轮子是4
我们看到,我们使用多继承,使用到了Car和Vehicle中的内容。
但是我们注意到,因为是多继承,使用super()方法不能确认我们调用哪个父类的构造。于是我们就需要使用ClassName.init(self,params)来指明调用哪个父类的构造。
方法重写
对于方法重写,我们这里暂时不做过多介绍,和其它语言一样。重写了方法之后,在调用的时候,就不会再使用父类的方法,而是直接使用子类重写后的实现。
网友评论