クラス変数をプライベートにすることとパブリックにすることの利点を理解しようとしています。ゲッター/セッターがプライベート/保護されたデータにアクセス/変更することを理解していますが、その唯一の目的は「自分のデータを壊さないようにする」ことですか? 例:言い方がわかりません
$person->age = x;//bad?
とは異なる大混乱の可能性を秘めている
$person->set_x(x);//reccommended in OOP articles
クラス変数をプライベートにすることとパブリックにすることの利点を理解しようとしています。ゲッター/セッターがプライベート/保護されたデータにアクセス/変更することを理解していますが、その唯一の目的は「自分のデータを壊さないようにする」ことですか? 例:言い方がわかりません
$person->age = x;//bad?
とは異なる大混乱の可能性を秘めている
$person->set_x(x);//reccommended in OOP articles
それはすべてカプセル化に関するものです。
を使用するとします$person->age = x
。今のところは問題なく動作します。100 か所にその行があるとしましょう。後でage
、たとえば 0 より大きい数値に制限する必要があることがわかります。メンバー変数に直接アクセスする場合、その制限を簡単に適用する方法はありません。
$person->set_age(x)
しかし、最初にそれらの 100 か所で書いたとしましょう。これで、セッターを次から変更できます
private $_age;
public void age($new_age) {
$this->_age = $new_age;
}
に
private $_age;
public void age($new_age) {
if ($new_age > 0) {
$this->_age = $new_age;
}
}
set_age メソッドの単一のコンシューマーに触れる必要はありません。変更は「うまくいく」。これが OOP の本当の利点です。1 つのメソッド呼び出しの背後に多くの実装の詳細を隠すことができます。
カプセル化は他の場所でも役立ちます。たとえば、年齢の変化をすべて記録する Person のサブクラスが必要だとします。セッター メソッドを使用すると、オーバーライドと同じくらい簡単です。直接変数にアクセスすると、混乱します。
アクセサー (setter / getter メソッド、またはそれらをサポートする言語 (C# など) のプロパティを使用すること) を提供することにより、開発者は、クラスとそのユーザーの間でより安定したコントラクトを定義できます。実際にメモリ位置を読み書きすることによってフィールドに直接アクセスする代わりに、ユーザーはメソッドを呼び出すことを余儀なくされ、それによって必要なロジックをカプセル化できます。
同様に、クラスの内部設計を変更する場合、そのコントラクトを変更する頻度を減らす必要があります。したがって、コードの保守性と安定性が向上します。
最新の JIT コンパイラは、実際の呼び出しが排除され、コードが基になるメモリ位置への直接アクセスと同等になるように、単純なゲッター/セッターへの呼び出しを最適化できるため、パフォーマンスは問題ではないことに注意してください。
編集:
また、setter と getter は通常、異なる可視性 (public / protected / private) を持っている場合があり、指定された値に対する読み取り / 書き込み操作をより細かく制御できるという利点が追加されます。
したがって、ベスト プラクティスは、可能な限り public フィールドを避け、代わりに setter / getter メソッドまたはプロパティを使用することです。
あなたがそれを壊したり、他の人がそれを壊したりしないようにし、非公開のメンバーは他の人が見るべきものの一部ではないという考えを表現して、カプセル化を達成します。
値を直接変更すると、コードに有害などの問題が発生する可能性があるため、set/get メソッドは属性をより適切に保証するのに役立つと思います。set/get は、属性を直接操作するのではなく、ユーザーが呼び出すメソッドを提供すると思います。