Nobiq
Nobiq

継承とインターフェース

共通部分を親にまとめ、子が引き継ぐ

自動販売機にはいろいろな種類があります——ジュース用、お菓子用、切符用。でも「お金を受け取る」「商品を出す」という基本は共通です。共通部分を親の設計図にまとめ、子がそれを引き継いで拡張する。これが今回の継承です。

継承 = 設計図の引き継ぎ

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

contract Machine {
    function greet() public pure virtual returns (string memory) {
        return "I am a machine";
    }
}

contract AutoVending is Machine {
    function greet() public pure override returns (string memory) {
        return "I am a vending machine!";
    }
}

新しい言葉は 3 つだけです。

  • iscontract AutoVending is Machine = 「AutoVending は Machine の設計図を引き継ぐ」。Machine を、AutoVending をと呼びます。子は、親に書いてある変数や関数を自分で書かなくても持っています
  • virtual — 親側の印。「この関数は、子が書き換えてもよい」という許可です
  • override — 子側の印。「親の関数を、わたし流に書き換えます」という宣言です

greetvirtual(親)と override(子)が付いているので、AutoVending の greet() を呼ぶと、子の答え "I am a vending machine!" が返ります。親が許可し、子が宣言する——両方そろって初めて書き換えられる、安全設計です。

なお returns (string memory)memory は前回やった「データの置き場所」です。string を返すときは付ける、でしたね。

インターフェース = 中身のないボタン一覧

interface(インターフェース)は、「このボタンがあります」という一覧表だけを定めたものです。中身(手順)は書けません。

interface IVending {
    function buy() external;
    function getPrice() external view returns (uint256);
}
  • 名前は慣習で I から始めます(IVending = Vending の一覧表)
  • 関数は external(外から使う前提)で、中身なしの ; 止め
  • コントラクトが contract MyMachine is IVending { ... } と名乗ったら、一覧表にあるボタンを全部実装する義務が生じます

「なんの役に立つの?」——他人のコントラクトと会話するときの共通の窓口になります。相手の中身を知らなくても、一覧表さえ合っていれば呼び出せる。実際の開発では、トークン(ERC-20 など)の世界標準がこの interface で定義されています。今は「そういう約束ごとの道具がある」とわかれば十分です。

:::note interface は読むだけで OK この例を Lab のファイルに足してコンパイルすると、エラーになることがあります(interface には実行の中身がないため、Lab がデプロイ対象に interface を選んでしまうと失敗します)。今回は写さず、目で読んで「一覧表なんだな」とわかれば十分です。 :::

今回覚えたこと

  • is = 設計図の引き継ぎ(継承)。子は親の変数・関数をそのまま持つ
  • virtual(親: 書き換え許可)と override(子: 書き換え宣言)はセット
  • interface = 中身のないボタン一覧表。名乗ったら全部実装する義務

次回は、第4回で覚えた require の仲間たち——エラー処理をまとめて学びます。

:::tip Lab でやってみる 上の継承コードをそのままコンパイル→デプロイしてみましょう。1 つのファイルに contract を複数書いたとき、Lab では名前のアルファベット順で最初のものがデプロイされます(この例では AutoVending が Machine より先)。実行画面で greet() を呼ぶと、子の答え "I am a vending machine!" が返ってくるはずです。override の中の文字列を変えて再デプロイすれば、答えが変わることも確かめられます。操作方法: コントラクトを動かす :::