web-dev-qa-db-ja.com

PHPでの仮想関数の正しい実装?

私の職場(phpのみ)には、データベース抽象化の基本クラスがあります。新しいデータベーステーブルをベースレイヤーに追加する場合は、この基本クラスのサブクラスを作成し、いくつかのメソッドをオーバーライドして、このテーブルを使用するための個々の動作を定義する必要があります。通常の動作は同じままである必要があります。

今、私は私たちの会社で多くの新しいプログラマーを見てきました。彼らはデフォルトの振る舞いのためにメソッドをオーバーライドするだけです。すべてのデフォルトの動作を入れて、好きな場所に個別のものを追加するのにとても「いい」ものもあれば、ベースクラスとその継承を使用しようとして自殺するものもあります。

この問題を解決するための私の最初の考えは、クラスを継承することによってオーバーライドされるべき抽象メソッドについて考えることでした。しかし、抽象メソッドに対する他の引数のほかに、「abstract」は表示されませんwhyベースクラスを単独で使用することはできません。whyこれらの関数はオーバーライドする必要があります。

少し調べてみたところ、phpに「実際の」仮想関数を実装するための良い答えは見つかりませんでした(仮想関数があるだけで、具体的な実装のすべての希望がほぼ失われます)。

それで、あなたはこの問題で何をしますか?

22
erikbwork

PHPすべてのpublicおよびprotected関数は「仮想」です。 finalキーワードを前に付けることによってオーバーライドされます(またはそれらをプライベートにすることによって、しかしこれはおそらく悪い考えです)。

基本クラスの設計では、サブクラスが影響を与えたい動作について考えます。たとえば、before_update()やafter_insert()のような空の関数を作成します。

function after_insert() {
  // Virtual
}

更新/挿入イベントが発生したときに基本クラスが呼び出すもの。

たぶん、ベースクラスで常にtrueを返すis_valid()関数であり、コメントブロックを使用して、サブクラスがfalseを返したときの結果を説明します。

うまくいけば、これはあなたにいくつかのインスピレーションを与えるでしょう。

33
Bob Fanger

いつでも「final」キーワードを使用して、ユーザーがクラスを間違った方法で使用している場合に一部のクラス関数がオーバーライドされないようにすることができます。

特定の機能を実現できないため、メソッドをオーバーライドしているように思えます。クラスのデザインを確認する必要があるかもしれません。

4
Rob