📚

抽象クラスについて3分で理解する

2022/12/11に公開

概要

abstractやprotectedなどが出てきて?となったので物凄いシンプルなコードで理解できるようにまとめてみました。

抽象クラス (abstract class)とは?

abstractは抽象クラスを作成する時に宣言します。
抽象クラスとは直接インスタンス化(new)することができず、必ずスーパークラスとして利用することを保証するものです。
抽象クラス内のメソッドにもabstract宣言を行うことができます。

引用元: サバイバルTypeScript
上記解説通りなのですが、今回はこれについて深掘りしたいと思います。

サンプルコード

sample1.ts
abstract class Parent {
  protected abstract name: string;
  protected abstract age: number;
}
// Cannot create an instance of an abstract class
const user = new Parent({name: bob, age: 30})

「抽象クラスのインスタンスを作成できません」と言われてしまったので新しい継承クラスを作りたいと思います。

sample2.ts
abstract class Parent {
  protected abstract name: string;
  protected abstract age: number;
}

// Non-abstract class 'Children' does not implement inherited abstract member 'age' from class 'Parent'.
class Children extends Parent {
  public name = 'bob';
}

const user = new Children()
console.log(user)

上記のエラーを見ると「非抽象クラス 'Children' は、クラス 'Parent' から継承された抽象メンバー 'age' を実装していません。」と言われてますね。言葉通りなのでageを追加してみます。

sample3.ts
abstract class Parent{
  protected abstract name: string;
  protected abstract age: number;
}


class Children extends Parent {
  public name = 'bob';
  public age = 30;
}

const user = new Children()
// 30
console.log(user.age)

表示されました。これで解決なのですが、Childrenクラスのpublicをprotectedしたらどうなるのでしょうか・・・?

sample4.ts
abstract class Parent {
  protected abstract name: string;
  protected abstract age: number;
}


class Children extends Parent {
  protected name = 'bob';
  protected age = 30;
}

const user = new Children()
// Property 'age' is protected and only accessible within class 'Children' and its subclasses.
console.log(user.age)

「プロパティ 'age' は保護されており、クラス 'Children' とそのサブクラス内でのみアクセスできます。」とのことらしいです。
(サブクラスとは継承先のクラスのこと)
つまりChildrenやParentのカッコ外ではアクセスできないということですね。色々解決方法はあると思いますが、一番簡単なのは下記の方法ですね

sample5.ts
abstract class Parent {
  protected abstract name: string;
  protected abstract age: number;
}


class Children extends Parent {
  protected name = 'bob';
  protected age = 30;

  public getAge(): number{
    return this.age
  }
}

const user = new Children()
// 30
console.log(user.getAge())

Parentクラスに関数を追加するという手段もできます

sample6.ts
abstract class Parent {
  protected abstract name: string;
  protected abstract age: number;

  public getAge(): number{
    return this.age
  }
}


class Children extends Parent {
  protected name = 'bob';
  protected age = 30;
}

const user = new Children()
// 30
console.log(user.getAge())

抽象クラスって言われると少し難しいように感じますが、短いコードで色々試してみるとちょっとはわかった気がします!

Discussion