类与对象
实例变量与类变量
实例方法与类方法
#类的定义
class person(object):
# 构造方法
def __init__(self,name,age,addr,gender):
self.name = name
self.age = age
self.__addr = addr
self.gender = gender
#类属性
name="mike"
__addr="山东" #私有类属性
#实例属性是不需要定义在类里面的
#类方法,可以通过类名和实例对象名访问
@classmethod
def setAddr(cls,addr):
cls.__addr = addr
#实例方法,只能被实例对象访问
def getName(self):
return self.name
@staticmethod
def pringLog():
print(person.name,person.__addr)
def main():
'''
1. python不支持函数重载,因此构造函数无法重载
2. 如果类内由实例变量的引用,那么实例变量必需在构造函数内部声明并赋值
3. 静态方法要访问类中变量,用类名访问
'''
p1 = person("jhon",23,"广东","男")
print(p1.name,p1.age,p1.gender)
p1.pringLog() #实例对象访问静态方法
person.pringLog() #类名访问静态方法
if __name__ == '__main__':
main()
封装
class employee(object):
def __init__(self,name,age):
self.__name=name
self.__age=age
#实现__name和__age的setter和getter方法
def set_name(self,name):
self.__name=name
def get_name(self):
return self.__name
def set_age(self,age):
self.__age=age
def get_age(self):
return self.__age
#要想使用上述方法 需要:em.set_name("mike")
#如果想要和使用变量一样使用 em.name="mike"
#getter
@property
def name(self):
return self.__name
@property
def age(self):
return self.__age
#setter方法
@name.setter #这里的name必需是被property装饰的方法名
def name(self,name):
self.__name=name
@age.setter #这里的age必需是被property装饰的方法名
#否则的话,会出现TypeError: descriptor 'setter' requires a 'property' object but received a 'function'错误
def age(self,age):
self.__age=age
if __name__ == '__main__':
em = employee("mike",34)
print(em.name,em.age)
em.name="adasdf"
em.age=45
print(em.name,em.age)
继承
继承一个类
class person(object):
def __init__(self,name,age):
self.__name=name
self.__age=age
#获取类的信息
def getInfo(self):
print(self.__name,self.__age)
#getter方法
@property
def name(self):
return self.__name
@name.setter
def name(self,name):
self.__name=name
@property
def age(self):
return self.__age
@age.setter
def age(self,age):
self.__age=age
#继承
class student(person):
def __init__(self,name,age,score):
#要调用父类的构造器,否则将没有name和age属性
super(student,self).__init__(name,age)
self.__score = score
def getInfo(self):
print(self.name,self.age,self.__score)
@property
def score(self):
return self.__score
@score.setter
def score(self,score):
self.__score = score
def main():
stu = student("mike",23,78)
stu.getInfo()
stu.name="jhon"
stu.getInfo()
if __name__ == '__main__':
main()
多继承
class father(object):
def __init__(self,firstName,secondName):
self.__firstName=firstName
self.__secondName=secondName
class mother(object):
def __init__(self,firstName,seconName,gender):
self.__firstName=firstName
self.__secondName=seconName
self.__gender=gender
@property
def firstName(self):
return self.__firstName
@firstName.setter
def firstName(self,firstName):
self.__firstName=firstName
@property
def secondName(self):
return self.__secondName
@secondName.setter
def secondName(self,secondName):
self.__secondName = secondName
@property
def gender(self):
return self.__gender
@gender.setter
def gender(self,gender):
self.__gender = gender
class son(father,mother):
def __init__(self,firstName,secondName,gender,age):
mother.__init__(self,firstName,secondName,gender)
self.__age=age
def getInfo(self):
print(self.firstName,self.secondName,self.gender,self.__age)
'''
在单继承中:如果子类没有__init__函数,那么会自动调用父类的__init__函数
在单继承中,如果子类有__init__函数,那么需要显式的调用父类的__init__函数
在多继承中,如果子类没有__init__函数,那么会自动调用第一个父类的__init__函数
如果第一个父类中没有__init__函数,那么会依次调用第二个,第三个父类,一直到找到__init__函数
在多继承中,如果子类有__init__函数,那么需要显式指出调用哪个父类的__init__函数
'''
def main():
s = son("王","li","男",34)
s.getInfo()
if __name__ == '__main__':
main()
多态
多态的定义
- python有序列类型,但是序列类型有很多,列表,元组,字典等
- 文件有很多,但是类型有文本,可执行文件等
- 在我们打开文件的时候,根据类型,选择不同的打开方式
python中的多态也是这个原理。
class cat(object):
def log(self):
print("cat")
class dog(object):
def log(self):
print("dog")
class computer(object):
def log(self):
print("computer")
#下面实现一个函数,调用log方法
def printLog(x):
x.log()
#在上面的函数中,传入什么类型,就会打印哪个类型的log
#这就是多态
def main():
c = cat()
d = dog()
com = computer()
printLog(c)
printLog(com)
printLog(d)
if __name__ == '__main__':
main()
鸭子类型(接口)
python是一种动态类型语言,因此,python有一种鸭子类型。
即,在python中只要包含某个方法,就认为这就是哪个东西。
比如猫,狗,和电脑,很明显不是一类。但是都包含log()方法
那么,python就认为cat,dog,computer 都是x类型。