2022年 11月 13日

Python面向对象的三大特征

目录

一、封装

1、私有变量

2、私有方法

 3、使用属性

二、继承

2.1单继承:

2.2多继承    

2.4方法的重写

三、多态

3.1 继承与多态

3.2 鸭子类型测试与多态


一、封装

        封装性是面向对象重要的基本特性之一。封装隐藏了对象的内部细节,只保留有限的对外接口,外部调用者不用关心对象的内部细节,使得操作对象变得简单。

        例如:一台计算机内部及其复杂,有主板,CPU,硬盘,内存等,而一般人不需要了解它的内部细节。计算机制造商用机箱把计算机封装起来,对外提供了一些接口,如鼠标,键盘,和显示器等,使用计算机就变得非常简单了。

1、私有变量

        为了防止外部调用者随意存取类的内部数据(成员变量),内部数据(成员变量)会被封装成为“私有变量”,外部调用者只能通过方法调用私有变量。

        默认情况下,Python中的变量是公有的,可以在类的外部访问它们。如果想让它们成为私有变量,则在变量前加上双下划线(__)即可。

示例:

  1. class Student(object):
  2. def __init__(self, name, age):
  3. self.name = name # 创建并初始化公有实例变量
  4. self.__age = age # 创建并初始化私有实例变量
  5. def print_info(self):
  6. print(f'姓名:{self.name},年龄:{self.__age}')
  7. student1 = Student("samual", 21)
  8. student1.print_info() # 打印名字和年龄出来
  9. print(student1.name) # 打印名字出来
  10. print(student1.__age) # 报错

私有变量可以在类的内部进行访问,不能在类的外部进行访问

2、私有方法

        私有方法与私有变量的封装是类似的,在方法前面加上双下划线(__)就是私有方法了。

示例:

  1. class Student(object):
  2. def __init__(self, name, age):
  3. self.name = name # 创建并初始化公有实例变量
  4. self.__age = age # 创建并初始化私有实例变量
  5. def __print_info_inner(self): # 定义为私有方法
  6. print(f'姓名:{self.name},年龄:{self.__age}')
  7. def print_info_out(self):
  8. self.__print_info_inner() # 在类的内部调用私有方法
  9. student1 = Student("samual", 21)
  10. student1.print_info_out()
  11. student1.__print_info_inner() # 在外部调用私有方法会报错

 3、使用属性

        为了实现对象的封装,在一个类中不应该有公有的成员变量,这些成员变量应该都被设计成为私有的,然后通过公有的set(赋值)和get(取值)方法来访问。

示例:

  1. class Student(object):
  2. def __init__(self, name, age):
  3. self.name = name # 创建并初始化公有实例变量
  4. self.__age = age # 创建并初始化私有实例变量
  5. # 实例方法
  6. def print_info(self):
  7. print(f'姓名:{self.name},年龄:{self.__age}')
  8. # set方法
  9. def set_age(self,age):
  10. self.__age = age
  11. # get方法
  12. def get_age(self):
  13. return self.__age
  14. student1 = Student("samual", 21)
  15. student1.print_info()
  16. # 输出:姓名:samual,年龄:21
  17. student1.set_age(18)
  18. student1.print_info()
  19. # 输出:姓名:samual,年龄:18

在上面的示例中,当外部调用通过两个公有方法访问被封装的私有成员变量,会比较麻烦,所有我们还有一种简单的方法来访问私有变量,那个就是通过@property和@属性名.setter装饰器来完成。

示例:

  1. class Student(object):
  2. def __init__(self, name, age):
  3. self.name = name # 创建并初始化公有实例变量
  4. self.__age = age # 创建并初始化私有实例变量
  5. # 实例方法
  6. def print_info(self):
  7. print(f'姓名:{self.name},年龄:{self.__age}')
  8. @property
  9. def age(self): # 替代get_age(self)方法
  10. return self.__age
  11. @age.setter
  12. def age(self,age): # 替代set_age(self,age)方法
  13. self.__age = age
  14. student1 = Student("samual", 21)
  15. student1.print_info()
  16. student1.age = 18 # 通过属性赋值来修改
  17. student1.print_info()

二、继承

        继承性也是面向对象重要的基本特性之一。

        在现实世界中的继承关系无处不在,例如:猫与动物之间的关系:猫是一种特殊动物,具有动物的全部特征和行为,即数据和操作。在面向对象中动物是一般类,被称为“父类”,猫是特殊类,被称为“子类”。特殊类拥有一般类的全部数据和操作,可称子类继承父类。

在Python中声明子类继承父类的语法很简单,定义类时在类的后面使用一对小括号指定它的父类就可以了,在Python中一般类都继承object。

2.1单继承:

语法格式:

  1. class 父类(object):
  2. pass
  3. class 子类(Master):
  4. pass

示例:

  1. # 定义动物类
  2. class Animal(object):
  3. def __init__(self,name):
  4. self.name = name
  5. def print_info(self):
  6. print(f'动物的名字叫:{self.name}')
  7. # 定义猫类使其继承动物类
  8. class Cat(Animal):
  9. def __init__(self,name,age):
  10. Animal.__init__(self,name) # 调用父类的构造方法
  11. self.age = age
  12. cat = Cat('Tom',3)
  13. cat.print_info() # 父类的方法被子类继承,子类对象可调用

