Python09 - 面向对象特性
封装、继承和多态
一、封装
# 私有化
class Student:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return '姓名:{}, 年龄:{}'.format(self.name, self.age)
s1 = Student('张三', 18)
print(s1) # 姓名:张三, 年龄:18
s1.age = -9
print(s1) # 姓名:张三, 年龄:-9
# 封装: 私有化属性, 定义公有set和get方法
# __属性: 将属性私有化,访问访问仅仅限于类中; 隐藏属性不被外界随意修改
class Student:
def __init__(self, name, age):
self.__name = name
self.__age = age
self.__score = 60
def setAge(self, age):
if 0 < age < 120:
self.__age = age
else:
print('年龄不准确')
def getAge(self):
return self.__age
def __str__(self):
return '姓名:{}, 年龄:{}'.format(self.__name, self.__age)
s2 = Student('张三', 18)
print(s2) # 姓名:张三, 年龄:18
s2.age = -9
print(s2) # 姓名:张三, 年龄:18
s2.setAge(-9)
print(s2) # 年龄不准确 \n 姓名:张三, 年龄:18
print(dir(Student))
'''
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__',
'__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__',
'__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__',
'__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'getAge', 'setAge']
'''
print(dir(s2))
'''
['_Student__age', '_Student__name', '_Student__score',
'__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__',
'__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__',
'__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__',
'__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'getAge', 'setAge']
'''
print(__name__) # __main__
#print(s2.__name) # AttributeError: 'Student' object has no attribute '__name'
print(s2._Student__name) # 张三
print(s2.__dir__())
'''
['_Student__name', '_Student__age', '_Student__score',
'__module__', '__init__', 'setAge', 'getAge', '__str__', '__dict__',
'__weakref__', '__doc__', '__repr__', '__hash__', '__getattribute__',
'__setattr__', '__delattr__', '__lt__', '__le__', '__eq__', '__ne__',
'__gt__', '__ge__', '__new__', '__reduce_ex__', '__reduce__', '__subclasshook__',
'__init_subclass__', '__format__', '__sizeof__', '__dir__', '__class__']
'''
私有化处理: 装饰器
# 装饰器
class Student:
def __init__(self, name, age):
self.name = name
self.__age = age
# def setAge(self, age):
# if 0 < age < 120:
# self.__age = age
# else:
# print('年龄不准确')
#
# def getAge(self):
# return self.__age
@property # 先有getXXX
def age(self):
return self.__age
@age.setter # 再有setXXX
def age(self, age):
if 0 < age < 120:
self.__age = age
else:
print('年龄不准确')
def __str__(self):
return '姓名:{}, 年龄:{}'.format(self.name, self.__age)
s3 = Student('悟空',500)
s3.name = '孙悟空'
print(s3.name) # 孙悟空
s3.age = 130 # 年龄不准确
print(s3.age) # 500
print(s3.__dir__())
'''
['name', '_Student__age',
'__module__', '__init__', 'age', '__str__', '__dict__', '__weakref__', '__doc__', '__repr__', '__hash__', '__getattribute__',
'__setattr__', '__delattr__', '__lt__', '__le__', '__eq__', '__ne__', '__gt__', '__ge__', '__new__', '__reduce_ex__',
'__reduce__', '__subclasshook__', '__init_subclass__', '__format__', '__sizeof__', '__dir__', '__class__']
'''
二、继承
class Person:
def __init__(self, name, age):
print('**** Person的init初始化')
self.__name = name
self.__age = age
def setName(self, name):
self.__name = name
def getName(self):
return self.__name
def setAge(self, age):
self.__age = age
def getAge(self):
return self.__age
def eat(self):
print(self.__name + '正在吃饭...')
def run(self):
print(self.__name + '正在跑步...')
class Student(Person):
pass
class Teacher(Person):
pass
s1 = Student('小花',14)
s1.run() # 小花正在跑步...
t1 = Teacher('王老师',45)
t1.run() # 王老师正在跑步...
class Student(Person):
def __init__(self, name, age, course):
print('---> student的init')
super().__init__(name, age)
self.course = course
def study(self, course):
print('{}正在学习{}课程'.format(self.getName(), course))
def eat(self, food):
super().eat()
print(self.getName() + '正在吃饭..., 喜欢吃:' + food)
class Employee(Person):
def __init__(self, name, age, salary, manager):
super().__init__(name, age)
self.salary = salary
self.manager = manager
s2 = Student('Tom', 27, '三年五班')
s2.run()
s2.study('数学')
'''
---> student的init
**** Person的init初始化
Tom正在跑步...
Tom正在学习数学课程
'''
1. 如果类中不定义__init__, 调用父类 super class 的 __init__
2. 如果类继承父类时也需要自定义自己的__init__, 需要在当前类的__init__调用父类的__init__
3. 调用父类__init__: super().__init__(参数) super(类名,对象).__init__(参数)
4. 如果父类有eat()方法,子类也定义了eat()方法,默认搜索原则:先找当前类,再找父类
5. s2.eat() 重写(覆盖/override): 父类提供的方法不能满足子类的需求,子类中定义一个同名方法
s2.eat('西瓜')
# Tom正在吃饭...
# Tom正在吃饭..., 喜欢吃:西瓜
多重继承,inspect.getmro() 查看继承顺序
经典类: 从左向右, 深度优先
新式类: 广度优先
class Base:
def test(self):
print('--Base--test--')
class A(Base):
def test(self):
print('--A--test--')
class B(Base):
def test(self):
print('--B--test--')
class C(Base):
def test(self):
print('--C--test--')
class D(A, B, C):
pass
class E(B, C, A):
pass
c = C()
c.test() # --C--test--
d = D()
d.test() # --A--test--
e = E()
e.test() # --B--test--
import inspect
print(inspect.getmro(D))
'''
(<class '__main__.D'>, <class '__main__.A'>, <class '__main__.B'>, <class '__main__.C'>,
<class '__main__.Base'>, <class 'object'>)
'''
print(inspect.getmro(E))
'''
(<class '__main__.E'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>,
<class '__main__.Base'>, <class 'object'>)
'''
class A:
def __init__(self):
print('A')
class B:
def __init__(self):
print('B')
class C(A):
def __init__(self):
print('C')
super(C, self).__init__()
class D(A):
def __init__(self):
print('D')
super(D, self).__init__()
class E(C, B):
def __init__(self):
print('E')
super(E, self).__init__()
class F(C, D, B):
def __init__(self):
print('F')
super(F, self).__init__()
class G(D, B):
def __init__(self):
print('G')
super(G, self).__init__()
if __name__ == '__main__':
import inspect
g = G()
print(inspect.getmro(G))
f = F()
print(inspect.getmro(F))
e = E()
print(inspect.getmro(E))
'''
G
D
A
(<class '__main__.G'>, <class '__main__.D'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)
F
C
D
A
(<class '__main__.F'>, <class '__main__.C'>, <class '__main__.D'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)
E
C
A
(<class '__main__.E'>, <class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)
'''
三、多态
class Pet: role = '宠物' def __init__(self, nickname, age): self.nickname = nickname self.age = age def show(self): print('昵称:{}, 年龄:{}'.format(self.nickname, self.age)) class Cat(Pet): role = '猫' def catch_mouse(self): print('抓老鼠...') class Dog(Pet): role = '狗' def watch_house(self): print('看家...') class Tigger: role = '老虎' def eat(self): print('老虎吃人...') class Person: def __init__(self, name): self.name = name
# pet既可以接收cat,也可以是dog, trigger def feed_pet(self, pet): print('{}喜欢养宠物:{}'.format(self.name, pet.role)) # 对pet参数进行判断,是不是类的对象,或者该类子类的对象 def feed_pet2(self, pet): if isinstance(pet, Pet): print('{}喜欢养宠物:{}, 昵称:{}'.format(self.name, pet.role, pet.nickname)) else: print('不是宠物,不能养...') cat = Cat('花花', 2) dog = Dog('旺财', 1) person = Person('管家') person.feed_pet(cat) # 管家喜欢养宠物:猫 tigger = Tigger() person1 = Person('阿拉伯人') person1.feed_pet(tigger) # 阿拉伯人喜欢养宠物:老虎 person2 = Person('俄罗斯人') person2.feed_pet2(tigger) # 不是宠物,不能养... person2.feed_pet2(dog) # 俄罗斯人喜欢养宠物:狗, 昵称:旺财
四、单例模式
# 单例模式
class Student:
def study(self, course):
print('{}正在学习{}课程'.format(self.name, course))
s = Student()
s1 = Student()
s2 = Student()
print(s) # <__main__.Student object at 0x000000C59D6931F0>
print(s1) # <__main__.Student object at 0x000000C59D68F370>
print(s2) # <__main__.Student object at 0x000000C59D68F3A0>
class Singleton:
__instance = None # 私有化
def __new__(cls): # 重写__new__
print('----> __new__')
if cls.__instance is None:
cls.__instance = object.__new__(cls)
return cls.__instance
else:
return cls.__instance
def show(self, n):
print('------->show', Singleton.__instance, n)
singleton = Singleton() # ----> __new__
print(singleton) # <__main__.Singleton object at 0x000000835F74F220>
singleton2 = Singleton() # ----> __new__
print(singleton2) # <__main__.Singleton object at 0x000000835F74F220>
singleton3 = Singleton() # ----> __new__
print(singleton3) # <__main__.Singleton object at 0x000000835F74F220>
singleton.show(5) # ------->show <__main__.Singleton object at 0x00000085247DF1F0> 5
singleton2.show(7) # ------->show <__main__.Singleton object at 0x00000085247DF1F0> 7
浙公网安备 33010602011771号