Python教程

大爽Python入门教程 7-3 面向对象编程 封装、继承、多态

本文主要是介绍大爽Python入门教程 7-3 面向对象编程 封装、继承、多态,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

大爽Python入门公开课教案 点击查看教程总目录

第二节部分的例子,给人最直观的感受,
就是类能够通过self来实现跨函数(方法)传参。
在参数比较多的情景中,这算是一种比较省事的手段。

实际上,类的真正优点不在于此。
而在于其三大特性:封装、继承、多态。

1 三大特性

封装

封装(encapsulation)
简单的来讲,就是隐藏对象的属性和实现细节,仅对外公开接口。

就像使用手机,我们并不需要知道手机的底层原理,
也不需要知道运行的app的源码,就可以直接使用手机和APP。

这样在开发过程中,
能更轻松地理解类的方法,调用(使用)类的方法,。

继承

继承(inheritance)

如果一个类别B“继承自”另一个类别A,就把这个B称为“A的子类”,
而把A称为“B的父类别”也可以称“A是B的超类”。

继承可以使得子类具有父类别的各种属性和方法,而不需要再次编写相同的代码。

在令子类别继承父类别的同时,可以重新定义某些属性,并重写某些方法,即覆盖父类别的原有属性和方法,使其获得与父类别不同的功能。
另外,为子类追加新的属性和方法也是常见的做法。

比如有一个父类

class Parent:
    pass

写一个继承它的子类,写法如下

class Child(Person):
    pass

也就是在类名后加括号,括号里面加父类。

python支持同时继承多个类,
继承多个时,用逗号隔开。

class GrandChild(Person, Child):
    pass

多态

多态(polymorphism)
指为不同数据类型的实体提供统一的接口。

一个父类可以有多个子类,不同的子类对同一方法,有不同的实现。
这就实现了使用一个接口(方法),实现不同的效果(对于不同的子类)。

多态性一般依赖于继承和重写(见下)。

2 常用补充

重写(Override)

子类重写父类的函数,功能上覆盖掉父类。

class Parent:
    def __init__(self, name):
        self.name = name

    def greet(self):
        print("This is %s" % self.name)


class Child(Parent):
    def greet(self):
        print("Hi, I'm %s" % self.name)


p = Parent("Zhang san")
c = Child("Li si")
p.greet()
c.greet()

其输出为

This is Zhang san
Hi, I'm Li si

其中Child类重写了父类的greet方法。
Child类创建的实例,其调用greet方法时,
调用的是Childgreet方法,
父类的方法被覆盖掉了,不再执行。

super

子类可以重写父类的方法,也可以直接沿用父类的方法(什么都不写)。

在重写时,常有的情形是,沿用父类的代码,
然后做一点修改(比如增加一些属性之类的)。

在这个时候,我们无法直接使用父类的方法,因为这个方法名已经被子类用了。
这个时候我们尝试用super方法来调用父类的方法,执行父类的代码。

比如现有类Animal如下

class Animal:
    def __init__(self, name, age):
        self.name = name
        self.age = age

我们想要继承这个类,实现一个宠物类Pet
这个类要添加一个新的属性owener,其代码如下

class Pet(Animal):
    def __init__(self, name, age, owner):
        super().__init__(name, age)
        self.owner = owner

其中

super().__init__(name, age)

就是调用了父类Animal__init__方法。
这个也有其他写法(但不常用)

super(Pet, self).__init__(name, age)  # 主要是python2用,python3也可以,但不常用了

3 实例理解

Animal

我们这里以动物为例,
先实现一个一个基础的动物类,作为所有的动物的父类。

class Animal:
    def __init__(self, name, age):
        self.name = name
        self.age = age
        self.sound = ""

    def get_name(self):
        return self.name

    def show_info(self):
        print("%s is %s years old" % (self.get_name(), self.age))

    def say(self):
        print("%s say: %s" % (self.get_name(), self.sound))

Dog, Cat, Sheep

接下来实现其子类Dog, Cat, Sheep, 代码如下

class Dog(Animal):
    def __init__(self, name, age):
        super().__init__(name, age)
        self.kind = "Dog"
        self.sound = "Wang wang"

    def get_name(self):
        return "%s %s" % (self.kind, self.name)


class Cat(Animal):
    def __init__(self, name, age):
        super().__init__(name, age)
        self.kind = "Cat"
        self.sound = "miao~"

    def get_name(self):
        return "%s %s" % (self.kind, self.name)


class Sheep(Animal):
    def __init__(self, name, age):
        super().__init__(name, age)
        self.kind = "Sheep"
        self.sound = "Mie~"

    def get_name(self):
        return "%s %s" % (self.kind, self.name)

效果

然后执行以下代码

animals = [
    Dog("Duoduo", 10),
    Cat("Bubu", 12),
    Sheep("Lili", 15),
]

for a in animals:
    a.show_info()
    a.say()

输出如下

Dog DuoDuo is 10 years old
Dog DuoDuo say: Wang wang
Cat Bubu is 12 years old
Cat Bubu say: miao~
Sheep Lili is 15 years old
Sheep Lili say: Mie~

分析

上面的例子展示了面向对象写法的一些特点,或者说优点。

  • 父类Animal的很多代码可以直接沿用。
  • 添加功能时,只用作一点针对性的修改。
  • 不同的子类有相同的方法名,不用单独区分再处理,直接一起调用,方便。
    同一方法,不同子类可以有不同实现,最后效果也不同。
这篇关于大爽Python入门教程 7-3 面向对象编程 封装、继承、多态的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!