web-dev-qa-db-ja.com

Javaでメソッドを設定および取得しますか?

Setメソッドとgetメソッドをどのように使用できますか?また、なぜそれらを使用する必要がありますか?彼らは本当に役に立ちましたか?また、setメソッドとgetメソッドの例を教えてもらえますか?

47
user759630

SetおよびGetメソッドは、データのカプセル化のパターンです。クラスメンバー変数に直接アクセスする代わりに、getメソッドを定義してこれらの変数にアクセスし、setメソッドを定義してそれらを変更します。この方法でそれらをカプセル化することにより、将来、クラスの内部動作を変更する必要がある場合に、パブリックインターフェイスを制御できます。

たとえば、メンバー変数の場合:

Integer x;

メソッドがあるかもしれません:

Integer getX(){ return x; }
void setX(Integer x){ this.x = x; }

チッコロ また、重要な点にも言及しました。外部クラスのフィールドへの読み取りアクセスのみを許可する場合は、パブリックgetメソッドを提供し、setをプライベートのままにするか、setを提供しないことで、それを行うことができます。すべて。

54
Justin Ethier

オブジェクトを無効な状態にすることを防ぐためにセッターを使用できることを他の回答に追加したいと思います。

たとえば、文字列としてモデル化されたTaxIdを設定するとします。セッターの最初のバージョンは次のとおりです。

private String taxId;

public void setTaxId(String taxId) {
    this.taxId = taxId;
}

ただし、無効なtaxIdを使用してオブジェクトを設定する使用を防ぐ方がよいため、チェックを導入できます。

private String taxId;

public void setTaxId(String taxId) throws IllegalArgumentException {
    if (isTaxIdValid(taxId)) {
        throw new IllegalArgumentException("Tax Id '" + taxId + "' is invalid");
    }
    this.taxId = taxId;
}

プログラムのモジュール性を改善する次のステップは、TaxId自体をオブジェクトとして作成し、それ自体をチェックできるようにすることです。

private final TaxId taxId = new TaxId()

public void setTaxId(String taxIdString) throws IllegalArgumentException {
    taxId.set(taxIdString); //will throw exception if not valid
}

ゲッターについても同様に、値がまだない場合はどうなりますか?別のパスにしたいのかもしれません。

public String getTaxId() throws IllegalStateException {
    return taxId.get(); //will throw exception if not set
}
22
stivlo

次のようなものが欲しいと思います:

public class Person {

  private int age;

  //public method to get the age variable
  public int getAge(){
       return this.age
  }

  //public method to set the age variable
  public void setAge(int age){
       this.age = age;
  }
}

オブジェクトインスタンスでこのようなメソッドを呼び出すだけです。このような方法は、特に何かを設定すると副作用があると思われる場合に便利です。例えば。次のような特定のイベントに反応する場合:

  public void setAge(int age){

       this.age = age;

       double averageCigarettesPerYear = this.smokedCigarettes * 1.0 / age;

       if(averageCigarettesPerYear >= 7300.0) {
           this.eventBus.fire(new PersonSmokesTooMuchEvent(this));
       }
  }

もちろん、誰かがsetAge(int)の呼び出しを忘れて、this.ageを使用してageを直接設定するのを忘れると、これは危険です。

8
displayname

フィールドへのアクセス方法を制御し(データチェックなどを課す場合があります)、インターフェイスに適合します(インターフェイスはフィールドの存在を必要とせず、メソッドのみ)ため、フィールドへの直接アクセスよりもアクセサメソッドの方が適しています。

6
Bohemian

セッターとゲッターは、外部クラスから直接アクセスするメンバー変数を置き換えるために使用されます。プロパティへのアクセスにセッターとゲッターを使用する場合、初期化、エラーチェック、複雑な変換などを含めることができます。

private String x;

public void setX(String newX) {
    if (newX == null) {
        x = "";
    } else {
        x = newX;
    }
}

public String getX() {
    if (x == null) {
        return "";
    } else {
       return x;
    }
}
5
g051051

ゲッターとセッターを使用するいくつかの利点( encapsulation またはdata-hiding):

