LoginSignup
13
11

More than 5 years have passed since last update.

Goのinterfaceと他の言語(Swift/ObjC/Java/PHP)での(明示的)実装方法

Last updated at Posted at 2015-02-14

Goではインターフェース型で実装された関数を全て実装すれば、その型で振舞うことができます。

ダック・タイピングなアプローチができるので、これが扱えるのと扱えないのではコードに差が出てくるなと感じます。

一旦慣れてしまえば簡単に使えるのですが、わからない人向けに感覚値として掴んでもらえればと思って明示的な方法でインターフェースの実装を他の言語に置き換えています。

Goのファイルに関して、今回はインターフェースを埋め込んでいるため、仮にSounds関数を実装していなくてもビルドが通ります。

ですが、もちろんのこと実装していないため、ランタイムエラーとなります。

そこの違いもいろいろ触ってもらえればと。(ビルドエラーかランタイムエラーか、実装変えるとどうなるかなどなど)

一部だけ解説します。

Goでは宣言したinterfaceの実装さえされていれば、その型で振舞われるため、わざわざインターフェースを埋め込まなくてもよいです。
よくわからないければ、作り手の意思としてチョイスする感じでよいかと。(適当)

package main

import "fmt"

type Animal interface {
    sounds() string
}

type Cat struct {
    Animal
    Name string
}

func (c Cat) sounds() string {
    return "Meow"
}

func call(a Animal) {
    fmt.Println(a.sounds())
}

func main() {
    cat := Cat{Name: "NyanCat"}
    call(cat)
}

Swiftのprotocolでは、Objective-C時代にあった@optionalにあたるものがなくなりました。

そのため、protocol実装されたオブジェクトに関して必ず実装する必要があるため、ランタイムエラーとなり得る実装は無理な気がしました。柔軟ではないですね。(さすが堅牢をうたっているだけある(褒めてます。褒めてます。


protocol Animal {
    func sounds() -> String
}

struct Cat: Animal {
    var name: String

    init(name: String) {
        self.name = name
    }

    func sounds() -> String {
        return "Meow"
    }
}

func call(a : Animal) {
    println(a.sounds())
}

func main() {
    var cat = Cat(name: "NyanCat")
    call(cat)
}

main()

Objective-Cには@optionalがあるため、- (NSString *)sounds;を実装しなくてもビルドが通ります。
が、もちろんメソッドがない場合はランタイムエラーとなります。

#import <Foundation/Foundation.h>

@protocol Animal
@optional
- (NSString *)sounds;
@end

@interface Cat : NSObject <Animal>
@property (nonatomic, strong) NSString *name;
@end

@implementation Cat
- (NSString *)sounds {
    return @"Meow";
}
@end

void call(NSObject<Animal> *a) {
    printf("%s\n", [[a sounds] UTF8String]);
}

int main(int argc, char *argv[])
{
    Cat *cat = [Cat new];
    cat.name = @"NyanCat";
    call(cat);
    return 0;
}
13
11
0

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
13
11