一、封装
'''
面向对象中的封装:将属性属性私有化,通过设置共有方法来设置和获取该属性的值
1.python 中属性私有化:在属性前添加两个下划线
2.私有属性的操作接口可以自定义set属性()和get属性()方法
3.python则通过@property装饰器实现 私有属性的操作接口
'''
class Person(object):
def __init(self,name,age):
self.__name = name;
self.__age = age
# 自定义get和set 方法实现对私有属性的操作
def getName(self):
return self.__name
def setName(self,name):
self.__name = name
#使用 @property 装饰器 实现
@property
def age(self):
return self.__age
@age.setter
def age(self,age):
self.__age = age
'''
@property说明:
1.将成员函数的访问 变成对 成员属性的访问 例如:
p = Person('zhangsan',18)
p.age 实际上 是访问成员函数age
2.给私有属性提供访问接口 @property 和 XX.setter(XX 一般为私有属性名称去掉下划线) 成对
出现,用于获取值和赋值
'''
'''
属性和方法被私有化之后 只能在当前类中被访问,方法的私有化,同属性的私有化即在方法名之前添加两个下划线
'''
'''
__new__() 方法使用:
1.该方法为实例化对象时第一个调用的方法。
2.该方法若设置返回值为 对象实例,则在该方法调用完成之后,接着调用__init__()方法,否则将不调用__init__() 方法
'''
class Person(obbject):
def __init__(self,name,age):
self.__name = name
self.__age = age
def __new__(cls,*args,**kwargs):
print("new 方法被执行了")
二、继承
'''
单继承:一个子类只有一个父类
claas 父类类名(object):
父类类体
class 子类类名(父类类名):
子类类体
'''
class Person(object):
def __init__(self,name,age):
self.name = name
self.age = age
class Student(Person):
def __init__(self,name,age,num):
# 调用父类构造函数
#方式一: super(当前类名,self).__init__(属性列表)
# super(Student,self).__init__(name,age)
#方式二:父类类名.__init__(self,属性列表)
#Person.__init__(self,name,age)
# 方式三:super().__init__(属性列表)
super().__init__(name,age)
self.num = num
'''
说明:
1.在子类不显示的定义__init__,会将父类中的构造函数继承
2.如果在子类中显式定义了构造函数__init__,则如果需要使用父类中的实例属性
继承的特点:
a.子类对象可以直接访问父类中未被私有化的属性
b.若父类中的属性被私有化,则可以通过@property 接口进行间接访问
c.子类对象可以调用父类中未被私有化的成员函数
d.父类的对象无法访问子类特有的属性和成员函数
'''
'''
多继承:一个子类有多个父类
语法:class 父类1(object):
pass
class 父类2(object):
pass
class 子类(父类1,父类2):
pass
'''
class Father(object):
pass
class Mother(object):
pass
class Son(Father,Mother):
pass
'''
1.子类若继承多个父类,子类没有显示 定义子类构造函数,则创建子类对象的时候,默认调用第一个父类的构造函数,若子类显示 定义构造函数 则在 子类构造函数中 通过 父类名称.__init__(self) 指定要构造哪个父类对象
2.多继承中,子类调用父类 重名的构造函数,若通过supper().重名函数名(列表) 则默认调用 第一个继承类 若通过父类名称.重名函数名(参数列表) 调用 则是调用指定的父类成员函数
'''
三、多态
'''
多态的前提是继承
定义时的类和运行时的类型不一致,或者不确定该变量的类型是什么类型,只有当运行
的时候才能确定该变量的类型
'''
class Person(object):
def feedAnimal(self,animal): #只有在运行时候才知道是哪个animal的子类
animal.eat()
class Animal(object):
def __init__(self,name):
self.name = name
def eat(self):
print("eating")
class Dog(Animal):
pass
class Cat(Animal):
pass
四.继承树
class Base(object):
def __init__(self):
print("inter" +"Base" * 10 )
print("*" * 10)
print("outer" + "Base" * 10)
class A(Base):
def __init__(self):
print("inter" + "A" * 10)
super().__init__()
print("outer" + "A" * 10)
class B(A):
def __init__(self):
print("inter" + "B" * 10)
super().__init__()
print("outer" + "B" * 10)
class C(A):
def __init__(self):
print("inter" + "C" * 10)
super().__init__()
print("outer" + "C" * 10)
class D(B,C):
pass
if __name__ == "__main__":
d = D()
'''
继承关系为:
Base
|
A
/ \
B C
\ /
D
解析顺序为:
interBBBBBBBBBB
interCCCCCCCCCC
interAAAAAAAAAA
interBaseBaseBaseBaseBaseBaseBaseBaseBaseBase
**********
outerBaseBaseBaseBaseBaseBaseBaseBaseBaseBase
outerAAAAAAAAAA
outerCCCCCCCCCC
outerBBBBBBBBBB
由此不难看出:python3 继承树中 类的解析规则 为 广度优先解析规则,而在python2中则按照深度优先规则解析
'''