(元々回答済み ここ

1。クラスのフィールドは、読み取り専用(ゲッターのみを提供)または書き込み専用(セッターのみを提供)にすることができます。これにより、クラスに誰がそのフィールドにアクセス/変更できるかを完全に制御できます。

例:

class EncapsulationExample {
    private int readOnly = -1;  // this value can only be read, not altered
    private int writeOnly = 0;    // this value can only be changed, not viewed
    public int getReadOnly() {
        return readOnly;
    }
    public int setWriteOnly(int w) {
        writeOnly = w;
    }
}

2。クラスのユーザーは、クラスがデータを実際に格納する方法を知る必要はありません。これは、データが分離され、ユーザーとは独立して存在するため、コードをより簡単に変更および保守できることを意味します。これにより、メンテナーは、ユーザーに影響を与えずに、バグ修正、設計、パフォーマンスの強化などの頻繁な変更を行うことができます。

さらに、カプセル化されたリソースは各ユーザーに均一にアクセスでき、この動作はクラスで内部的に定義されているため、ユーザーに依存しない同一の動作を持ちます。

例(値を取得する):

class EncapsulationExample {
    private int value;
    public int getValue() {     
        return value; // return the value
    }
}

では、代わりに値の2倍を返したい場合はどうなりますか?ゲッターを変更するだけで、私の例を使用しているすべてのコードを変更する必要はなく、2倍の値を取得できます。

class EncapsulationExample {
    private int value;
    public int getValue() {
        return value*2; // return twice the value
    }
}

3。コードをわかりやすく、読みやすく、理解しやすくします。

以下に例を示します。

カプセル化なし:

class Box {
    int widthS; // width of the side
    int widthT; // width of the top
    // other stuff
}

// ...
Box b = new Box();
int w1 = b.widthS;  // Hm... what is widthS again? 
int w2 = b.widthT;  // Don't mistake the names. I should make sure I use the proper variable here!

カプセル化あり:

class Box {
    private int widthS; // width of the side
    private int widthT; // width of the top
    public int getSideWidth() {
        return widthS;
    }
    public int getTopWIdth() {
        return widthT;
    }
    // other stuff
}

// ...
Box b = new Box();
int w1 = b.getSideWidth(); // Ok, this one gives me the width of the side
int w2 = b.getTopWidth(); // and this one gives me the width of the top. No confusion, whew!

2番目の例では、取得する情報をより詳細に制御し、これがどれほど明確であるかを確認します。気を付けてください、この例は簡単であり、実際には、多くの異なるコンポーネントがアクセスする多くのリソースを扱うクラスです。したがって、リソースをカプセル化すると、どのリソースにどの方法でアクセスするか(取得または設定)が明確になります。

このトピックの good SO thread です。

これは、データのカプセル化に関する good read です。

4
nem035

上記の答えは、ゲッターとセッターの役割を私ができる以上に要約していますが、純粋なゲッターとセッター、つまり複雑な構築、検証などのないものの使用を減らすために理想的にコードを構成する必要があることを付け加えました。カプセル化が破られるためです。これは、使用できないという意味ではなく(stivloの答えはゲッターとセッターの適切な使用例を示しています)、使用頻度を最小限に抑えるようにしてください。

問題は、ゲッターとセッターがプライベートデータへの直接アクセスの回避策として機能できることです。プライベートデータは、他のオブジェクトと共有するためのものではないため、プライベートと呼ばれます。これは、オブジェクトの状態を表すものです。他のオブジェクトがオブジェクトのプライベートフィールドにアクセスできるようにすると、そもそもプライベートに設定するという目的全体が無効になります。さらに、作成するすべてのゲッターまたはセッターにカップリングを導入します。たとえば、これを考慮してください。

private String foo;

public void setFoo(String bar) {
    this.foo = bar;
}

将来、どこかでfooが不要になった、または整数にしたい場合はどうなりますか? setFooメソッドを使用するすべてのオブジェクトは、fooとともに変更する必要があります。

2
xobicvap

OOPルール:データの非表示とカプセル化のためです。オブジェクトをパブリックとして宣言し、ほとんどの状況でその場で変更することは非常に悪い習慣です。他にも多くの理由がありますが、ルートはOOPでのカプセル化です。 「本を購入するか、オブジェクト指向プログラミングを読んでください」と、OOPの本を読んだ後、このすべてを理解できます。

2
Ben Xu
public class Person{

private int age;

public int getAge(){
     return age;
}

public void setAge(int age){
     this.age = age;
}
}

私はこれがあなたが望むと思う..そしてこれはpojoとも呼ばれます

1
subash

上記の答えはすべて、問題のオブジェクトが振る舞いを持つオブジェクトであると仮定しています。 OOPの高度な戦略は、データオブジェクト(Zipを実行し、フィールドのみを持つ)と動作オブジェクトを分離することです。

データオブジェクトでは、ゲッターを省略し、代わりにパブリックフィールドを使用することはまったく問題ありません。ほとんどの場合不変であるため、通常はセッターはありません。フィールドはコンストラクターを介して設定され、再び設定されることはありません。詳細については、Bob Martinの Clean Code またはPryce and Freemanの Growing OO Software ... をご覧ください。

1
Urs Reupke

Get()set()メソッドの利点は次のとおりです。

  1. オブジェクトを簡単にシリアル化できます。
  2. 包含クラスから永続オブジェクトを作成できます。
  3. プロパティをJSONに簡単に変換できます。
  4. DAOレイヤー(Hibernateのようなフレームワーク)では、オブジェクトをDBに直接保存できます。
  5. オブジェクト指向の概念を簡単に理解できます。
  6. おそらくシングルトーンパターンを除くすべてのデザインパターンでのニーズ。
  7. 直接アクセスを保護するプロパティのセキュリティ。
  8. ポリモーフィズム、カプセル化は、このタイプのクラスによって簡単に理解および実装できます。

例:

private String personName;
private int personId;

    public void setPersonName(String name) throws Exception{
    if(!(name.equals("")||name=="")){
      this.personName = name;
    }
  }
  public String getPersonName(){
    return this.personName;
  }
  public void setPersonId(int id) throws Exception{
    this.personId = id;
  }
  public int getPersonId(){
    return this.personId;
  }
1
Kaisar

この答えは別の質問からマージされます。

getAge()メソッドは、Javaではインスタンスメソッドと呼ばれます。

インスタンスメソッドを呼び出すには、このメソッドが定義されているクラスのオブジェクトが必要です。

たとえば、クラスのこのメソッドがPersonと呼ばれる場合、

  1. New演算子を使用してPersonオブジェクトを作成します

     Person p = new Person();
    
  2. Personオブジェクトの年齢を取得するには、このメソッドを使用します

    p.getAge()
    
0

これはsetメソッドのコードです

public void setAge(int age){
  this.age = age;
}
0
amit bhardwaj

SetAge createメソッドが必要な場合は、C#に似た何かをしようとしているようです
setAge(int age){ this.age = age;}

0
user3455363

ここに2番目の質問(理由)に対する簡単な答えがありません。だからここに行きます。

コードで非常に頻繁に使用されるパブリックフィールドがあるとします。このフィールドを指定または設定する前に何か特別なことをする必要があると判断するたびに、問題が発生します。このフィールドに特別なゲッターとセッターを作成し、フィールドを直接使用するコードからゲッターとセッターを使用するように完全なコードを変更する必要があります。

今、あなたが多くの人々によって広く使われているライブラリを開発していると想像してください。上記のような変更を行い、フィールドへの直接アクセスをprivateに設定する必要がある場合、このフィールドを使用しているすべてのユーザーのコードが破損します。

ゲッターとセッターの使用はコードの将来の計画に関するものであり、より柔軟になります。もちろん、特に一部のデータのみを保持する単純なクラスの場合は、パブリックフィールドを使用できます。しかし、フィールドを非公開にして、そのフィールドのgetおよびsetメソッドをコーディングすることは常に良い考えです。

0
Madmenyo