Setメソッドとgetメソッドをどのように使用できますか?また、なぜそれらを使用する必要がありますか?彼らは本当に役に立ちましたか?また、setメソッドとgetメソッドの例を教えてもらえますか?
SetおよびGetメソッドは、データのカプセル化のパターンです。クラスメンバー変数に直接アクセスする代わりに、get
メソッドを定義してこれらの変数にアクセスし、set
メソッドを定義してそれらを変更します。この方法でそれらをカプセル化することにより、将来、クラスの内部動作を変更する必要がある場合に、パブリックインターフェイスを制御できます。
たとえば、メンバー変数の場合:
Integer x;
メソッドがあるかもしれません:
Integer getX(){ return x; }
void setX(Integer x){ this.x = x; }
チッコロ また、重要な点にも言及しました。外部クラスのフィールドへの読み取りアクセスのみを許可する場合は、パブリックget
メソッドを提供し、set
をプライベートのままにするか、set
を提供しないことで、それを行うことができます。すべて。
オブジェクトを無効な状態にすることを防ぐためにセッターを使用できることを他の回答に追加したいと思います。
たとえば、文字列としてモデル化された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
}
次のようなものが欲しいと思います:
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
を直接設定するのを忘れると、これは危険です。
フィールドへのアクセス方法を制御し(データチェックなどを課す場合があります)、インターフェイスに適合します(インターフェイスはフィールドの存在を必要とせず、メソッドのみ)ため、フィールドへの直接アクセスよりもアクセサメソッドの方が適しています。
セッターとゲッターは、外部クラスから直接アクセスするメンバー変数を置き換えるために使用されます。プロパティへのアクセスにセッターとゲッターを使用する場合、初期化、エラーチェック、複雑な変換などを含めることができます。
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;
}
}
ゲッターとセッターを使用するいくつかの利点( 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
です。
上記の答えは、ゲッターとセッターの役割を私ができる以上に要約していますが、純粋なゲッターとセッター、つまり複雑な構築、検証などのないものの使用を減らすために理想的にコードを構成する必要があることを付け加えました。カプセル化が破られるためです。これは、使用できないという意味ではなく(stivloの答えはゲッターとセッターの適切な使用例を示しています)、使用頻度を最小限に抑えるようにしてください。
問題は、ゲッターとセッターがプライベートデータへの直接アクセスの回避策として機能できることです。プライベートデータは、他のオブジェクトと共有するためのものではないため、プライベートと呼ばれます。これは、オブジェクトの状態を表すものです。他のオブジェクトがオブジェクトのプライベートフィールドにアクセスできるようにすると、そもそもプライベートに設定するという目的全体が無効になります。さらに、作成するすべてのゲッターまたはセッターにカップリングを導入します。たとえば、これを考慮してください。
private String foo;
public void setFoo(String bar) {
this.foo = bar;
}
将来、どこかでfooが不要になった、または整数にしたい場合はどうなりますか? setFooメソッドを使用するすべてのオブジェクトは、fooとともに変更する必要があります。
OOPルール:データの非表示とカプセル化のためです。オブジェクトをパブリックとして宣言し、ほとんどの状況でその場で変更することは非常に悪い習慣です。他にも多くの理由がありますが、ルートはOOPでのカプセル化です。 「本を購入するか、オブジェクト指向プログラミングを読んでください」と、OOPの本を読んだ後、このすべてを理解できます。
public class Person{
private int age;
public int getAge(){
return age;
}
public void setAge(int age){
this.age = age;
}
}
私はこれがあなたが望むと思う..そしてこれはpojoとも呼ばれます
上記の答えはすべて、問題のオブジェクトが振る舞いを持つオブジェクトであると仮定しています。 OOPの高度な戦略は、データオブジェクト(Zipを実行し、フィールドのみを持つ)と動作オブジェクトを分離することです。
データオブジェクトでは、ゲッターを省略し、代わりにパブリックフィールドを使用することはまったく問題ありません。ほとんどの場合不変であるため、通常はセッターはありません。フィールドはコンストラクターを介して設定され、再び設定されることはありません。詳細については、Bob Martinの Clean Code またはPryce and Freemanの Growing OO Software ... をご覧ください。
Get()set()メソッドの利点は次のとおりです。
例:
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;
}
この答えは別の質問からマージされます。
getAge()
メソッドは、Javaではインスタンスメソッドと呼ばれます。
インスタンスメソッドを呼び出すには、このメソッドが定義されているクラスのオブジェクトが必要です。
たとえば、クラスのこのメソッドがPerson
と呼ばれる場合、
New演算子を使用してPersonオブジェクトを作成します
Person p = new Person();
Person
オブジェクトの年齢を取得するには、このメソッドを使用します
p.getAge()
これはsetメソッドのコードです
public void setAge(int age){
this.age = age;
}
SetAge createメソッドが必要な場合は、C#に似た何かをしようとしているようですsetAge(int age){ this.age = age;}
ここに2番目の質問(理由)に対する簡単な答えがありません。だからここに行きます。
コードで非常に頻繁に使用されるパブリックフィールドがあるとします。このフィールドを指定または設定する前に何か特別なことをする必要があると判断するたびに、問題が発生します。このフィールドに特別なゲッターとセッターを作成し、フィールドを直接使用するコードからゲッターとセッターを使用するように完全なコードを変更する必要があります。
今、あなたが多くの人々によって広く使われているライブラリを開発していると想像してください。上記のような変更を行い、フィールドへの直接アクセスをprivateに設定する必要がある場合、このフィールドを使用しているすべてのユーザーのコードが破損します。
ゲッターとセッターの使用はコードの将来の計画に関するものであり、より柔軟になります。もちろん、特に一部のデータのみを保持する単純なクラスの場合は、パブリックフィールドを使用できます。しかし、フィールドを非公開にして、そのフィールドのgetおよびsetメソッドをコーディングすることは常に良い考えです。