<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:media="http://search.yahoo.com/mrss/">
  <channel>
    <title>多型｜林鼎淵 Dean Lin</title>
    <link>https://deanlin.net/tags/%E5%A4%9A%E5%9E%8B/</link>
    <image><url>https://deanlin.net/images/author_hu_aa256fc934e9a932.jpg</url><title>多型｜林鼎淵 Dean Lin</title><link>https://deanlin.net/tags/%E5%A4%9A%E5%9E%8B/</link><width>144</width><height>144</height></image>
    <description>林鼎淵（Dean Lin）的部落格：生成式 AI 企業內訓講師、外商資安公司軟體專家、7 本書作者。400 多篇文章用白話分享生成式 AI 實戰、Claude Code 與 Vibe Coding 教學、團隊合作與職場成長。</description>
    <generator>Hugo</generator>
    <language>zh-tw</language>
    <copyright>© 2020–2026 林鼎淵 Dean Lin</copyright>
    <lastBuildDate>Thu, 25 Aug 2022 13:08:49 +0800</lastBuildDate>
    <atom:link href="https://deanlin.net/tags/%E5%A4%9A%E5%9E%8B/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>多型(Polymorphism)＆繼承(Inheritance)能解決什麼問題？ — 用 TypeScript 學物件導向</title>
      <link>https://deanlin.net/blog/202208/typescript-oop-polymorphism-inheritance/</link>
      <pubDate>Thu, 25 Aug 2022 13:08:49 +0800</pubDate>
      <guid>https://deanlin.net/blog/202208/typescript-oop-polymorphism-inheritance/</guid>
      <dc:creator>林鼎淵</dc:creator>
      <category>技術教學</category>
      <description>市面上很多文章、影片分享了物件導向要如何應用。 卻很少人分享這些概念最初是為了解決什麼問題，所以很多人就算學完了物件導向的概念，卻依舊沒有把它應用在手上的專案。 因此這個系列文中，筆者會先分享「直線思考下」我們會設計出怎樣糟糕的程式…</description>
      <media:content url="https://deanlin.net/blog/202208/typescript-oop-polymorphism-inheritance/images/typescript-oop-polymorphism-inheritance-og_hu_1123639ad1a26f33.jpg" medium="image" type="image/jpeg" width="1200" height="675" />
      <content:encoded><![CDATA[<p>市面上很多文章、影片分享了物件導向要如何應用。</p>
<p>卻很少人分享<strong>這些概念最初是為了解決什麼問題</strong>，所以很多人就算學完了物件導向的概念，卻依舊沒有把它應用在手上的專案。</p>
<p>因此這個系列文中，筆者會先分享「直線思考下」我們會設計出怎樣糟糕的程式；接著再來討論如何應用物件導向的概念對程式做 Refactoring，提升程式未來的擴充性、維護性。</p>
<p><img src="https://deanlin.net/blog/202208/typescript-oop-polymorphism-inheritance/images/typescript-oop-polymorphism-inheritance-01.webp" width="1400" height="730" alt="多型(Polymorphism)＆繼承(Inheritance)能解決什麼問題？ — 用 TypeScript 學物件導向（圖 1）" fetchpriority="high" decoding="async"></p>
<pre tabindex="0"><code>大綱
一、建立一個讓不同職業交流的平台
二、老闆想要再多加幾個職業
三、[Refactoring]將「介紹技能」程式移轉到 Class 變成 Function
四、平台經營的很成功，要擴增「技能交換、讀書會」的功能
五、[Refactoring]老闆…我改不動了，打算用繼承進行重構
六、應用多型讓不同職業的工作者進行交流
七、所以「多型(Polymorphism)＆繼承(Inheritance)」的概念幫我們解決了什麼問題？
</code></pre><h2 id="一建立一個讓不同職業交流的平台">一、建立一個讓不同職業交流的平台<a class="h-anchor" href="#%e4%b8%80%e5%bb%ba%e7%ab%8b%e4%b8%80%e5%80%8b%e8%ae%93%e4%b8%8d%e5%90%8c%e8%81%b7%e6%a5%ad%e4%ba%a4%e6%b5%81%e7%9a%84%e5%b9%b3%e5%8f%b0" aria-label="這個段落的連結"></a></h2>
<p>既然要建立不同職業交流的平台，那工作者就是必不可少的元素；我們先建立一個「工作者（Worker）」的 Class，並設計「name（姓名）、jobType（職業類型）」作為屬性。</p>
<p>因為這個系統只是試水溫的階段，所以在一開始只開放「工程師（ENGINEER）、設計師（DESIGNER）、律師（LAWYER）」這幾個職業（Job），我們用列舉（enum）的方式來實現。</p>
<div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-typescript" data-lang="typescript"><span style="display:flex;"><span><span style="color:#ff7b72">export</span> <span style="color:#ff7b72">enum</span> Job { <span style="color:#8b949e;font-style:italic">// 職業對應的常數
</span></span></span><span style="display:flex;"><span>  ENGINEER <span style="color:#ff7b72;font-weight:bold">=</span> <span style="color:#a5d6ff">0</span>,
</span></span><span style="display:flex;"><span>  DESIGNER <span style="color:#ff7b72;font-weight:bold">=</span> <span style="color:#a5d6ff">1</span>,
</span></span><span style="display:flex;"><span>  LAWYER <span style="color:#ff7b72;font-weight:bold">=</span> <span style="color:#a5d6ff">2</span>,
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span><span style="color:#ff7b72">export</span> <span style="color:#ff7b72">class</span> Worker {
</span></span><span style="display:flex;"><span>  <span style="color:#ff7b72">private</span> _name: <span style="color:#ff7b72">string</span>; <span style="color:#8b949e;font-style:italic">// 姓名
</span></span></span><span style="display:flex;"><span>  <span style="color:#ff7b72">private</span> _jobType: <span style="color:#ff7b72">number</span>; <span style="color:#8b949e;font-style:italic">// 職業類型
</span></span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#ff7b72">constructor</span>(theName: <span style="color:#ff7b72">string</span>, theJobType: <span style="color:#ff7b72">number</span>) {
</span></span><span style="display:flex;"><span>    <span style="color:#ff7b72">this</span>._name <span style="color:#ff7b72;font-weight:bold">=</span> theName;
</span></span><span style="display:flex;"><span>    <span style="color:#ff7b72">this</span>._jobType <span style="color:#ff7b72;font-weight:bold">=</span> theJobType;
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#ff7b72">public</span> <span style="color:#ff7b72">get</span> name() {
</span></span><span style="display:flex;"><span>    <span style="color:#ff7b72">return</span> <span style="color:#ff7b72">this</span>._name;
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#ff7b72">public</span> <span style="color:#ff7b72">set</span> name(theName: <span style="color:#ff7b72">string</span>) {
</span></span><span style="display:flex;"><span>    <span style="color:#ff7b72">this</span>._name <span style="color:#ff7b72;font-weight:bold">=</span> theName;
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#ff7b72">public</span> <span style="color:#ff7b72">get</span> jobType() {
</span></span><span style="display:flex;"><span>    <span style="color:#ff7b72">return</span> <span style="color:#ff7b72">this</span>._jobType;
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#ff7b72">public</span> <span style="color:#ff7b72">set</span> jobType(theJobType: <span style="color:#ff7b72">number</span>) {
</span></span><span style="display:flex;"><span>    <span style="color:#ff7b72">this</span>._jobType <span style="color:#ff7b72;font-weight:bold">=</span> theJobType;
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p class="code-source">原始碼：<a href="https://gist.github.com/dean9703111/be165f0a7735971ae8a62346ff2bf668" rel="noopener">Worker-init.ts</a>（GitHub Gist）</p>
<p>在 Worker 的 Class 建立完後，我們便可以將對應的「職業」實體化；既然我們要讓不同的職業進行交流，就模擬一小段讓他們「介紹技能」的程式。</p>
<div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-typescript" data-lang="typescript"><span style="display:flex;"><span><span style="color:#ff7b72">let</span> workers <span style="color:#ff7b72;font-weight:bold">=</span> [
</span></span><span style="display:flex;"><span>  <span style="color:#ff7b72">new</span> Worker(<span style="color:#a5d6ff">&#34;Dean&#34;</span>, Job.ENGINEER), <span style="color:#8b949e;font-style:italic">// 產生工作者
</span></span></span><span style="display:flex;"><span>  <span style="color:#ff7b72">new</span> Worker(<span style="color:#a5d6ff">&#34;Amy&#34;</span>, Job.DESIGNER),
</span></span><span style="display:flex;"><span>  <span style="color:#ff7b72">new</span> Worker(<span style="color:#a5d6ff">&#34;Peter&#34;</span>, Job.LAWYER),
</span></span><span style="display:flex;"><span>];
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>workers.forEach((worker) <span style="color:#ff7b72;font-weight:bold">=&gt;</span> {
</span></span><span style="display:flex;"><span>  console.log(worker.name);
</span></span><span style="display:flex;"><span>  <span style="color:#ff7b72">switch</span> (worker.jobType) {
</span></span><span style="display:flex;"><span>    <span style="color:#ff7b72">case</span> Job.ENGINEER<span style="color:#ff7b72;font-weight:bold">:</span> {
</span></span><span style="display:flex;"><span>      console.log(<span style="color:#a5d6ff">&#34;我超會寫程式！&#34;</span>);
</span></span><span style="display:flex;"><span>      <span style="color:#ff7b72">break</span>;
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>    <span style="color:#ff7b72">case</span> Job.DESIGNER<span style="color:#ff7b72;font-weight:bold">:</span> {
</span></span><span style="display:flex;"><span>      console.log(<span style="color:#a5d6ff">&#34;我超會UI設計！&#34;</span>);
</span></span><span style="display:flex;"><span>      <span style="color:#ff7b72">break</span>;
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>    <span style="color:#ff7b72">case</span> Job.LAWYER<span style="color:#ff7b72;font-weight:bold">:</span> {
</span></span><span style="display:flex;"><span>      console.log(<span style="color:#a5d6ff">&#34;我超會打官司！&#34;</span>);
</span></span><span style="display:flex;"><span>      <span style="color:#ff7b72">break</span>;
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>});
</span></span></code></pre></div><p class="code-source">原始碼：<a href="https://gist.github.com/dean9703111/c1611b4265fa117c34e724cba80cbae6" rel="noopener">introSkill-init.ts</a>（GitHub Gist）</p>
<hr>
<h2 id="二老闆想要再多加幾個職業">二、老闆想要再多加幾個職業<a class="h-anchor" href="#%e4%ba%8c%e8%80%81%e9%97%86%e6%83%b3%e8%a6%81%e5%86%8d%e5%a4%9a%e5%8a%a0%e5%b9%be%e5%80%8b%e8%81%b7%e6%a5%ad" aria-label="這個段落的連結"></a></h2>
<p>系統上線後反應熱烈，老闆希望再新增「魔術師（MAGICIAN）、畫家（PAINTER）」這兩個職業，於是我們在 Job 裡面新增這兩個職業的常數。</p>
<div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-typescript" data-lang="typescript"><span style="display:flex;"><span><span style="color:#ff7b72">export</span> <span style="color:#ff7b72">enum</span> Job { <span style="color:#8b949e;font-style:italic">// 職業對應的常數
</span></span></span><span style="display:flex;"><span>  ENGINEER <span style="color:#ff7b72;font-weight:bold">=</span> <span style="color:#a5d6ff">0</span>,
</span></span><span style="display:flex;"><span>  DESIGNER <span style="color:#ff7b72;font-weight:bold">=</span> <span style="color:#a5d6ff">1</span>,
</span></span><span style="display:flex;"><span>  LAWYER <span style="color:#ff7b72;font-weight:bold">=</span> <span style="color:#a5d6ff">2</span>,
</span></span><span style="display:flex;"><span>  MAGICIAN <span style="color:#ff7b72;font-weight:bold">=</span> <span style="color:#a5d6ff">3</span>,
</span></span><span style="display:flex;"><span>  PAINTER <span style="color:#ff7b72;font-weight:bold">=</span> <span style="color:#a5d6ff">4</span>
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p class="code-source">原始碼：<a href="https://gist.github.com/dean9703111/ff56305a0ac0798f4668290d8de420f4" rel="noopener">job-add.ts</a>（GitHub Gist）</p>
<p>在 Worker 的 Class 調整完畢後，我們也要同步調整讓工作者「介紹技能」的程式。</p>
<div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-typescript" data-lang="typescript"><span style="display:flex;"><span><span style="color:#ff7b72">let</span> workers <span style="color:#ff7b72;font-weight:bold">=</span> [
</span></span><span style="display:flex;"><span>  <span style="color:#ff7b72">new</span> Worker(<span style="color:#a5d6ff">&#34;Dean&#34;</span>, Job.ENGINEER), <span style="color:#8b949e;font-style:italic">// 產生工作者
</span></span></span><span style="display:flex;"><span>  <span style="color:#ff7b72">new</span> Worker(<span style="color:#a5d6ff">&#34;Amy&#34;</span>, Job.DESIGNER),
</span></span><span style="display:flex;"><span>  <span style="color:#ff7b72">new</span> Worker(<span style="color:#a5d6ff">&#34;Peter&#34;</span>, Job.LAWYER),
</span></span><span style="display:flex;"><span>  <span style="color:#ff7b72">new</span> Worker(<span style="color:#a5d6ff">&#34;Davy&#34;</span>, Job.MAGICIAN),
</span></span><span style="display:flex;"><span>  <span style="color:#ff7b72">new</span> Worker(<span style="color:#a5d6ff">&#34;Angela&#34;</span>, Job.PAINTER),
</span></span><span style="display:flex;"><span>];
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>workers.forEach((worker) <span style="color:#ff7b72;font-weight:bold">=&gt;</span> {
</span></span><span style="display:flex;"><span>  console.log(worker.name);
</span></span><span style="display:flex;"><span>  <span style="color:#ff7b72">switch</span> (worker.jobType) {
</span></span><span style="display:flex;"><span>    <span style="color:#ff7b72">case</span> Job.ENGINEER<span style="color:#ff7b72;font-weight:bold">:</span> {
</span></span><span style="display:flex;"><span>      console.log(<span style="color:#a5d6ff">&#34;我超會寫程式！&#34;</span>);
</span></span><span style="display:flex;"><span>      <span style="color:#ff7b72">break</span>;
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>    <span style="color:#ff7b72">case</span> Job.DESIGNER<span style="color:#ff7b72;font-weight:bold">:</span> {
</span></span><span style="display:flex;"><span>      console.log(<span style="color:#a5d6ff">&#34;我超會UI設計！&#34;</span>);
</span></span><span style="display:flex;"><span>      <span style="color:#ff7b72">break</span>;
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>    <span style="color:#ff7b72">case</span> Job.LAWYER<span style="color:#ff7b72;font-weight:bold">:</span> {
</span></span><span style="display:flex;"><span>      console.log(<span style="color:#a5d6ff">&#34;我超會打官司！&#34;</span>);
</span></span><span style="display:flex;"><span>      <span style="color:#ff7b72">break</span>;
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>    <span style="color:#ff7b72">case</span> Job.MAGICIAN<span style="color:#ff7b72;font-weight:bold">:</span> {
</span></span><span style="display:flex;"><span>      console.log(<span style="color:#a5d6ff">&#34;我會變魔術！&#34;</span>);
</span></span><span style="display:flex;"><span>      <span style="color:#ff7b72">break</span>;
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>    <span style="color:#ff7b72">case</span> Job.PAINTER<span style="color:#ff7b72;font-weight:bold">:</span> {
</span></span><span style="display:flex;"><span>      console.log(<span style="color:#a5d6ff">&#34;我會畫畫！&#34;</span>);
</span></span><span style="display:flex;"><span>      <span style="color:#ff7b72">break</span>;
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>});
</span></span></code></pre></div><p class="code-source">原始碼：<a href="https://gist.github.com/dean9703111/aac5820b25bd16363c29d8b65251edc0" rel="noopener">introSkill-add.ts</a>（GitHub Gist）</p>
<p>我想程式寫到這裡，應該有很多人發覺不對勁了，如果每新增一個職業，我們就要在另一個檔案中調整程式，這樣伴隨系統的成長，我們會越來越難維護它。</p>
<hr>
<h2 id="三refactoring將介紹技能程式移轉到-class-變成-function">三、[Refactoring]將「介紹技能」程式移轉到 Class 變成 Function<a class="h-anchor" href="#%e4%b8%89refactoring%e5%b0%87%e4%bb%8b%e7%b4%b9%e6%8a%80%e8%83%bd%e7%a8%8b%e5%bc%8f%e7%a7%bb%e8%bd%89%e5%88%b0-class-%e8%ae%8a%e6%88%90-function" aria-label="這個段落的連結"></a></h2>
<p>為了避免日後我們要在多個地方維護程式，我們把判斷職業的 switch 轉移到 Worker 的 Class 中，並新增一個「introSkill」的 Function 讓外部使用。</p>
<div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-typescript" data-lang="typescript"><span style="display:flex;"><span><span style="color:#ff7b72">export</span> <span style="color:#ff7b72">class</span> Worker {
</span></span><span style="display:flex;"><span>  <span style="color:#ff7b72">private</span> _name: <span style="color:#ff7b72">string</span>; <span style="color:#8b949e;font-style:italic">// 姓名
</span></span></span><span style="display:flex;"><span>  <span style="color:#ff7b72">private</span> _jobType: <span style="color:#ff7b72">number</span>; <span style="color:#8b949e;font-style:italic">// 職業類型
</span></span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#ff7b72">constructor</span>(theName: <span style="color:#ff7b72">string</span>, theJobType: <span style="color:#ff7b72">number</span>) {
</span></span><span style="display:flex;"><span>    <span style="color:#ff7b72">this</span>._name <span style="color:#ff7b72;font-weight:bold">=</span> theName;
</span></span><span style="display:flex;"><span>    <span style="color:#ff7b72">this</span>._jobType <span style="color:#ff7b72;font-weight:bold">=</span> theJobType;
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#ff7b72">public</span> <span style="color:#ff7b72">get</span> name() {
</span></span><span style="display:flex;"><span>    <span style="color:#ff7b72">return</span> <span style="color:#ff7b72">this</span>._name;
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#ff7b72">public</span> <span style="color:#ff7b72">set</span> name(theName: <span style="color:#ff7b72">string</span>) {
</span></span><span style="display:flex;"><span>    <span style="color:#ff7b72">this</span>._name <span style="color:#ff7b72;font-weight:bold">=</span> theName;
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#ff7b72">public</span> <span style="color:#ff7b72">get</span> jobType() {
</span></span><span style="display:flex;"><span>    <span style="color:#ff7b72">return</span> <span style="color:#ff7b72">this</span>._jobType;
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#ff7b72">public</span> <span style="color:#ff7b72">set</span> jobType(theJobType: <span style="color:#ff7b72">number</span>) {
</span></span><span style="display:flex;"><span>    <span style="color:#ff7b72">this</span>._jobType <span style="color:#ff7b72;font-weight:bold">=</span> theJobType;
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#ff7b72">public</span> introSkill() {
</span></span><span style="display:flex;"><span>    <span style="color:#ff7b72">switch</span> (<span style="color:#ff7b72">this</span>.jobType) {
</span></span><span style="display:flex;"><span>      <span style="color:#ff7b72">case</span> Job.ENGINEER<span style="color:#ff7b72;font-weight:bold">:</span> {
</span></span><span style="display:flex;"><span>        console.log(<span style="color:#a5d6ff">&#34;我超會寫程式！&#34;</span>);
</span></span><span style="display:flex;"><span>        <span style="color:#ff7b72">break</span>;
</span></span><span style="display:flex;"><span>      }
</span></span><span style="display:flex;"><span>      <span style="color:#ff7b72">case</span> Job.DESIGNER<span style="color:#ff7b72;font-weight:bold">:</span> {
</span></span><span style="display:flex;"><span>        console.log(<span style="color:#a5d6ff">&#34;我超會UI設計！&#34;</span>);
</span></span><span style="display:flex;"><span>        <span style="color:#ff7b72">break</span>;
</span></span><span style="display:flex;"><span>      }
</span></span><span style="display:flex;"><span>      <span style="color:#ff7b72">case</span> Job.LAWYER<span style="color:#ff7b72;font-weight:bold">:</span> {
</span></span><span style="display:flex;"><span>        console.log(<span style="color:#a5d6ff">&#34;我是傳奇律師！&#34;</span>);
</span></span><span style="display:flex;"><span>        <span style="color:#ff7b72">break</span>;
</span></span><span style="display:flex;"><span>      }
</span></span><span style="display:flex;"><span>      <span style="color:#ff7b72">case</span> Job.MAGICIAN<span style="color:#ff7b72;font-weight:bold">:</span> {
</span></span><span style="display:flex;"><span>        console.log(<span style="color:#a5d6ff">&#34;我是魔術師！&#34;</span>);
</span></span><span style="display:flex;"><span>        <span style="color:#ff7b72">break</span>;
</span></span><span style="display:flex;"><span>      }
</span></span><span style="display:flex;"><span>      <span style="color:#ff7b72">case</span> Job.PAINTER<span style="color:#ff7b72;font-weight:bold">:</span> {
</span></span><span style="display:flex;"><span>        console.log(<span style="color:#a5d6ff">&#34;我是畫家！&#34;</span>);
</span></span><span style="display:flex;"><span>        <span style="color:#ff7b72">break</span>;
</span></span><span style="display:flex;"><span>      }
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p class="code-source">原始碼：<a href="https://gist.github.com/dean9703111/5face493257f1308f643c9a83c1350c1" rel="noopener">worker-addFun.ts</a>（GitHub Gist）</p>
<p>經過上面的調整後，不同職業的工作者如果想「介紹技能」，呼叫 introSkill 的 Function 即可。</p>
<div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-typescript" data-lang="typescript"><span style="display:flex;"><span><span style="color:#ff7b72">let</span> workers <span style="color:#ff7b72;font-weight:bold">=</span> [
</span></span><span style="display:flex;"><span>  <span style="color:#ff7b72">new</span> Worker(<span style="color:#a5d6ff">&#34;Dean&#34;</span>, Job.ENGINEER), <span style="color:#8b949e;font-style:italic">// 產生工作者
</span></span></span><span style="display:flex;"><span>  <span style="color:#ff7b72">new</span> Worker(<span style="color:#a5d6ff">&#34;Amy&#34;</span>, Job.DESIGNER),
</span></span><span style="display:flex;"><span>  <span style="color:#ff7b72">new</span> Worker(<span style="color:#a5d6ff">&#34;Peter&#34;</span>, Job.LAWYER),
</span></span><span style="display:flex;"><span>  <span style="color:#ff7b72">new</span> Worker(<span style="color:#a5d6ff">&#34;Davy&#34;</span>, Job.MAGICIAN),
</span></span><span style="display:flex;"><span>  <span style="color:#ff7b72">new</span> Worker(<span style="color:#a5d6ff">&#34;Angela&#34;</span>, Job.PAINTER),
</span></span><span style="display:flex;"><span>];
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>workers.forEach((worker) <span style="color:#ff7b72;font-weight:bold">=&gt;</span> {
</span></span><span style="display:flex;"><span>  console.log(worker.name);
</span></span><span style="display:flex;"><span>  worker.introSkill() <span style="color:#8b949e;font-style:italic">// 改成函式後就不用這樣改來改去了
</span></span></span><span style="display:flex;"><span>});
</span></span></code></pre></div><p class="code-source">原始碼：<a href="https://gist.github.com/dean9703111/95eab0cb648c88bfc94690d9acf43ce1" rel="noopener">worker-refactoring.ts</a>（GitHub Gist）</p>
<hr>
<h2 id="四平台經營的很成功要擴增技能交換讀書會的功能">四、平台經營的很成功，要擴增「技能交換、讀書會」的功能<a class="h-anchor" href="#%e5%9b%9b%e5%b9%b3%e5%8f%b0%e7%b6%93%e7%87%9f%e7%9a%84%e5%be%88%e6%88%90%e5%8a%9f%e8%a6%81%e6%93%b4%e5%a2%9e%e6%8a%80%e8%83%bd%e4%ba%a4%e6%8f%9b%e8%ae%80%e6%9b%b8%e6%9c%83%e7%9a%84%e5%8a%9f%e8%83%bd" aria-label="這個段落的連結"></a></h2>
<p>為了讓各行各業交流的更加熱烈、深化自身技能，老闆請你增加「技能交換（skillExchange）、讀書會（studyGroup）」的功能，如果你依照原本的邏輯繼續設計程式會長這樣。</p>
<div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-typescript" data-lang="typescript"><span style="display:flex;"><span><span style="color:#ff7b72">export</span> <span style="color:#ff7b72">class</span> Worker {
</span></span><span style="display:flex;"><span>  <span style="color:#ff7b72">private</span> _name: <span style="color:#ff7b72">string</span>; <span style="color:#8b949e;font-style:italic">// 姓名
</span></span></span><span style="display:flex;"><span>  <span style="color:#ff7b72">private</span> _jobType: <span style="color:#ff7b72">number</span>; <span style="color:#8b949e;font-style:italic">// 職業類型
</span></span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#ff7b72">constructor</span>(theName: <span style="color:#ff7b72">string</span>, theJobType: <span style="color:#ff7b72">number</span>) {
</span></span><span style="display:flex;"><span>    <span style="color:#ff7b72">this</span>._name <span style="color:#ff7b72;font-weight:bold">=</span> theName;
</span></span><span style="display:flex;"><span>    <span style="color:#ff7b72">this</span>._jobType <span style="color:#ff7b72;font-weight:bold">=</span> theJobType;
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#ff7b72">public</span> <span style="color:#ff7b72">get</span> name() {
</span></span><span style="display:flex;"><span>    <span style="color:#ff7b72">return</span> <span style="color:#ff7b72">this</span>._name;
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#ff7b72">public</span> <span style="color:#ff7b72">set</span> name(theName: <span style="color:#ff7b72">string</span>) {
</span></span><span style="display:flex;"><span>    <span style="color:#ff7b72">this</span>._name <span style="color:#ff7b72;font-weight:bold">=</span> theName;
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#ff7b72">public</span> <span style="color:#ff7b72">get</span> jobType() {
</span></span><span style="display:flex;"><span>    <span style="color:#ff7b72">return</span> <span style="color:#ff7b72">this</span>._jobType;
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#ff7b72">public</span> <span style="color:#ff7b72">set</span> jobType(theJobType: <span style="color:#ff7b72">number</span>) {
</span></span><span style="display:flex;"><span>    <span style="color:#ff7b72">this</span>._jobType <span style="color:#ff7b72;font-weight:bold">=</span> theJobType;
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#ff7b72">public</span> introSkill() {
</span></span><span style="display:flex;"><span>    <span style="color:#ff7b72">switch</span> (<span style="color:#ff7b72">this</span>.jobType) {
</span></span><span style="display:flex;"><span>      <span style="color:#ff7b72">case</span> Job.ENGINEER<span style="color:#ff7b72;font-weight:bold">:</span> {
</span></span><span style="display:flex;"><span>        console.log(<span style="color:#a5d6ff">&#34;我超會寫程式！&#34;</span>);
</span></span><span style="display:flex;"><span>        <span style="color:#ff7b72">break</span>;
</span></span><span style="display:flex;"><span>      }
</span></span><span style="display:flex;"><span>      <span style="color:#ff7b72">case</span> Job.DESIGNER<span style="color:#ff7b72;font-weight:bold">:</span> {
</span></span><span style="display:flex;"><span>        console.log(<span style="color:#a5d6ff">&#34;我超會UI設計！&#34;</span>);
</span></span><span style="display:flex;"><span>        <span style="color:#ff7b72">break</span>;
</span></span><span style="display:flex;"><span>      }
</span></span><span style="display:flex;"><span>      <span style="color:#ff7b72">case</span> Job.LAWYER<span style="color:#ff7b72;font-weight:bold">:</span> {
</span></span><span style="display:flex;"><span>        console.log(<span style="color:#a5d6ff">&#34;我是傳奇律師！&#34;</span>);
</span></span><span style="display:flex;"><span>        <span style="color:#ff7b72">break</span>;
</span></span><span style="display:flex;"><span>      }
</span></span><span style="display:flex;"><span>      <span style="color:#ff7b72">case</span> Job.MAGICIAN<span style="color:#ff7b72;font-weight:bold">:</span> {
</span></span><span style="display:flex;"><span>        console.log(<span style="color:#a5d6ff">&#34;我是魔術師！&#34;</span>);
</span></span><span style="display:flex;"><span>        <span style="color:#ff7b72">break</span>;
</span></span><span style="display:flex;"><span>      }
</span></span><span style="display:flex;"><span>      <span style="color:#ff7b72">case</span> Job.PAINTER<span style="color:#ff7b72;font-weight:bold">:</span> {
</span></span><span style="display:flex;"><span>        console.log(<span style="color:#a5d6ff">&#34;我是畫家！&#34;</span>);
</span></span><span style="display:flex;"><span>        <span style="color:#ff7b72">break</span>;
</span></span><span style="display:flex;"><span>      }
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>  <span style="color:#ff7b72">public</span> skillExchange(jobType: <span style="color:#ff7b72">number</span>) {
</span></span><span style="display:flex;"><span>    <span style="color:#ff7b72">switch</span> (jobType) {
</span></span><span style="display:flex;"><span>      <span style="color:#ff7b72">case</span> Job.ENGINEER<span style="color:#ff7b72;font-weight:bold">:</span> {
</span></span><span style="display:flex;"><span>        console.log(<span style="color:#a5d6ff">&#34;我想學程式！&#34;</span>);
</span></span><span style="display:flex;"><span>        <span style="color:#ff7b72">break</span>;
</span></span><span style="display:flex;"><span>      }
</span></span><span style="display:flex;"><span>      <span style="color:#ff7b72">case</span> Job.DESIGNER<span style="color:#ff7b72;font-weight:bold">:</span> {
</span></span><span style="display:flex;"><span>        console.log(<span style="color:#a5d6ff">&#34;我想學UI設計！&#34;</span>);
</span></span><span style="display:flex;"><span>        <span style="color:#ff7b72">break</span>;
</span></span><span style="display:flex;"><span>      }
</span></span><span style="display:flex;"><span>      <span style="color:#ff7b72">case</span> Job.LAWYER<span style="color:#ff7b72;font-weight:bold">:</span> {
</span></span><span style="display:flex;"><span>        console.log(<span style="color:#a5d6ff">&#34;我想學法律！&#34;</span>);
</span></span><span style="display:flex;"><span>        <span style="color:#ff7b72">break</span>;
</span></span><span style="display:flex;"><span>      }
</span></span><span style="display:flex;"><span>      <span style="color:#ff7b72">case</span> Job.MAGICIAN<span style="color:#ff7b72;font-weight:bold">:</span> {
</span></span><span style="display:flex;"><span>        console.log(<span style="color:#a5d6ff">&#34;我想學魔術！&#34;</span>);
</span></span><span style="display:flex;"><span>        <span style="color:#ff7b72">break</span>;
</span></span><span style="display:flex;"><span>      }
</span></span><span style="display:flex;"><span>      <span style="color:#ff7b72">case</span> Job.PAINTER<span style="color:#ff7b72;font-weight:bold">:</span> {
</span></span><span style="display:flex;"><span>        console.log(<span style="color:#a5d6ff">&#34;我想學畫畫！&#34;</span>);
</span></span><span style="display:flex;"><span>        <span style="color:#ff7b72">break</span>;
</span></span><span style="display:flex;"><span>      }
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#ff7b72">public</span> studyGroup() {
</span></span><span style="display:flex;"><span>    <span style="color:#ff7b72">switch</span> (<span style="color:#ff7b72">this</span>.jobType) {
</span></span><span style="display:flex;"><span>      <span style="color:#ff7b72">case</span> Job.ENGINEER<span style="color:#ff7b72;font-weight:bold">:</span> {
</span></span><span style="display:flex;"><span>        console.log(<span style="color:#a5d6ff">&#34;程式讀書會&#34;</span>);
</span></span><span style="display:flex;"><span>        <span style="color:#ff7b72">break</span>;
</span></span><span style="display:flex;"><span>      }
</span></span><span style="display:flex;"><span>      <span style="color:#ff7b72">case</span> Job.DESIGNER<span style="color:#ff7b72;font-weight:bold">:</span> {
</span></span><span style="display:flex;"><span>        console.log(<span style="color:#a5d6ff">&#34;UI設計讀書會！&#34;</span>);
</span></span><span style="display:flex;"><span>        <span style="color:#ff7b72">break</span>;
</span></span><span style="display:flex;"><span>      }
</span></span><span style="display:flex;"><span>      <span style="color:#ff7b72">case</span> Job.LAWYER<span style="color:#ff7b72;font-weight:bold">:</span> {
</span></span><span style="display:flex;"><span>        console.log(<span style="color:#a5d6ff">&#34;法律讀書會&#34;</span>);
</span></span><span style="display:flex;"><span>        <span style="color:#ff7b72">break</span>;
</span></span><span style="display:flex;"><span>      }
</span></span><span style="display:flex;"><span>      <span style="color:#ff7b72">case</span> Job.MAGICIAN<span style="color:#ff7b72;font-weight:bold">:</span> {
</span></span><span style="display:flex;"><span>        console.log(<span style="color:#a5d6ff">&#34;魔術讀書會&#34;</span>);
</span></span><span style="display:flex;"><span>        <span style="color:#ff7b72">break</span>;
</span></span><span style="display:flex;"><span>      }
</span></span><span style="display:flex;"><span>      <span style="color:#ff7b72">case</span> Job.PAINTER<span style="color:#ff7b72;font-weight:bold">:</span> {
</span></span><span style="display:flex;"><span>        console.log(<span style="color:#a5d6ff">&#34;畫畫讀書會&#34;</span>);
</span></span><span style="display:flex;"><span>        <span style="color:#ff7b72">break</span>;
</span></span><span style="display:flex;"><span>      }
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p class="code-source">原始碼：<a href="https://gist.github.com/dean9703111/44adfd5e4a16fe329eba6558af647b9d" rel="noopener">worker-ugly-code.ts</a>（GitHub Gist）</p>
<p>我們現在才 5 個職業、3 個功能就把 Worker 這個 Class 搞的這麼冗長了，現在先來分析這個程式日後會遭遇的問題：</p>
<ol>
<li><strong>維護性</strong>：日後增加新的職業，需要在每個 switch 設計對應的 case；如果職業繁多，那產生 Bug 是完全可以預期的事情。</li>
<li><strong>可讀性</strong>：如果這個平台由多位工程師共同開發，那其他工程師使用到 Worker 這個 Class 時可能會很抖，因為無論閱讀理解還是改寫都很困難。</li>
<li><strong>擴充性</strong>：如果未來需要根據特定職業設計獨有的 Function（比如只允許工程師使用 Programing），那可能就要動到 Class 的結構了。</li>
</ol>
<hr>
<h2 id="五refactoring老闆我改不動了打算用繼承進行重構">五、[Refactoring]老闆…我改不動了，打算用繼承進行重構<a class="h-anchor" href="#%e4%ba%94refactoring%e8%80%81%e9%97%86%e6%88%91%e6%94%b9%e4%b8%8d%e5%8b%95%e4%ba%86%e6%89%93%e7%ae%97%e7%94%a8%e7%b9%bc%e6%89%bf%e9%80%b2%e8%a1%8c%e9%87%8d%e6%a7%8b" aria-label="這個段落的連結"></a></h2>
<p>既然我們已經體會到「新增職業」帶來的痛苦，不如先用繼承的概念重構，將「工作者（Worker）」設計為基礎類別（父類別）。</p>
<p>因為職位有「多樣性」，所以我們將 Worker 定義為「抽象類別（abstract class）」，並將「skill、skillExchange、studyGroup」這些功能抽象化，讓繼承的衍生類別（子類別）去實現。</p>
<div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-typescript" data-lang="typescript"><span style="display:flex;"><span><span style="color:#ff7b72">export</span> <span style="color:#ff7b72">abstract</span> <span style="color:#ff7b72">class</span> Worker {
</span></span><span style="display:flex;"><span>  <span style="color:#ff7b72">private</span> _name: <span style="color:#ff7b72">string</span>; <span style="color:#8b949e;font-style:italic">// 姓名
</span></span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#ff7b72">constructor</span>(theName: <span style="color:#ff7b72">string</span>) {
</span></span><span style="display:flex;"><span>    <span style="color:#ff7b72">this</span>._name <span style="color:#ff7b72;font-weight:bold">=</span> theName;
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#ff7b72">public</span> <span style="color:#ff7b72">get</span> name() {
</span></span><span style="display:flex;"><span>    <span style="color:#ff7b72">return</span> <span style="color:#ff7b72">this</span>._name;
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#ff7b72">public</span> <span style="color:#ff7b72">set</span> name(theName: <span style="color:#ff7b72">string</span>) {
</span></span><span style="display:flex;"><span>    <span style="color:#ff7b72">this</span>._name <span style="color:#ff7b72;font-weight:bold">=</span> theName;
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>  <span style="color:#ff7b72">abstract</span> introSkill()<span style="color:#ff7b72;font-weight:bold">:</span> <span style="color:#ff7b72">void</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#ff7b72">abstract</span> skillExchange()<span style="color:#ff7b72;font-weight:bold">:</span> <span style="color:#ff7b72">void</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#ff7b72">abstract</span> studyGroup()<span style="color:#ff7b72;font-weight:bold">:</span> <span style="color:#ff7b72">void</span>;
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p class="code-source">原始碼：<a href="https://gist.github.com/dean9703111/3daa4538e6869e1ef1a8fb0a1a960803" rel="noopener">woker-inheritance.ts</a>（GitHub Gist）</p>
<p>日後我們想新增一個職業時，只要讓他繼承「工作者（Worker）」的 Class，並實作抽象的功能即可；下面舉一個新增「工程師（Engineer）」這個職業的例子。</p>
<div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-typescript" data-lang="typescript"><span style="display:flex;"><span><span style="color:#ff7b72">class</span> Engineer <span style="color:#ff7b72">extends</span> Worker {
</span></span><span style="display:flex;"><span>  introSkill() {
</span></span><span style="display:flex;"><span>    console.log(<span style="color:#a5d6ff">&#34;我超會寫程式！&#34;</span>);
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  skillExchange() {
</span></span><span style="display:flex;"><span>    console.log(<span style="color:#a5d6ff">&#34;我想學程式！&#34;</span>);
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  studyGroup() {
</span></span><span style="display:flex;"><span>    console.log(<span style="color:#a5d6ff">&#34;程式讀書會&#34;</span>);
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ff7b72">let</span> engineer <span style="color:#ff7b72;font-weight:bold">=</span> <span style="color:#ff7b72">new</span> Engineer(<span style="color:#a5d6ff">&#34;Dean&#34;</span>);
</span></span><span style="display:flex;"><span>engineer.studyGroup();
</span></span></code></pre></div><p class="code-source">原始碼：<a href="https://gist.github.com/dean9703111/a7d4b0cec3577037451b155d83f21128" rel="noopener">engineer.ts</a>（GitHub Gist）</p>
<p>程式重構後，我們新增職業不但變得輕鬆，還大幅降低產生 Bug 的風險；因爲繼承 Worker 的 Class 後，會明確告訴你需要實作的功能有哪些（如果沒有實作就會報錯😅）。</p>
<hr>
<h2 id="六應用多型讓不同職業的工作者進行交流">六、應用多型讓不同職業的工作者進行交流<a class="h-anchor" href="#%e5%85%ad%e6%87%89%e7%94%a8%e5%a4%9a%e5%9e%8b%e8%ae%93%e4%b8%8d%e5%90%8c%e8%81%b7%e6%a5%ad%e7%9a%84%e5%b7%a5%e4%bd%9c%e8%80%85%e9%80%b2%e8%a1%8c%e4%ba%a4%e6%b5%81" aria-label="這個段落的連結"></a></h2>
<p>接著我們回到讓不同職業的工作者「介紹技能」的程式。</p>
<p>這次我們在陣列中塞了兩種職業（Engineer、Designer）；不過因為這些職業都是 Worker 的衍生類別，所以在 forEach 中我們可以用「Worker」進行解析，進而存取 Worker 所提供的方法（introSkill）。</p>
<div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-typescript" data-lang="typescript"><span style="display:flex;"><span><span style="color:#ff7b72">let</span> workers <span style="color:#ff7b72;font-weight:bold">=</span> [<span style="color:#ff7b72">new</span> Engineer(<span style="color:#a5d6ff">&#34;Dean&#34;</span>), <span style="color:#ff7b72">new</span> Designer(<span style="color:#a5d6ff">&#34;Amy&#34;</span>)];
</span></span><span style="display:flex;"><span>workers.forEach((worker: <span style="color:#ff7b72">Worker</span>) <span style="color:#ff7b72;font-weight:bold">=&gt;</span> {
</span></span><span style="display:flex;"><span>  console.log(worker.name);
</span></span><span style="display:flex;"><span>  worker.introSkill();
</span></span><span style="display:flex;"><span>});
</span></span></code></pre></div><p class="code-source">原始碼：<a href="https://gist.github.com/dean9703111/17b1efe18be6402d4d88f70a299acf3a" rel="noopener">worker-polymorphism.ts</a>（GitHub Gist）</p>
<p><strong>備註 1</strong>：如果今天我們在工程師（Engineer）的 Class 新增 programming 的方法，那這個方法在 forEach 裡面是無法使用的（因為裡面僅允許 Worker 的方法）。<br><strong>備註 2</strong>：如果我們今天在陣列中增加一個並非 Worker 的衍生類別（ex：new Animal()），那 forEach 會因為偵測到你放了非 Worker 的衍生類別而報錯。</p>
<hr>
<h2 id="七所以多型polymorphism繼承inheritance的概念幫我們解決了什麼問題">七、所以「多型(Polymorphism)＆繼承(Inheritance)」的概念幫我們解決了什麼問題？<a class="h-anchor" href="#%e4%b8%83%e6%89%80%e4%bb%a5%e5%a4%9a%e5%9e%8bpolymorphism%e7%b9%bc%e6%89%bfinheritance%e7%9a%84%e6%a6%82%e5%bf%b5%e5%b9%ab%e6%88%91%e5%80%91%e8%a7%a3%e6%b1%ba%e4%ba%86%e4%bb%80%e9%ba%bc%e5%95%8f%e9%a1%8c" aria-label="這個段落的連結"></a></h2>
<p>這邊筆者就分享自己使用下來最直觀的感受：</p>
<ol>
<li>繼承的概念讓我們的程式可以被重複使用。</li>
<li>多形的概念幫我們把功能抽象化，根據實際的需求去執行。</li>
</ol>
<hr>
<p><strong>參考資源</strong>：<a href="https://www.youtube.com/watch?v=FkgLc5gFPAU&amp;list=PLicQRHHL75d7RG_kfnEFAEnBouLncvwQp&amp;ab_channel=%E6%B0%B4%E7%90%83%E6%BD%98">Java物件導向 重觀念迅速教學 3 Polymorphism 什麼是繼承? 什麼是多型？為何多型以及如何設計多型？</a></p>
<pre tabindex="0"><code>▶︎ 用 TypeScript 學物件導向
▋ 封裝(Encapsulation)能解決什麼問題？
▋ 多型(Polymorphism)＆繼承(Inheritance)能解決什麼問題？(本篇)
</code></pre>]]></content:encoded>
    </item>
  </channel>
</rss>
