面向对象下
1.类的访问权限–封装(encapsulation)
1.1 封装的引入
由于我们可以直接通过对象.属性的方式来修改属性的值,那么这样就非常的不安全。python中提供了一个私有属性与方法,这个观念的主要精神是类外无法直接更改类内的私有属性,类外也无法直接调用私有方法,这个观念称之为封装。
class Car: #定义一个Car类
def __init__(self,name,color): #初始化属性
self.name = name
self.color = color
def run(self): #定义一个方法
print('一辆%s的%s在马路上飞奔'%(self.color,self.name))
c=Car('保时捷','红色') #实例化类
c.run() #调用方法
c.name='五菱宏光' #修改属性
c.color='白色'
c.run()
#一辆红色的保时捷在马路上飞奔
#一辆白色的五菱宏光在马路上飞奔
1.2 私有属性
为了确保类内的属性安全,有必要限制外部无法直接获取类内的属性值,python对于类内的属性增加了私有属性的观念,应用方式是定义时在属性名称前增加__(两个底线),定义为私有属性后,类外的程序就无法引用了。在类内部的方法中使用是self.__属性名.
class Car: #定义一个Car类
def __init__(self,name,color): #初始化属性
self.__name = name
self.__color = color
def run(self): #定义一个方法
print('一辆%s的%s在马路上飞奔'%(self.__color,self.__name))
c=Car('保时捷','红色') #实例化类
c.run() #调用方法
c.__name='五菱宏光' #修改属性
c.__color='白色'
c.run()
c.name='五菱宏光' #修改属性
c.color='白色'
c.run()
#一辆红色的保时捷在马路上飞奔
#一辆红色的保时捷在马路上飞奔
#一辆红色的保时捷在马路上飞奔
1.3 私有方法
既然类有私有属性,那么也有私有方法,它的观念与私有属性类似,类外的程序无法调用。定义方式和私有属性相同,只要在方法前加__(两个底线)符号即可。
class Car: #定义一个Car类
def __init__(self,name,color,money): #初始化属性
self.__name = name
self.__color = color
self.money = money
def run(self): #定义一个方法
print('一辆%s的%s在马路上飞奔'%(self.__color,self.__name))
def __price(self):
print('这辆车的造格是%d'%self.money)
def get_price(self):
self.__price()
c=Car('保时捷','红色',1000000) #实例化类
c.run() #调用方法
#c.price()
c.get_price()
#AttributeError: 'Car' object has no attribute 'price'
#注释掉c.price()后
#一辆红色的保时捷在马路上飞奔
#这辆车的造格是1000000
2.@property装饰器的介绍
既要保护类的封装特性,又要让开发者可以使用“对象.属性”的方式操作操作类属性,Python 还提供了 @property 装饰器。通过 @property 装饰器,可以直接通过方法名来访问方法,不需要在方法名后添加一对“()”小括号。
2.1语法格式
@property 的语法格式如下:
@property
def 方法名(self):
代码块
class Car:
def __init__(self,name,color):
self.__name = name
self.__color = color
@property
def run(self):
return self.__name
def description(self):
print('一辆%s的%s在马路上飞奔'%(self.__color,self.__name))
c=Car('特斯拉','金色')
print(c.run)
c.description()
c.name='保时捷'
print(c.run)
c.description()
#特斯拉
#一辆金色的特斯拉在马路上飞奔
#特斯拉
#一辆金色的特斯拉在马路上飞奔
如果要修改属性则需要使用setter方法,语法如下
@方法.setter
def 方法(self,value):
代码块
class Car:
def __init__(self,name,color):
self.__name = name
self.__color = color
@property
def run(self):
return self.__name
@run.setter
def run(self,value):
self.__name = value
def description(self):
print('一辆%s的%s在马路上飞奔'%(self.__color,self.__name))
c=Car('特斯拉','金色')
print(c.run)
c.description()
c.run='五菱宏光'
print(c.run)
c.description()
#特斯拉
#一辆金色的特斯拉在马路上飞奔
#五菱宏光
#一辆金色的五菱宏光在马路上飞奔
3.类的继承
在面对对象设计中类是可以继承的,其中被继承的类称为父类或基类,继承的类称子类或者衍生类。类的继承最大的有点是许多父类的共有方法或属性,在子类中不用重新设计。
3.1 语法
class BaseClassName(): #先定义一个父类
baseClass的内容
class DerivedClassName(BaseClassName): #子类继承父类的公有属性或方法
DerviedClass的内容
class Animal(): #定义一个Animal类
def eat(self): #定义eat方法
print("吃食物")
def sleep(self): #定义sleep方法
print('睡觉')
class Dogs(Animal): #Dogs类继承Animal类
def action(self): #定义Dog类自己的action方法
print('狗会看家')
xiao=Dogs()
xiao.eat()
xiao.sleep()
xiao.action()
#吃食物
#睡觉
#狗会看家
3.2 issubclass()函数
判断一个类是不是另外一个类的子类。
class A():
pass
class B(A):
pass
class C(B):
pass
class D(A):
pass
print(issubclass(B,A)) #True
print(issubclass(C,A)) #True
print(issubclass(D,C)) #False
3.3、方法的重写
在子类中,如果有和父类同名的方法,则通过子类实例去调用方法时,会调用子类的方法而不是父类的方法,这个特点我们称为方法的重写。
3.4、当调用一个对象的方法
- 会优先去当前对象中寻找是否具有该方法,如果有则直接调用
- 如果没有,则去当前对象的父类中寻找,如果父类中有则直接调用父类中的方法
- 如果没有,则去父类的父类中寻找,以此类推,直到找到object,如果依然没有找到,则报错.
class A(): #定义一个Animal类
def test1(self):
print('我是A类')
class B(A):
def test2(self):
print('我是B类')
class C(B):
def test3(self):
print('我是C类')
class D(C):
pass
d=D()
d.test1()
#我是A类
d.test()
#AttributeError: 'D' object has no attribute 'test'