8
3

More than 5 years have passed since last update.

インスタンスメソッドと同名のクラスメソッド

Posted at

Rubyで普通に使っていた(というより標準ライブラリにすらArray.[]Array#[]がまったく別目的で定義してあるぐらいの)「インスタンスメソッドと同名のクラスメソッドを作ること」ですが、言語によってできるできないが分かれることに気づきました。

できない言語

PHP

はじめはPHPで似たようなことをやろうとして、行き詰まったところでQiitaの記事にたどり着きました。結局、クラスメソッドもインスタンスメソッドも「同じクラスで定義されるメソッド」なので同名にはできない、ということでした(両方をマジックメソッドで対応するなら別ですが)。

C++

PHPでできなかったところで、C++でも試してみました。

class Foo
{
public:
    void hoge() {}

    static void hoge() {}
};

int main()
{
    return 0;
}

上のプログラムは、コンパイルしただけで

test.cpp:11:17: error: 'static void Foo::hoge()' cannot be overloaded
test.cpp:6:10: error: with 'void Foo::hoge()'

と、エラーになってしまいました。

Java

同じようなことをpaiza.ioでJavaについてもやってみましたが、やはり「error: method foo() is already defined in class Hoge」とのことでした。

まとめ

クラスメソッドを「そのクラスに属するstaticなメソッド」とする言語では、staticでないものと同じ名前(と、言語によってはシグネチャ)だと衝突してしまう、という感じでした。

できる言語

Ruby

Rubyの場合、「クラスメソッド」=「(何らかの方法で)クラスオブジェクトに生やすメソッド」なので、インスタンスのメソッドとはそもそも別系統になります。

TypeScript

となると、「クラス」がオブジェクトとして存在しているTypeScriptだとどうなるだろう、と気になって試してみることにしました。

シンタックスハイライトはJavaScriptモード
// TypeScript
class Test{
    foo() { }

    static foo() {  }
}

// JavaScriptへの翻訳後
var Test = (function () {
    function Test() {
    }
    Test.prototype.foo = function () { };
    Test.foo = function () { };
    return Test;
}());

と、「クラスメソッド=オブジェクト自身に生えるメソッド」「インスタンスメソッド=prototypeのメソッド」ということがはっきりしています。

8
3
1

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
8
3