在调用父类的构造方法时,我们还有一种写法,那就是使用super()函数

super() 函数,它会使子类从其父继承所有方法和属性:

示例:

  1. class Cat(Animal):
  2. def __init__(self,name,age):
  3. super.__init__(name) # 调用父类的构造方法
  4. self.age = age

 这种方法与用父类名调用的方法效果是一样的。

2.2多继承    

一个类继承多个父类
    在多继承中 如果多个父类中属性名 或者是方法名相同  那么将按照MRO算法查找

    mro:
        1.在自己的类中查找 如果找到 就结束
        2.在父类元组中按照顺序查找 从左到右

类名.__mro__

所有在Python中,当子类继承多个父类时,如果在多个父类有相同的成员方法和成员变量,则子类优先继续左边父类中的成员方法或成员变量,从左到右继承级别从高到低。

语法格式:

  1. class A(Object):
  2. pass
  3. class B(object):
  4. pass
  5. class C(A,B):
  6. pass

示例:

  1. class Horse(object):
  2. def __init__(self,name):
  3. self.name = name
  4. def show_info(self):
  5. print(f'马的名字叫{self.name}')
  6. def run(self):
  7. print('马跑的很快')
  8. class Donkey(object):
  9. def __init__(self,name):
  10. self.name = name
  11. def show_info(self):
  12. print(f'驴的名字叫{self.name}')
  13. def run(self):
  14. print('驴跑的很慢')
  15. def roll(self):
  16. print('驴打滚')
  17. class Mule(Horse,Donkey):
  18. def __init__(self,name,age):
  19. super().__init__(name)
  20. self.age = age
  21. m = Mule('小骡',2)
  22. m.run() # 继承父类马方法
  23. m.roll() # 继承父类驴方法
  24. m.show_info() # 继承父类马方法

2.4方法的重写

        如果子类的方法名与父类的方法名相同,则在这种情况下,子类的方法会重写父类的同名方法。

示例:

  1. class Horse(object):
  2. def __init__(self,name):
  3. self.name = name
  4. def show_info(self):
  5. print(f'马的名字叫{self.name}')
  6. def run(self):
  7. print('马跑的很快')
  8. class Donkey(object):
  9. def __init__(self,name):
  10. self.name = name
  11. def show_info(self):
  12. print(f'驴的名字叫{self.name}')
  13. def run(self):
  14. print('驴跑的很慢')
  15. def roll(self):
  16. print('驴打滚')
  17. class Mule(Horse,Donkey):
  18. def __init__(self,name,age):
  19. super().__init__(name)
  20. self.age = age
  21. def show_info(self):
  22. print(f'骡的名字叫{self.name},今年{self.age}岁')
  23. m = Mule('小骡',2)
  24. m.run() # 继承父类马方法
  25. m.roll() # 继承父类驴方法
  26. m.show_info() # 重写了父类马的方法

三、多态

        多态也是面向对象重要的基本特征之一,“多态”指对象可以表现出多种形态。

        例如:猫,狗,鸭子都属于动物,它们有“叫”和“动”等行为,但是它们叫的方式不同,动的方式也不同。

3.1 继承与多态

        在多个子继承父类,并重写父类方法后,这些子继承所创建的对象之间就是多态的,这些对象采用不同的方式实现父类方法。

示例:

  1. class Animal(object):
  2. def speak(self):
  3. print('动物在叫,但不知道是哪种动物在叫')
  4. class Dog(Animal):
  5. def speak(self):
  6. print('狗:汪汪汪')
  7. class Cat(Animal):
  8. def speak(self):
  9. print('猫:喵喵喵')
  10. an1 = Dog()
  11. an2 = Cat()
  12. an1.speak()
  13. an2.speak()

3.2 鸭子类型测试与多态

        Python的多态性更加灵活,支持鸭子类型测试。鸭子类型测试:指的是若看到一只鸟走起来像鸭子,游起来像鸭子,叫起来也像鸭子,那么这只鸟就可以被叫作鸭子。

        由于支持鸭子类型测试,所有Python解释器不检测发生多态的对象是否继承同一个父类,只要它们有相同的行为(方法),它们之间就是多态的。

例如:我们设计一个函数start(),它接收具有“叫”speak() 方法的对象

  1. class Animal(object):
  2. def speak(self):
  3. print('动物在叫,但不知道是哪种动物在叫')
  4. class Dog(Animal):
  5. def speak(self):
  6. print('狗:汪汪汪')
  7. class Cat(Animal):
  8. def speak(self):
  9. print('猫:喵喵喵')
  10. class Car(object):
  11. def speak(self):
  12. print('汽车:嘀嘀嘀')
  13. def start(obj):
  14. obj.speak()
  15. start(Dog())
  16. start(Cat())
  17. start(Car())

上一章:Python中的面向对象