はじめに
こちらの記事で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ならインターフェースの切りやすさがますのがいいですね!
最後に
インターフェースクラスっていいよね!