专栏首页面向人生编程如何理解“面向对象”编程思想
原创

如何理解“面向对象”编程思想

理解面向对象,首先理解要它的基础概念:

面向对象 ( Object Oriented ) 是将现实问题构建关系,然后抽象成 类 ( class ),给类定义属性和方法后,再将类实例化成 实例 ( instance ) ,通过访问实例的属性和调用方法来进行使用。

在不同的语言中,对象的定义范围不同。在 Python 中“类”和“类的实例”都称为 对象 ( Object ),因为 Python 的类是更顶级的 type 实例化后的对象,也就是常说的“Python 里万物皆对象”;而在 Java 等静态语言中,一般把类的实例称为对象。

理解了理论知识后,接着通过例子,再理解面向对象的三大特征:封装、继承、多态。

下边我们把“女娲造人”这个神话故事,用 Python 的面向对象代码来叙述一遍:

假设我们是女娲(程序设计者),我们突然有个想法,想造一群和自己差不多的小人,小人需要有男女两种性别,外观和行为也有一些差异。那首先我们分析出,不管什么性别,都应该有四肢,所以我们先仿照自己的构造,在脑海中构思泥人的样子(抽象成基类),然后先赋予泥人一些共有的行为(定义类的实例方法):

class Human(object):

    def __init__(self, name):
        # 有个名字,有两只手,两条腿
        self._name = name
        self.hands = 2
        self.legs = 2

    def introduce_self(self):
        # 介绍自己
        print('我是%s' % self._name)

    def work(self):
        # 工作,但还没有定义具体的行为
        raise NotImplementedError

然后我们先捏3个泥人(实例化对象),并给他们取了不同的名字(初始化实例属性):

>>> a = Human('大强子')
>>> b = Human('二狗子')
>>> c = Human('三愣子')

我们让其中一个人介绍自己(调用实例方法):

>>> a.introduce_self()
我是大强子

这里解释一下 Human 的代码,虽然设定了每个人都要工作,但如何工作需要到具体到不同类型的人,所以在基类里我们并没有定义 work 方法的内容,如果强行调用会抛出异常。

还有一点,上面定义属性时,我们把 self._name 前边加了下划线,是因为 Python 里用下划线来约定这是一个受保护变量(对应 Java 中的 protected ),我们不希望外界能直接访问 name 这个属性,必须要通过对象调用 introduce_self() 这个行为介绍了自己,别人才能知道他叫什么名字,这个过程就称之为封装

然后我们继续完成想法,需要给泥人增加两种性别,并且异性之间能结婚,我们开始在刚才泥人模型的基础上(继承于基类),构思出两种性别的泥人的区别(设置不同的属性),然后让他们都可以工作,但工作的内容不一样(调用相同的方法出现不同结果,是多态性),并决定让男人可以娶女人(将这个行为定义为男人的方法)。

import random

class Female(Human):

    def __init__(self, name):
        # 调用父类的初始化方法,依然有名字、两只手、两条腿
        super().__init__(name)
        # 头发和力量进行随机取值
        self.hair = random.randint(3, 5)
        self.power = random.randint(1, 3)
        # 是否已婚
        self.married = False

    def work():
        print('%s采摘了一些果子' % self.name)

class Male(Human):

    def __init__(self, name):
        super().__init__(name)
        self.hair = random.randint(0, 2)
        self.power = random.randint(2, 5)
        self.married = False

    def work():
        print('%s出去打猎了一天' % self.name)

    def marry(self, other):
        # 判断自己或对方是否已结婚,否则抛出异常
        if self.married is True or other.married is True:
            raise ValueError('法律不支持多次结婚')
        # 判断对方是否是女性,否则抛出异常
        if isinstance(other, Female):
            self.married = True
            other.married = True
        else:
            raise TypeError('法律不支持同性结婚')

然后我们就可以让小人活动起来:

