web-dev-qa-db-ja.com

静的メンバーが抽象化できず、ポリモーフィズムを実装できないのはなぜですか?

私はJava/C#/ PHP開発者です。私のOOPプログラミング経験を通じて、私は同じ質問をしていることに気づきます:なぜ静的メンバーは抽象的で実装できないのですかポリモーフィズム特にファクトリメソッドを含む状況では、例えば:

abstract class Resource {
    public void doSomething();
}

abstract class User<resource extends Resource> {

    //if i want to instantiate resource, 
    //my only option here is to create an abstract factory in user class
    protected abstract resource create();

    public void use(){
        create().doSomething();
    }

}

class FileUser extends User<File> {

    //It's a bit clumsy, isn't it?
    @Override
    protected Internet create() {
        return new File();
    }

}

抽象静的メソッドがこれらの抽象ファクトリを取り除く場合:(以下は有効なコードではありません)

abstract class Resource {
    public void doSomething();
    //Im not sure how the child class would get passed though
    static abstract Resource create();
}

abstract class User<resource extends Resource> {

    public void use(){
        resource.create().doSomething();
    }

}

それで、なぜこの種の振る舞いがOOPで承認されないのか誰か知っていますか?ばかげた質問のように聞こえる場合は申し訳ありません。

1
Ben

静的メソッドはオブジェクト指向プログラミングの一部ではなく、実際には名前空間関数です。このように考えてみてください。abstractメソッドを使用すること、またはpolymorphic動作を使用することはどういう意味ですか?

これは、次のことができることを意味します。

function connectToDB(/*string */ $dsn, /* string */ $user, /*string*/ $password, /*Logger*/ $logger) {
    $pdo = new PDO($dsn, $user, $password);
    //This is polymorphic, you can pass any object that implements the Logger
    //interface, without exposing to this function what logging mechanism is used.
    $logger->log('Connected to database!'); 
}

静的メソッドでこれをどのように行いますか?静的メソッドは呼び出しにクラス名を含めます。必要な任意のロガーを(合理的に)渡すことはできず、その上でlog静的メソッドを使用します。

同じことが抽象にも当てはまります。抽象静的メソッドには意味がありません。

3
Madara's Ghost

私は前述の言語のいずれの専門家でもありませんが、Java docsをざっと読んで、それらがすべて同じように動作するという暗黙の主張から、すべてが使用していることを理解することができます。 C++と同じ方法で静的:

静的メソッド/変数/何でもクラスレベルのものであり、オブジェクトレベルのものではありません。静的メソッドを呼び出すか、静的変数にアクセスするには、静的メンバーにアクセスするクラスを(暗黙的または明示的に)指定する必要があります。そして、そのクラスのタイプのオブジェクトを作成することなく、それを行うことができます。

オブジェクトがない場合、これらの言語に存在するような多態性はありません。これらの言語はすべて、オブジェクトの実際のタイプに基づいてポリモーフィズムを実行するため、意味がありません。オブジェクトもポリモーフィズムもありません。

2
Michael Kohne

オブジェクト指向と呼ばれる現在のプログラミングモデルがあり、その中心にはオブジェクトがあります。

さまざまな種類のポリモーフィズムがサポートされていますが、それについて議論する人もいます。しかし、主な種類で最も強力なのは、ターゲットオブジェクトの実際のタイプによって実装されるメソッドへのメソッド呼び出しの動的バインディングです。

言語が異なれば、これに対するサポートのレベルも異なります。 Smalltalkのように、メソッドがターゲットクラスに実装されることを保証しないものもあるため、実行時に「メッセージが見つかりません」エラーが発生する可能性があります(Smalltalkはメソッドmessages、大まかに言えば)。 C++やJavaのような他の強く型付けされた言語には構文規則があり、コードが正しくコンパイルされた後、メソッド呼び出しがどこかになることをコンパイラーが保証できます。適切な。

だからあなたはcouldあなたが望むようなことが起こり得る言語を作ることができます。 JavaまたはC++ではありません。言語定義で機能するようにコードが常に定義どおりに機能するように、すべてのコーナーケースを検討する必要があります。 Java仕様 これをどれほど注意深く行う必要があるかを理解する。

新しい言語の代わりに多くの人々が着く解決策はデザインパターンです。 OO Design および Wikipedia を参照してください。デザインパターンは、一般的な問題に対する一般的なソリューションを提供し、ソリューションの一般的な語彙を提供します。

あなたはいつも「もしいいなら…」というケースに出くわすでしょう-そして、非常に多くの人々が、存在する多数のオープンソースフレームワークなどのソリューションを生み出しています。新しいコンパイル言語と比較して、フレームワークは比較的簡単に作成および配布できます。

では、なぜ静的メンバーを抽象化できず、ポリモーフィズムを実装できないのでしょうか。 object指向ではなく、それを行う言語を設計しているためand人々にそれを受け入れて使わせるのは難しいです。

0
andy256