Python面向对象的三大特征

目录

一、封装

1、私有变量

2、私有方法

 3、使用属性

二、继承

2.1单继承:

2.2多继承    

2.4方法的重写

三、多态

3.1 继承与多态

3.2 鸭子类型测试与多态


一、封装

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

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

1、私有变量

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

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

示例:

class Student(object):
    def __init__(self, name, age):
        self.name = name  # 创建并初始化公有实例变量
        self.__age = age  # 创建并初始化私有实例变量

    def print_info(self):
        print(f'姓名:{self.name},年龄:{self.__age}')


student1 = Student("samual", 21)
student1.print_info() # 打印名字和年龄出来
print(student1.name) # 打印名字出来
print(student1.__age) # 报错

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

2、私有方法

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

示例:

class Student(object):
    def __init__(self, name, age):
        self.name = name  # 创建并初始化公有实例变量
        self.__age = age  # 创建并初始化私有实例变量

    def __print_info_inner(self): # 定义为私有方法
        print(f'姓名:{self.name},年龄:{self.__age}')

    def print_info_out(self): 
        self.__print_info_inner() # 在类的内部调用私有方法


student1 = Student("samual", 21)
student1.print_info_out() 

student1.__print_info_inner() # 在外部调用私有方法会报错

 3、使用属性

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

示例:

class Student(object):
    def __init__(self, name, age):
        self.name = name  # 创建并初始化公有实例变量
        self.__age = age  # 创建并初始化私有实例变量

    # 实例方法
    def print_info(self):
        print(f'姓名:{self.name},年龄:{self.__age}')

    # set方法
    def set_age(self,age):
        self.__age = age

    # get方法
    def get_age(self):
        return self.__age


student1 = Student("samual", 21)
student1.print_info()
# 输出:姓名:samual,年龄:21
student1.set_age(18)
student1.print_info()
# 输出:姓名:samual,年龄:18

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

示例:

class Student(object):
    def __init__(self, name, age):
        self.name = name  # 创建并初始化公有实例变量
        self.__age = age  # 创建并初始化私有实例变量

    # 实例方法
    def print_info(self):
        print(f'姓名:{self.name},年龄:{self.__age}')

    @property
    def age(self):   # 替代get_age(self)方法
        return self.__age

    @age.setter
    def age(self,age):   # 替代set_age(self,age)方法
        self.__age = age

student1 = Student("samual", 21)
student1.print_info()
student1.age = 18  # 通过属性赋值来修改
student1.print_info()

二、继承

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

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

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

2.1单继承:

语法格式:

class 父类(object):
	pass

class 子类(Master):
	pass

示例:

# 定义动物类
class Animal(object):
    def __init__(self,name):
        self.name = name

    def print_info(self):
        print(f'动物的名字叫:{self.name}')

# 定义猫类使其继承动物类
class Cat(Animal):
    def __init__(self,name,age):
        Animal.__init__(self,name)   # 调用父类的构造方法
        self.age = age

cat = Cat('Tom',3)
cat.print_info()  # 父类的方法被子类继承,子类对象可调用

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

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

示例:

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

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

2.2多继承    

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

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

类名.__mro__

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

语法格式:

class A(Object):
	pass

class B(object):
	pass

class C(A,B):
	pass

示例:

class Horse(object):
    def __init__(self,name):
        self.name = name

    def show_info(self):
        print(f'马的名字叫{self.name}')

    def run(self):
        print('马跑的很快')

class Donkey(object):
    def __init__(self,name):
        self.name = name

    def show_info(self):
        print(f'驴的名字叫{self.name}')

    def run(self):
        print('驴跑的很慢')

    def roll(self):
        print('驴打滚')

class Mule(Horse,Donkey):
    def __init__(self,name,age):
        super().__init__(name)
        self.age = age
m = Mule('小骡',2)
m.run()   # 继承父类马方法
m.roll()  # 继承父类驴方法
m.show_info()   # 继承父类马方法

2.4方法的重写

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

示例:

class Horse(object):
    def __init__(self,name):
        self.name = name

    def show_info(self):
        print(f'马的名字叫{self.name}')

    def run(self):
        print('马跑的很快')

class Donkey(object):
    def __init__(self,name):
        self.name = name

    def show_info(self):
        print(f'驴的名字叫{self.name}')

    def run(self):
        print('驴跑的很慢')

    def roll(self):
        print('驴打滚')

class Mule(Horse,Donkey):
    def __init__(self,name,age):
        super().__init__(name)
        self.age = age

    def show_info(self):
        print(f'骡的名字叫{self.name},今年{self.age}岁')

m = Mule('小骡',2)
m.run()   # 继承父类马方法
m.roll()  # 继承父类驴方法
m.show_info()   # 重写了父类马的方法

三、多态

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

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

3.1 继承与多态

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

示例:

class Animal(object):
    def speak(self):
        print('动物在叫,但不知道是哪种动物在叫')


class Dog(Animal):
    def speak(self):
        print('狗:汪汪汪')


class Cat(Animal):
    def speak(self):
        print('猫:喵喵喵')

an1 = Dog()
an2 = Cat()
an1.speak()
an2.speak()

3.2 鸭子类型测试与多态

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

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

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

class Animal(object):
    def speak(self):
        print('动物在叫,但不知道是哪种动物在叫')


class Dog(Animal):
    def speak(self):
        print('狗:汪汪汪')


class Cat(Animal):
    def speak(self):
        print('猫:喵喵喵')

class Car(object):
    def speak(self):
        print('汽车:嘀嘀嘀')

def start(obj):
    obj.speak()

start(Dog())
start(Cat())
start(Car())

上一章:Python中的面向对象

你可能感兴趣的:(Python基础,python,开发语言)