4

良い一日!

カプセル化に関する Java の本を読んでいて、getter メソッドと setter メソッドについて言及されています。

属性を非表示にするには、インスタンス変数を「PRIVATE」としてマークし、データにアクセスするための「PUBLIC」メソッドを作成する必要があることを読みました。getter and setterそこで、次のように、従来のコードではなく、同様のコードを作成してみました。

public class AddressBookEntry {

    private String name;
    private String address;
    private String telNo;
    private String email;

    public void getAllInfo() {
        name = JOptionPane.showInputDialog("Enter Name: ");
        address = JOptionPane.showInputDialog("Enter Address: ");
        telNo = JOptionPane.showInputDialog("Enter Tel. No: ");
        email = JOptionPane.showInputDialog("Enter Email Address: ");
    }
}

上記のコードは、変数を直接割り当てたために変数を公開していますか? どうすればこれを改善できますか?代わりに従来のgetter and setterメソッドを作成し、他のクラスに値を割り当てた方がよいでしょうか? 「データを隠す」とはどういう意味ですか?

ありがとうございました。

4

6 に答える 6

7

セッターとゲッターを使用して、クラスの外部から変数にアクセスできるようにします。あなたの例では、

public class AddressBookEntry {

    private String name;

    public void setName(String name) {
       this.name = name;
    }

    public String getName() {
       return name;
    }
}

UIクラスからnameプロパティにアクセスします(同じクラスにUIとビジネスロジックを混在させるのは適切ではありません)。

public class MyPane extends JFrame {

  public getAllData() {
     String name = JOptionPane.showInputDialog("Enter Name: ");
     AddressBookEntry entry = new AddressBookEntry();
     entry.setName(name);
     // You can't use entry.name = name
  }

}
于 2011-02-18T06:39:43.487 に答える
5

はいといいえ。カプセル化のポイントは、クラスが舞台裏で何をしているのかを他のクラスが知る必要がないようにすることです。name(ここで行ったように)に保存する場合、ファイルから読み取り/書き込みを行う場合、または別のことを行う場合、カプセル化のポイントは、クラスのユーザーにとっては、表示されるのはすべてStringあるため、問題ではないということです。および。String getName( )void setName (String name)

ここでは、データの変更は完全にクラスの制御下にあるため、カプセル化が中断されることはありません。ファイルに保存した場合、クラスの他のユーザーが賢くなくても、保存nameできる可能性があります。クラスの外部getAllInfoからの観察可能な動作は、クラスの内部が行っていることをまだ隠しているため、カプセル化されたままです。

とはいえ、これは非常に型破りなアプローチです。最初の段落で説明したように、アクセサーメソッド(ゲッターとセッター)の使用は、より慣用的なアプローチであり、コードを使用している他の人にとっては理解しやすいものです。あなたはあなたがすることをすることができます、それはカプセル化を壊しません、しかしそれは私がエレガントまたは典型と呼ぶものではありません。

于 2011-02-18T06:38:35.090 に答える
3

プライベートクラスメンバー(属性、フィールド)の考え方は、宣言しているクラス(インスタンスではありません!)内でのみそれらに直接アクセスすることです。他のすべてのクラスは、getterメソッドやsetterメソッドなどの他のアクセサーを使用する必要があります。したがって、名前、アドレス、telNo、および電子メールの値を格納する方法は、クラス内に完全に隠されています。AdressBookEntry

ゲッターやセッターを使用する必要はありません、クラス内でも使用するのには十分な理由がある場合があります。値が設定される前にロギングまたは検証を行う場合は、ゲッターとセッターを使用することが理にかなっている場合があります。

于 2011-02-18T06:37:45.583 に答える
1

私は提供されたすべての素晴らしい答えに同意します。カプセル化を使用することについてもう1つの大きな利点を追加したいと思います。これは、クライアントからデータを非表示にすることで(上記の例のように)、これらのインスタンス変数を設定および取得する方法を保証できるため、クラスの保守とテストが容易になることです。 (つまり、オブジェクト変数を操作するクライアントが多数ある場合は、クラスごとに新しい機能を作成する必要はありません。代わりに、ゲッターとセッターを変更するだけです)。

オブジェクトセッターとゲッターのみを使用することで、その実装の詳細を外界から隠すことができます。これは素晴らしい利点であるため、クラスと対話しようとしている他のオブジェクトがその機能を壊すことはありません。これにより、システムが効果的に実装される可能性も高まります。

于 2011-02-18T08:06:33.230 に答える
1

私はあなたの質問にすでに答えている上記の答えを見つけます。しかし、コードに別の問題があります。それは、セキュリティとデータの整合性の問題です。クラスメンバーは、検証なしでユーザーの入力から直接入力します。たとえば、電子メールアドレスがxyz@abc.comパターンを持っていることを確認したい場合があります。悪意のあるユーザーが入力に非常に長い文字列を入力すると、予期しないエラーが発生する可能性があります。

于 2011-02-20T08:35:17.330 に答える
1

内部データを別のクラスに公開しないため、これはカプセル化に違反しません。インターフェイスをデータから分離するために、Model-View-Controller (MVC)を確認することをお勧めします。

従来は、次のように、必要に応じて変数ごとに1つのゲッターとセッターを作成します。

public String getName() {
  return name;
}

public void setName(String name) {
  this.name = name;
}

クラスの外部でアクセスする必要のない変数のセッターを作成したり、クラスの外部で設定する必要のない変数のセッターを作成したりしないでください。

MVCに従い、上記のような従来のゲッターとセッターを使用する場合は、別の場所にビューコードがあり、次のようなものを呼び出すことになります。

myAddressBookEntry.setName(JOptionPane.showInputDialog("Enter Name: "));
于 2011-02-18T06:37:31.383 に答える