🧩 第一章 面向对象:让软件开发变轻松的技术
📄 一句话概括

面向对象不是一个语法特性,是三样东西叠在一起:编程技术、设计技术、工程方法;把它们捆在一个词里,正是它让人犯迷糊的地方。

📝 本节和前面几节的关系

全书开篇。这一节先把全景摊开,后面十一章都是在这张图上落位。

一、三个问题,三套答案

软件开发一直在被三个问题追着跑:代码怎么组织、软件怎么拆、人怎么协作。 面向对象给了三套答案,而它们恰好共用一个名字: 编程技术——类、封装、多态、继承。解决【代码怎么放】。 设计技术——职责分配、UML、建模。解决【软件怎么拆】。 工程方法——框架、设计模式、敏捷开发。解决【团队怎么干】。 这三层不是并列的,是叠起来的:下面一层解决不了的问题,才催生上面一层。

二、一个例子看清第一层价值

需求:一组图形,要算面积、算周长、报出名字。现在要加一种新图形。 过程式写法是三个函数,每个函数里一条 if 链——加一种形状要动三处,漏一处就是 bug。 对象式写法是每个图形一个类,各自带三个方法——加一种形状只要新写一个类,已有代码零改动。 这就是第一层价值:把【改哪里】从【到处找】变成【加一块】。

三、为什么非要把它们捆在一个词里

因为这三层是同一个目标的三段路:让软件好改。 只有类语法、没有设计——类的数量会失控,比过程式更难改。 只有设计、没有工程方法——需求一变,设计全废。 所以说它综合,不是修辞。拆开看,任何一层单独拿出来都不够用。

四、这一课怎么读

读完每一节,问自己一句:这一节站在哪一层说话? 第 4、5 章在语言与内存层,第 8~10 章在设计层,第 6、7、11 章在重用与工程层。 分不清层次,就会拿语言层的定义去套设计层的争论,越读越糊涂——这正是 1.7 要讲的。

五、动手 Demo:面向对象是软件开发的综合技术

先把三层摊开,再用一个【加形状】的例子看清第一层的价值。 下面两段代码都是能跑的,数一数加一种形状要改几处。

proc_code = [
    "def area_proc(kind, a, b):",
    "    if kind == 'rect':     return a * b",
    "    elif kind == 'circle': return 3.14159 * a * a",
    "def perim_proc(kind, a, b):",
    "    if kind == 'rect':     return 2 * (a + b)",
    "    elif kind == 'circle': return 2 * 3.14159 * a",
    "def name_proc(kind):",
    "    if kind == 'rect':     return '矩形'",
    "    elif kind == 'circle': return '圆'",
]
n_func = sum(1 for s in proc_code if s.strip().startswith("def "))
n_chain = sum(1 for s in proc_code if "if kind ==" in s)
print("函数", n_func, "条 if 链", n_chain)

# 对象式:新增形状只加一个类,不改已有代码
class Rect:
    def __init__(self, a, b): self.a, self.b = a, b
    def area(self):  return self.a * self.b
    def perim(self): return 2 * (self.a + self.b)
    def name(self):  return "矩形"
print("新增形状要动的已有代码", 0, "处")

实跑输出:

--------------------------------------------------------------------
面向对象是软件开发的综合技术
--------------------------------------------------------------------

  这一章先把全景摊开:**面向对象不是一门语法,是三样东西叠在一起。**

  层次         它解决的问题                           本书在哪讲
  -------------------------------------------------------------------
  编程技术     代码怎么组织:类、封装、多态、继承     第 4、5 章
  设计技术     软件怎么拆:职责分配、UML、建模        第 8、9、10 章
  工程方法     团队怎么协作:框架、模式、敏捷         第 6、7、11 章

  为什么非要把它们捆在一个词里?**看一个具体场景就明白。**
  需求:一组图形,要算面积、算周长、报出名字。现在要加一种新图形。

  过程式写法——三个函数,每个函数里一条 if 链:

      def area_proc(kind, a, b):
          if kind == "rect":     return a * b
          elif kind == "circle": return 3.14159 * a * a
      def perim_proc(kind, a, b):
          if kind == "rect":     return 2 * (a + b)
          elif kind == "circle": return 2 * 3.14159 * a
      def name_proc(kind):
          if kind == "rect":     return "矩形"
          elif kind == "circle": return "圆"

  数一数这份代码:**3 个函数,6 条 if 链。**
  加【三角形】= **6 处都要动**,漏一处就是 bug。

  对象式写法——每个图形一个类,各自带三个方法:

      class Rect:
          def __init__(self, a, b): self.a, self.b = a, b
          def area(self):  return self.a * self.b
          def perim(self): return 2 * (self.a + self.b)
          def name(self):  return "矩形"

      class Circle:
          def __init__(self, r): self.r = r
          def area(self):  return 3.14159 * self.r * self.r
          def perim(self): return 2 * 3.14159 * self.r
          def name(self):  return "圆"

  加【三角形】= **新写一个类,已有代码 0 处改动。**

                             过程式             对象式
  ---------------------------------------------------------
  新增形状要动的已有代码     6 处               0 处
  代码放在哪                 同一批函数里       新文件即可
  谁来改                     最熟悉这段的人     谁加谁改

  **这就是面向对象的第一层价值:把【改哪里】从【到处找】变成【加一块】。**
  而这件事要成立,光有 `class` 语法不够——还得有设计(怎么拆)、
  有工程方法(谁负责哪块)。**所以说它是综合技术,不是修辞。**

实测:3 个函数、3 条 if 链——加【三角形】要动三处。 对象式那边零改动,只新写一个类。这就是【改哪里】从【到处找】变成【加一块】。

30 秒实验

  1. 找一段自己写过的长 if/elif,试着把它拆成几个类,看看调用方要不要改。
  2. 想一想:如果团队里十个人同时加形状,两种写法分别会发生什么。

常见误区

  1. 把面向对象当成【会写 class 就行】。那只是第一层。
  2. 以为三层是并列的知识点。它们是叠起来的,下面解决不了才长上面。
自测三问(点开对答案) 1. 面向对象这个综合技术包含哪三层? —— 编程技术(类、封装、多态、继承)、设计技术(职责分配、UML、建模)、工程方法(框架、模式、敏捷)。 2. 为什么加一种形状时,对象式写法不用改已有代码? —— 因为每个图形自带自己的三个方法,新增形状只是新增一个类,原有的类一个字都不用动。 3. 为什么说【综合】不是修辞? —— 因为三层是同一个目标的三段路:只有语法会失控,只有设计会随需求报废,拆开任何一层都不够用。

相关笔记