面向对象的三大特性 - python小知识2

三大特性

特性 内容
封装 确保对象中数据的安全
继承 保证了对象的可扩展性
多态 增加了对象的灵活性

封装

隐藏对象中不希望被外部访问到的属性、方法。
封装虽然增加了类定义的复杂度,但确保了类的安全。

使用方法

  1. 将属性名设置一个较为复杂的内容。
  2. 对属性名添加双下划线__。添加双下划线的属性称之为私有属性(私有属性不会被继承),添加双下划线的属性名在类内部访问可以直接通过(__属性名)来调用,但在外部无法直接通过(__属性名)来定义。

添加双下划线的属性名在外部名字被自动修改为(_类名_属性名)

class Prople:
    def __init__(self):
        self.__name = '寻觅'
        self.age = '20'
    def can(self):
        print('%s很能吃' % self.__name)
fan = Prople()
fan.__name = '大头'
fan.can() # 寻觅很能吃
  1. 用getter方法和setter方法进行封装(这种方法增加了程序的复杂度,但符合OCP开闭原则)
    1. getter方法:可以让对象中的属性变为只读信息,获取对象的属性名。
    2. setter方法:用来开放对属性的修改权限。
class Prople:
    def __init__(self):
        self.__name = '寻觅'
        self.age = '20'
    def can(self):
        print('%s很能吃' % self.__name)
    # getter方法
    def get_name(self):
        return self.__name
    # setter方法
    def set_name(self, name):
        self.__name = name
fan = Prople()
data = fan.get_name()
fan.data = '大头'
print(data) # 寻觅
fan.set_name('大头')
fan.can() # 大头很能吃

getter于装饰器property,setter于装饰器 方法名.getter 常常会一起使用
property和getter装饰器可以让方法可以像属性一样调用

使用setter设置属性可以增加数据的验证确保属性的正确性。

class Prople:
    __age = 20
    @property
    def age(self):
        print('我已经是一个%s岁的老人了' % self.__age)
        return self.__age
    @age.setter
    def age(self, age):
        if age > 0:
            self.__age = age
a = Prople()
a.age = -21 # 我已经是一个20岁的老人了
a.age

继承

提高了代码的复用性,让类与类直接产生了关系,有了这个关系才产生了之后的多态。

使用方法

创建类时在类名后的括号内添加父类

class Prople:
    def __init__(self):
        self.__name = '寻觅'
    # getter方法
    def get_name(self):
        return self.__name
class man(Prople):
    def looks(self):
        print('%s长得帅' % self.get_name())
data = man()
data.looks()

验证父类的方法:issubclass(类名1,类名2),验证类名1是否为类名2的子类

super

super函数可以让子类获取到父类中的内容,在继承后添加init中默认变量会经常使用,如果不使用super函数,在子类中的init魔术方法会覆盖父类中的魔术方法。语法:super().init(属性名)

class Animal:
    def __init__(self, name):
        self.__name = name
    def call(self):
        print(f'{self.__name}会叫', end='')
class Cat(Animal):
    def __init__(self, name, voice):
        super().__init__(name)
        self.__voice = voice
    def voice(self):
        self.call()
        print(self.__voice)
garfield = Cat('加菲猫', 'Holle')
garfield.voice()

多重继承

在Python中允许多重继承,一个类可以设置多个父类,但在开发中并不建议使用多重继承,多重继承会让代码变得更复杂。

class Animal:

    def __init__(self, name):
        self.__name = name

    def call(self):
        print(f'{self.__name}会叫', end='')

    @property
    def name(self):
        return self.__name

    @name.setter
    def name(self, name):
        self.__name = name


class Catamount():

    def looks(self):
        print('是有毛的,', end='')


class Cat(Catamount, Animal):

    def __init__(self, name, voice):
        super().__init__(name)
        self.__voice = voice

    def voice(self):
        print(self.name, end='')
        self.looks()
        self.call()
        print(self.__voice)


garfield = Cat('加菲猫', 'Holle')
garfield.voice()

查看父类的方法:类名.__bases__

多态

一个对象可以已不同的形态呈现。多态的概念是应用于Java和C#这一类动态语言中,而Python崇尚"鸭子类型"。
动态语言中调用实例方法时不检查类型,只要方法存在,参数正确,就可以调用。它并不要求严格的继承体系,即“当看起来像鸭子,他就可以被当做鸭子”
我们举个例子:我们先设一个动物类和猫类,猫类继承动物类,然后将猫类进行实例化成加菲猫,橘猫,奶猫等不同的形态,而这些不同的形态就是多态。

class Animal:
    def __init__(self, name):
        self.__name = name
    def call(self):
        print(f'{self.__name}会叫', end='')
class Cat(Animal):
    def __init__(self, name, voice):
        super().__init__(name)
        self.__voice = voice
    def voice(self):
        self.call()
        print(self.__voice)
garfield = Cat('加菲猫', 'Holle')
orangecat = Cat('橘猫', '请以大橘为重')
milkcat = Cat('奶猫', '喵喵喵')
garfield.voice()
orangecat.voice()
milkcat.voice()

所谓多态:定义时的类型和运行时的类型不一样,此时就成为多态。

发布了47 篇原创文章 · 获赞 23 · 访问量 3431

猜你喜欢

转载自blog.csdn.net/qq_39611230/article/details/102753374
今日推荐