1. 方法
python中,方法的参数没有类型,参数数量可变,python中没有方法的重载。
如果定义了多个重名的方法,只有最后一个有效。
1.1 方法的特性
方法的动态性:python是动态语言,可以动态地为类增添新方法或动态地修改类的已有方法。
class Person:
def work(self):
print('work hard')
def play_game(a):
print('{0}在玩游戏'.format(a))
Person.play=play_game#添加新方法
p=Person()
p.work()
p.play()
1.2 私有属性
python对于类的成员没有严格的访问控制限制:
1.两个下划线开头的属性是私有的,其他为公共的
2.类内部可以访问私有属性/方法
3.类外部不能直接访问私有属性/方法
4.类外部可以通过 ‘_类名__私有属性/方法名’访问私有属性/方法
class Employee:
def __init__(self,name,age):
self.name=name
self.__age=age#私有属性
def __work(self):#私有方法
print('work hard')
e=Employee('JOJO',18)
print(e.name)
print(e._Employee__age)#访问私有属性
e._Employee__work()#调用私有方法
1.3 property装饰器
@property装饰器可以将一个方法的调用方式变为属性调用
lass Employee:
def __init__(self,name,salary):
self.__name=name
self.__salary=salary
@property
def salary(self):#变为属性调用
return self.__salary
@salary.setter
def salary(self,salary):
if 1000
self.__salary=salary
else:
print('wrong')
emp1=Employee('jojo',30000)
print(emp1.salary)
emp1.salary=20000#修改属性
print(emp1.salary)
1.4 方法的重写
子类可以重新定义父类中的方法,这样就会覆盖父类的方法,也称为重写。
class Person:
def __init__(self,name,age):
self.name=name
self.age=age
def say_age(self):
print('age')
class Student(Person):
def __init__(self,name,age,score):
Person.__init__(self,name,age)
self.score=score
def say_age(self):#重写该方法
print('reage')
s=Student('jojo',18,100)
s.say_age()
1.5 特殊方法和运算符重载
python中的运算符实际上是通过调用对象的特殊方法实现的,每个运算符都对应了相应的方法,重写该方法可以重载运算符。
class Shuzi:
def __init__(self,shu):
self.shu=shu
def __add__(self, other):#重新定义运算符+的对应方法
if isinstance(other,Shuzi):
return "{0}--{1}".format(self.shu,other.shu)
else:
return "wrong"
p1=Shuzi(10)
p2=Shuzi(20)
x=p1+p2
print(x)
1.6 特殊属性
python对象中包含了很多双下划线开始和结束的属性,是特殊属性,有特殊用法,常见的特殊属性有:
obj.__dict __ :对象的属性字典
obj.__class __:对象所属的类
class.__bases __类的父类元组(多继承)
class.__base __:类的父类
class.__mro __:类层次结构
class.__subclasses __():子类列表
2. 面向对象的三大特性
python是面向对象的语言,也支持面向对象的三大特性:继承,封装,多态。
封装:隐藏对象的属性和实现细节,只对外提供必要的方法。通过私有属性,私有方法的方式,实现封装
2.1 继承
继承可以让子类具有父类的特性,提高了代码的重用性。
语法格式:支持多重继承,一个子类可以继承多个父类。
class 子类类名(父类1[,父类2,…])
类体
如果类定义中没有指定父类,则默认父类是object类。object是所有类的父类,因此所有的类都有object类的属性和方法。
定义子类时,必须在其构造函数中调用父类的构造函数。
父类名.__ init__(self,参数列表)
子类可以继承私有属性,但不能直接使用。
class Person:
def __init__(self,name,age):
self.name=name
self.__age=age#私有属性
def say_age(self):
print('age')
class Student(Person):
def __init__(self,name,age,score):
Person.__init__(self,name,age)#必须显式地调用父类的初始化方法,不然解释器不会调用
self.score=score
s= Student('JOJO',18,100)
s.say_age()
print(s.name)
print(s._Person__age)#私有属性特殊调用
多重继承:支持多重继承,但是这样会被“类的整体层次”搞的很复杂,尽量避免使用。
class A:
def aa(self):
print('aa')
class B:
def bb(self):
print('bb')
class C(A,B):#AB同时为C的父类
def cc(self):
print('cc')
c=C()
c.aa()
c.bb()
c.cc()
mro(): method resolution order 方法解析顺序,可获得类的层次结构
super():代表父类的定义,不是父类对象。
class A:
def say(self):
print('A',self)
class B(A):
def say(self):
super().say()#代表父类的定义
print('B',self)
B().say()
组合:has-a关系,也能实现一个类用于另一个类的方法和属性
class Phone:
def __init__(self,cpu,screen):
self.cpu=cpu
self.screen=screen
class CPU:
def caculate(self):
print("cpu对象:",self)
class Scrren:
def show(self):
print('scrren对象',self)
m=Phone(CPU(),Scrren())#组合关系
m.cpu.caculate()#方法调用
m.screen.show()
2.2 多态
多态:同一个方法调用由于对象不同可能会产生不同的行为
1.多态是方法的多态,属性没有多态
2.多态的存在有两个必要条件:继承,方法重写
lass Man:
def eat(self):
print('eat')
class Chinese(Man):
def eat(self):
print('eat with chopsticks')
class English(Man):
def eat(self):
print('eat with fork')
def manEat(m):
if isinstance(m,Man):
m.eat()
else:
print('none')
manEat(Chinese())
manEat(English())#同一个方法产生不同行为