>>> a = Male('大强子')
>>> b = Male('二狗子')
>>> c = Female('翠花')
>>> for h in [a, b, c]:
...     # 调用父类的方法
...     h.introduce_self()
我是大强子
我是二狗子
我是翠花
>>> for h in [a, b, c]:
...     # 多态性使相同的方法产生不同的结果
...     h.work()
大强子出去打猎了一天
二狗子出去打猎了一天
翠花采摘了一些果子
>>> a.marry(c)
>>> a.married
True
>>> c.married
True
>>> b.marry(c)
ValueError: 法律不支持多次结婚
>>> b.marry(a)
TypeError: 法律不支持同性结婚

设计到此结束,我们来复盘一下整个过程。

我们先是把人的共有特征抽象成 Human 基类,这个基类并不用于实例化,而是用于让 FemaleMale 继承它,并实现不同的行为。这样我们就避免把一些共有的行为重复在多个类里定义,如果我们后续想对人类的行为进行变动,也只需要修改 Human,继承 Human 的子类会自动获得新行为,这是 继承带来的好处。

我们把 name 设计为受保护变量,外界无法直接访问这个属性,让每个人的隐私得到了保障(一些不必要的行为变得可控),这是 封装 带来的好处。

同时我们在 Human 中预留了 work 方法,并在 FemaleMale 都实现了不同的效果,然后我们知道人人都有 work 方法,因此可以像 introduce_self 一样,用循环批量调用 work 方法,这是 多态 带来的好处。

看到这里你应该有些理解:面向对象是将客观事物和一些关系,抽象成具体的模型(类),并为其设计属性和方法,即 对象 = 属性(特征)+ 方法(行为)

如果是拥有复杂关系的需求,我们就应该尽可能将互相有关联的行为抽象成类,比如每一个网页,网页中每一个组件 等等。实际上面向对象帮助我们在几万行代码的大型项目中,仍然可以游刃有余,正因为如此,才能发展为目前应用最为广泛的编程思想。

但也并不是说任何时候都要“面向对象”,过度的封装和抽象,也会造成代码可读性的下降,以及运行效率的下降,因此我们应该在能将事物抽象化的需求中使用面向对象

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 【编程基础第五讲】java面向对象思想如何理解?

    存在的疑惑: 如何理解面向对象的思想? 解决方案: 比如说,我们要用程序来描述一个人。如果是以往的结构化编程,我们可能会这样; 例如用C语言的话,可能会建立一个...

    程序员互动联盟
  • 如何理解面向对象编程?

    总觉得面向对象编程这个概念比较抽象。对象是个什么鬼?编程不就是写代码吗?你写一堆代码,然后运行,然后得到或显示运行结果,不是这样的吗?为什么还要说是面向对象编程...

    高一峰
  • 面向对象编程的思想

    天天_哥
  • 面向对象的编程思想

    面向过程的思想                                               面向对象的思想:更加符合人民思考习惯的思想, 从执行...

    用户8442333
  • 编程思想:面向对象和面向过程

    何谓面向对象?何谓面向过程?对于这编程界的两大思想,一直贯穿在我们学习和工作当中。我们知道面向过程和面向对象,但要让我们讲出来个所以然,又感觉是不知从何说起,最...

    李海彬
  • 编程思想:面向对象和面向过程

      何谓面向对象?何谓面向过程?对于这编程界的两大思想,一直贯穿在我们学习和工作当中。我们知道面向过程和面向对象,但要让我们讲出来个所以然,又感觉是不知从何说起...

    北国风光
  • 面向对象思想总结 新手如何理解JS面向对象开发?

    面向对象和面向过程的思想有着本质上的区别,作为面向对象的思维来说,当你拿到一个问题时,你分析这个问题不再是第一步先做什么,第二步再做什么,这是面向过程的思维,你...

    小蔚
  • 如何理解python面向对象编程

    类是面向对象程序设计的一部分。面向对象程序设计或者简称为 OOP 致力于创建可重用代码块称之为类。当你想在你的程序中使用类时,你会从类中创建一个对象,这也是面向...

    砸漏
  • 编程思想 _用Minercraft来讲解面向过程与面向对象

    !!!这篇文章主要学习面向对象和面向过程的思想,面向对象的具体实现将在后续文章出现

    木杉乀

扫码关注云+社区

领取腾讯云代金券