关於继承

什麽是继承

In object-oriented programming, inheritance is the mechanism of basing an object or class upon another object (prototype-based inheritance) or class (class-based inheritance), retaining similar implementation. Also defined as deriving new classes (sub classes) from existing ones such as super class or base class and then forming them into a hierarchy of classes.

在物件导向程序语言当中,「继承」是一种机制,可以保留某个类别或物件的实作方法。奠基在既有类别上创立一个新的类别,并建立阶层的关系。

In most class-based object-oriented languages, an object created through inheritance, a "child object", acquires all the properties and behaviors of the "parent object"
...
Inheritance allows programmers to create classes that are built upon existing classes, to specify a new implementation while maintaining the same behaviors (realizing an interface), to reuse code and to independently extend original software via public classes and interfaces. The relationships of objects or classes through inheritance give rise to a directed graph.

child 物件继承 parent 物件时,可以

  • 获得了 parent 物件的所有属性和方法
  • 用新的方式实现、但同时维持继承而来的 parent 物件的原有行为
  • 重复使用或延伸原有的程序码

拿先前提到的例子来看,并做一些延伸如下:

class BaseballPlayer {
  name: string

  constructor(name: string) {
    this.name = name
  }

  hit() {
    console.log(`${this.name} can hit`)
  }

  run() {
    console.log(`${this.name} can run`)
  }
}

class Shortstop extends BaseballPlayer {
  run() {
    console.log(`${this.name} can run very fast`)
  }
  
  defense() {
    console.log(`${this.name} can defense`)
  }
}
const jeter = new Shortstop('jeter')

jeter.name         // jeter
jeter.hit()        // jeter can hit
jeter.defense()    // jeter can can defense
jeter.run()        // jeter can run very fast

可以看到

  • Shortstop 类别继承了 BaseballPlayer 类别
  • Shortstop 类别的实例 jeter,拥有其 parent 类别的
    • name 属性
    • hit 方法,并维持同样的实作方式
    • run 方法,但使用了新的实作方式
  • Shortstop 类别的实例 jeter 拥有新的 defense 方法

为什麽要继承

其实「抽象」和「继承」是一体两面。当我们不断的将「许多类别」的共同特质抽出、变成更高一层的 parent 类别的时候(抽象),这时候「许多类别」就是继承了这个 parent 类别,也就是继承了这个共同特质。

在能够继承的情况下,因为可以直接使用 parent 类别、parent's parent 类别 ... 等的属性和方法,因此 child 类别来说,可以不需要重复撰写同样的程序码。另一方面,「继承」也建立了物件之间彼此的阶层关系,让我们能够更快速的模拟真实世界事物的关系。

虽然「继承」看起还有许多好处,不过「继承」的缺点是,parent 类别和 child 类别有高度的关联性,换个角度来说,就是难以根据新的需求或变化进行扩充。

譬如「人」这个类别只会在地上跑,不会在天上飞。如果今天我们想要建立一个超人的实例,那麽究竟是要让「超人」类别去继承「人」呢,还是继承「鸟」类别呢?在这样的情况下,先前所提到过抽象了另外一种实现方式「介面」就可以派上用场了!

class Human {
  name: string

  constructor(name: string) {
    this.name = name
  }

  run(): void {
    console.log(`${this.name} can run`)
  }
}

interface Fly {
  fly(): void;
}

class Superman extends Human implements Fly {
  fly(): void {
     console.log(`${this.name} can fly`)
  }
}

const clark = new Superman('clark')
clark.run()                          // clark can run
clark.fly()                          // clark can fly

<<:  Day23:安全性和演算法-混成密码系统(Hybrid Cryptosystem)

>>:  Rust-结构体(Struct)

系统分析师养成之路—商业思维(外师分享)补充

关於系统分析师、专案经理、商业分析师⋯这些IT角色来说,「商业思维」真的太重要!所以除了跟大家分享我...

深度学习训练集问题

小弟是深度学习方面新手 最近想试试图像辨识但遇到了难题 我想辨认的三种东西分别是lad, lcx, ...

Day 08 Create a classification model with Azure Machine Learning designer

Classification - Predict category or class Train r...

DAY24-资讯卡页面设计

前言: 昨天我们介绍了一个普通的资讯页面是如何完成的,今天我们要来介绍另一个很常用到的页面种类,资...

自主学习Android_APP开发 #纪录1

纪录时间:2022/04/16 【前言】 在现在,每人基本都有属於自己的一只智慧型手机,各式各样的A...