面向对象的特性
1.封装特性
在日常中封装指的是将我们的物品包裹起来,不让看到内部,具有保护功能。
在程序中,封装(Encapsulation)是将类中的某些部分(某些属性或方法)隐藏起来。
对象不能直接使用隐藏起来的属性或者方法,具有保护功能
封装格式:__属性或者方法名(也叫私有属性或方法)
封装目的:保护隐私
class Girl():
def init(self,name,age):
self.name=name
self.__age=age
def show(self):
print(self.name,self.__age)
zs=Girl(‘zs’,18)
zs.show()
print(zs.__age)#外部无法访问私有属性
私有化封装只需在属性或方法名前加双下滑线,例如__name
私有方法和属性只能在类中调用或使用
2.私有属性
格式:__属性名=值
class Girl():
def init(self,name,age):
self.name=name
self.__age=age
def setAge(self,age):
if age<0 or age>95:
print(‘来自星星的你’)
self.__age=0
else:
self.__age=age
def getAge(self):
return self.__age
zs=Girl(‘zs’,20)
zs.setAge(21)
print(zs.getAge())
zs.__age=22
print(zs.__age)
print(zs.getAge())
print(zs.dict)
3.私有方法
格式:__方法名()
类外不能使用私有方法
class Phone():
def test(self):
print(‘test1’)
def __test1(self):
print(’__test1’)
x=Phone()
x.test()
x.__test() 报错
4.私有化封装后的限制
类中 可以访问
类外/对象外 不可以访问
子类/子类对象 不可以访问
注意事项:
a.在pytho中实现的封装操作,不是通过权限限制,而是通过改名实现的,名字变了找不到而已。
b.可以是__dict__查看属性(包括私有)的值
在类的内部使用私有属性,python内部会自动转换成_类名__属性名
在类的外部不能给对象添加私有属性,因为无法转变成_类名__属性名。
class A():
def init(self,age):
self.__age=age
def setAge(self,age):
self.__age=age
def str(self):
return str(self.__age)
a=A(12)
a.__age=100
print(a.dict)
print(a._A__age)
a._A__age=23
print(a.dict)
通过 对象名._类名__方法名或类名._类名__方法名访问到(但是禁止这么做!),了解即可,一般情况下不要使用。
5.继承特性
继承就是让类和类之间产生父子关系,子类可以拥有父类的静态属性和方法。
【继承就是可以获取另一个类的静态属性和普通方法(并非所有成员)】
在python中,新建的类可以继承一个或多个父类,父类又称基类或超类,新建的类称为派生类或子类
注意:python中的继承分为单继承和多继承
class Animal():
def init(self,name,age,sex):
self.name=name
self.age=age
self.sex=sex
def jiao(self):
print(‘jiao’)
def eat(self):
print(‘eat’)
class Cat(Animal):
def climb(self):
print(‘climb’)
class Dog(Animal):
def swim(self):
print(‘swim’)
d=Dog(‘藏獒’,10,‘公’)
c=Cat(‘波斯’,3,‘母’)
d.jiao()
c.eat()
print(Cat.bases)
6.查看继承的父类
格式:类名.base
注意:
a.python3中如果一个类没有继承任何类,默认继承object,这种类叫新式类
b.object类,是python中的祖宗,所有类都是从object中继承下来的
7.方法的复写
子类中定义了和父类中相同的方法,我们叫做方法的复写(派生方法)
class A():
def hehe(self):
print(‘A:hehe’)
class B(A):
def hehe(self):
print(‘B:hehe’)
a=A()
b=B()
a.hehe()
b.hehe()
8.super()
子类和父类有相同的方法,如果子类想调用父类相同的方法,可以是有super方法
super默认省略两个参数,第一个是类名,第二个是self,这两个参数可以省略不传
super()还可以从类外使用,需要传递类名和对象名
格式:父类名.方法名(self)或者 super().方法名() super(本类类名,对象名)
class A():
num=3
__num1=2
def init(self,x,y):
self.x=x
self.y=y
class B(A):
num=10
def init(self,x,y,z):
self.z=z
super().init(x,y)
b=B(1,2,3)
print(b.x)
print(B.num)
print(b.__num1)#私有属性无法继承
print(A.num)
print(super(B,b).num)
9.init()方法以及其他
子类继承父类,如果子类不复写父类的__init__()方法,创建子类对象会自动调用父类的__init__()方法。
子类继承父类,如果子类复写了父类的__init__()方法,创建子类对象不会在调用父类的__init__()方法。
注意:
Python要求复写父类的__init__()方法时,需要调用父类的__init__()方法,因为存在隐患,例如,父类的初始化方法有参数,子类初始化无参数,子类再调用父类的参数时会报错。
10.派生属性
子类可以添加属性,对象调用的时候将调用自己的属性,需要注意的是如果添加的属性和父类属性重名,再调用的时候将调用子类的属性,这类现象叫做属性的覆盖
class A():
num=3
__num1=2
def init(self,x,y):
self.x=x
self.y=y
class B(A):
num=10
def init(self,x,y,z):
self.z=z
super().init(x,y)
11.多继承
class A():
def t1(self):
print(‘A.t1’)
class B():
def t2(self):
print(‘B.t2’)
class C(A,B):
def t3(self):
print(‘C.t3’)
c=C()
c.t1()
c.t2()
c.t3()
12.继承原理
对于你定义的每一个类,python都会计算出一个解析顺序表(MRO),这个列表就是一个简单的所有基类的线性顺序表
class A():
def init(self):
print(‘A.开始’)
print(‘A.结束’)
# def fun(self):
# print('A.开始')
# print('A.结束')
class B(A):
def init(self):
print(‘B.开始’)
super().init()
print(‘B.结束’)
# def fun(self):
# print('B.开始')
# super().fun()
# print('B.结束')
class C(A):
def init(self):
print(‘C.开始’)
super().init()
print(‘C.结束’)
# def fun(self):
# print('C.开始')
# super().fun()
# print('C.结束')
class D(B,C):
def init(self):
print(‘D.开始’)
super().init()
print(‘D.结束’)
# def fun(self):
# print('D.开始')
# super().fun()
# print('D.结束')
d=D()
d.fun()
print(D.mro())
print(C.mro())
print(B.mro())
13.多态
声明形参的时候是父类对象,实际运行的时候是子类对象