web-dev-qa-db-ja.com

クラスのインスタンスから静的メソッドを呼び出す

開発者として、私は静的メソッドのファンです。

最近、私はこの静的メソッドについてOOP言語間の違いに遭遇しました。

すべてOOP言語は静的メソッドを使用して、クラスのインスタンスを作成せずに任意のメソッドにアクセスするため、クラス名だけでこの種のメソッドを呼び出すことができます。

しかし、一部の言語ではJavaのようにインスタンス変数から静的メソッドにアクセスできます。一部の言語ではObjective-Cが好きではありません。

では、この2つのOOP言語の違いの理由は何ですか?どちらが正しいのですかOOP動作?私はこれを知りたいだけです。

4
CRDave

静的メソッドは、コアでOOPとは関係ありません。Javaにクラスのインスタンスがなかった場合、これは モジュール式プログラミング クラスはモジュールであり、静的メソッドは通常の手続きです。

JavaとObjective-Cのここで関連する違いは、後者がSmalltalkのような metaobject protocol :クラス自体は通常のオブジェクトです。fooオブジェクトは、FooClassのインスタンスである場合があります。これは、最終的にNSObjectのインスタンス(!=サブクラス)になります。クラスでメソッドを呼び出すと、このメッセージがそのクラスを表す実際のオブジェクト。Javaでは、静的メソッドの呼び出しはオブジェクトをまったく含まず、単なるプロシージャコールです(実行前に完全に解決できます。 動的ディスパッチ は必要ありません)。

Javaでは、クラスはリフレクションを超えて 具体化 ではありません。したがって、instance.staticMethod()は意味がありません。他の意味がないためです(たまたま通常のメソッド呼び出しの構文を共有するだけですが、静的メソッドはinstanceの静的タイプに従ってのみ検索されます変数:

class Super {
    public static void staticMethod() { return; }
}
class Instance extends Super {
}

Instance instance = new Instance();
instance.staticMethod();  // doesn't work
((Super) instance).staticMethod(); // works with cast

Objective-Cにはそのような「静的メソッド」はありませんが、次の機能があります。

  • クラスメソッド、目を細めれば静的メソッドに似ています。インスタンスのメソッド呼び出しが最終的にクラス(すべてのオブジェクト)のメソッド呼び出しになると非常に混乱するので、[instance staticMethod]のような構文上のショートカットはありません。 [[instance class] staticMethod]。このようなクラスメソッドは、コンストラクタやその他のファクトリメソッドに適しています。ただし、継承の対象となるため、「静的」ではありません。

  • 旧式C関数これらはオブジェクトやクラスの外部に存在し、動的ディスパッチの対象ではありません。これは、パフォーマンスの観点からも興味深いものです。これらは、その言葉の実際の意味では「静的」ですが、「方法」ではありません。

8
amon