LoginSignup
26
16

More than 1 year has passed since last update.

Rubyでインターフェースクラスを実現する

Last updated at Posted at 2019-03-10

はじめに

こちらの記事でRubyのインターフェースクラスについて触れていたところ、@yuukive さんよりアドバイスいただいたので記事化。
ありがとうございます!

インターフェースクラスを実現する

定義

例えばencodeというメソッドを持つインターフェースクラスEncoderIFを実現したいとします。
ここで使えるのがNotImplementedErrorというクラス。こんな感じで定義してあげます。

EncoderIF.rb
class EncoderIF
  def encode
    raise NotImplementedError.new("#{self.class}##{__method__} が実装されていません")
    #FFmpeg等、エンコーダーに合わせた処理を実装する。
  end
end

継承先の実装

後は普通に継承してメソッドを実装すればOKです。ここで、うっかりencodeの実装を忘れたりすると、

EncoderIFFailed.rb
$LOAD_PATH.push("./")
require 'EncoderIF'
class EncoderIFFailed < EncoderIF
end

実行時にエラーを返してくれます。

$ ruby Main.rb
Traceback (most recent call last):
        1: from Main.rb:5:in `<main>'
/home/XXX/EncoderIF.rb:3:in `encode': EncoderIFFailed#encode が実装されていません (NotImplementedError)

もちろんencodeメソッドを実装すれば正しく動作するようになります。

EncoderIFSuccess.rb
$LOAD_PATH.push("./")
require 'EncoderIF'
class EncoderIFSuccess < EncoderIF
  def encode()
    puts("実装しました")
  end
end
$ ruby Main.rb
実装しました

更にもういっちょ

@tommy_aka_jps さんよりいただいたコメントの反映です。
Rubyの継承だと多重継承が厳しいので、moduleのincludeで代用する方法の提案です。

EncoderIF.rb
# module
module EncoderIF
  def encode
    raise NotImplementedError.new("#{self.class}##{__method__} が実装されていません")
  end
end

# class
class EncoderIFSuccess
  include EncoderIF

  def encode
    p '実装しますた'
  end
end

# main
EncoderIFSuccess.new.encode

多重継承がOKならインターフェースの切りやすさがますのがいいですね!

最後に

インターフェースクラスっていいよね!

26
16
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
26
16