C#のgetterとsetterについて初心者でも分かりやすく解説!

このQ&Aのポイント
  • C#では変数に「プロパティ」を作ることができます。フィールド(クラスのインスタンス変数)というのは、クラスの内部で持っている値です。この内部の値に直接外部からアクセスさせてはいけません。カプセル化では、フィールドへの読み書きは、必ずそのクラスのコードを経由して行います。つまり、間接的に読み書きします。
  • getterとは、プロパティから値を取得するためのメソッドです。setterとは、プロパティに値を代入するためのメソッドです。プロパティを使うことによって、外部からフィールドの値を安全に読み書きすることができます。
  • 例えば、上記のコードでは、Personクラスにnameというフィールドがあります。このフィールドに直接アクセスすることはできず、Nameプロパティを通じて値の取得と代入を行います。getブロックでは、フィールドの値を返すためのロジックを記述し、setブロックでは、引数として渡された値をフィールドに代入するためのロジックを記述します。
回答を見る
  • ベストアンサー

getterとsetterについて

プログラム初心者です。 いきなりC#から勉強するのは難度が高いかもしれませんが、 克服しないといけません。 分からないことがあります。 教えていただけますでしょうか。 例えばC#のプログラミングで使用する getterとsetterについて初心者でも分かりやすく教えていただけないでしょうか。 "C#では変数に「プロパティ」を作ることができます…"とか "フィールド(クラスのインスタンス変数)というのは、クラスの内部で持っている値です。 この内部の値に直接外部からアクセスさせてはいけません。 カプセル化では、フィールドへの読み書きは、必ずそのクラスのコードを経由して行います。 つまり、間接的に読み書きします。"とか書かれているものがありました。 この値はいかなるどういう値で、それを取得したい場合に使うのか 分かりません。正確にイメージできません。 あと以下の例文があったのですが、 valueというのはもともとどういう値が入っていて代入しているのですか? 宜しくお願いします。 public class Person { private string name; public string Name; { get { return this.name; } set { this.name = value; } } }

質問者が選んだベストアンサー

  • ベストアンサー
  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

あまりいい例ではないのだが: 例えばあなたの所持金を, あなたの「プロパティ」と考えてみましょうか. 何らかの事情でほかの人があなたの所持金を知らなければならないかもしれません. そのとき, あなたはほかの人があなたの所持金を自由に知ることができるようにしていますか? それとも, 「あなたに尋ねる」など一定の方法で知ることができるようにしていますか? あるいは, 場合によってはあなたの所持金が変化することもあるでしょう. そのとき, ほかの人が勝手にあなたの所持金を増減させることができるようにしていますか? それとも, あなたの許可によって増やしたり減らしたるするようにしていますか? 下の例の value は setter のデフォルトの引数でしょう.

その他の回答 (4)

  • Ogre7077
  • ベストアンサー率65% (170/258)
回答No.5

本来のオブジェクト指向の考え方では、「オブジェクトの状態を表すもの」をプロパティと呼称します。 例: オブジェクト「ファイル」の状態「最終更新日」 オブジェクト指向のプログラム言語において、このプロパティを実現するために「オブジェクト内の変数」の形式で使うのが一般的です。  File o = new File();  Date d = o.LastUpdateDate; // ここ ですが、変数では正確な状態を取得できないケースがあるとします。  Date d = o.LastUpdateDate; // だれかに更新されたら古い情報になる  Date e = o.GetLastUpdateDate(); // 取得する処理が必要 そこで C# には「変数の様に操作できるオブジェクト」という機能があります。  public Date LastUpdateDate {   get { return this.GetLastUpdateDate(); }  }  Date d = o.LastUpdateDate; // 実は GetLastUpdateDate() の結果を取得している この「変数の様に操作できるオブジェクト」を、プログラミング言語では「プロパティ」と呼びます。 区別する為に「オブジェクト内の変数」は「フィールド」となります。 しかし変数のように使うには、変数の「設定」と「参照」の二通りの使い方を真似しなければなりません。そのためプロパティには、設定を担当する getter メソッドと、参照を担当する setter メソッドが存在します。 まとめ  フィールド: オブジェクト内の変数  プロパティ: オブジェクト内の変数の様に操作できるオブジェクト  setter: プロパティにおける「変数の設定」を担当するメソッド  getter: プロパティにおける「変数の参照」を担当するメソッド 例題の name ですが、これは記述が省略されていますが setter メソッドの第一引数のことです。

  • Wr5
  • ベストアンサー率53% (2177/4070)
回答No.4

#2で書いたアクセス元で判定…は出来なかったかも。 そういう意味ではイマイチな例になっていたと思われます。 まあ、だいたいのイメージということで……。

  • Wr5
  • ベストアンサー率53% (2177/4070)
回答No.3

長々書いていたらカブった。 # アクセス制御の例で財布の例が使われる…なんてのまでカブりましたな。 # 「直接的に」わかりやすい例になるから…でしょうけど。

  • Wr5
  • ベストアンサー率53% (2177/4070)
回答No.2

>この値はいかなるどういう値で、それを取得したい場合に使うのか >分かりません。正確にイメージできません。 想定外の値を勝手に書き換えられたり、秘密にしたい内容(相手)に勝手に見られないように……。 ってところでしょうかね。 変数の内容を覗いたり書き換えたりできる対象を制限したい場合とか。 入力の時点でエラーになる値を弾くようにしておけば、以降の処理を簡略化することができます。 たとえば日付を扱いたい時に西暦-6000年16月889日とかの入力をエラーに出来る。とか。 机の上に貴方の財布が置いてあります。 他人が勝手に財布を開けて飲み会の代金を徴収していった場合、貴方の知らないウチにお金が減っている事になります。 貴方に請求して貴方が財布からお金を取り出し払った場合なら、財布から幾らの現金が出ていったのかについては把握できますよね? # seter相当。自前で処理しているのだから、収支については把握できます。 貴方に手持ちの金額を尋ねて(geter相当)、飲み代分が足りないとかなら「後日徴収する」とか対応も可能ですよね? # 問い合わせ部分がgeter相当。財布内の現金額を知られたくない相手ならば答えない(あるいは嘘の金額を言う)などの制御が可能です。 >あと以下の例文があったのですが、 >valueというのはもともとどういう値が入っていて代入しているのですか? seterの呼び出し元が設定した値を一時的に受け取る変数です。 よって、どんな値が入っているかは(呼び出し元)コード次第でしょう。 # その値が不正なのかどうかを判定してフィールドメンバに値を適用するかどうかを制御します。 # 掲示された例では未チェックですけどね。 外のクラスからはnameというフィールドには直接アクセスできません。(privateですから) そんなワケで間接的にアクセスする為のseter/geterとしてNameというプロパティが用意された。 ということになります。 # もちろん、publicなフィールドも作れますけどね。

関連するQ&A

  • getter、setterメソッドを活用したいです

    Javaのgetter、setterメソッドをうまく使って、下記のコードを実行しようとしたのですが。 ---------------- package javatest; public class Jidosha { private int num; private double gas; public void setNum(int num) { this.num = num; } public void setGas(double gas) { this.gas = gas; } public int getNum() { return num; } public double getGas() { return gas; } public static void main(String args[]) { System.out.println("この車のナンバーは" + num + "です。"); System.out.println("この車のガソリンが入る最大量は " + gas + "です。"); } } ---------------- Eclipse上では「System.out.println・・・」のところで「非 static フィールド gas を static 参照できません」といったエラーが出てきまして。 getter、setterメソッドをうまく活用して「この車のナンバーは××××です」「この車のガソリンが入る最大量は〇〇〇〇です。」という文を出力するには、どう書けばよいでしょうか。 よろしくお願い致します。 ※OKWAVEより補足:「Webシステム開発」についての質問です。

    • ベストアンサー
    • Java
  • サブクラスでセッターを呼び出す

    java初心者です。 以下のようなソースコードで、コンパイルしたらエラーが出ました。 サブクラスのsetterのところでエラーが出たんですが、 サブクラスでスーパークラスのメソッドは呼び出せないんでしょうか? それとも他に間違いがあるんでしょうか? class rensyu { private int x; rensyu(){ x=this.x; } int getX(){ return x; } void setX(int m){ this.x = m; } } class rensyu2 extends rensyu{ private rensyu[] A; rensyu2(){ A = new rensyu[100]; } int getter(int i){ return A[i].getX(); } void setter(int x,int i){ A[i].setX(x); } } class rensyuTester{ public static void main(String[] args) { rensyu2 A = new rensyu2(); A.setter(1,0); A.setter(2,1); System.out.println(A.getter(0) +" "+ A.getter(1)); } }

    • ベストアンサー
    • Java
  • セッターとゲッター

    Java初心者です。 セッターとゲッターの違いがわからないので質問します。 あるクラスの配列に値を格納して、もうひとつのクラスでそれを取得するにはセッターとゲッターのどちらに記述すればいいですか? また、ソースの書き方としてはどのように記述すればいいでしょうか?お願い致します。

    • ベストアンサー
    • Java
  • ゲッタ、セッタの意味

    getterとsetterがあり、privateなインスタンス変数を持つクラスと、publicなインスタンス変数を持つクラスってどう違うんですか?

    • ベストアンサー
    • Java
  • Strutsで「setterメソッドが見つかりません」

    Eclipse+TOMCAT環境でStrutsアプリを作っています。 とりあえずの勉強として、参考書に載ってあるサンプルを作っているのですが、会社では動いたそのサンプルを自宅で同じ手順で実行すると、「index.jsp(24,2) 属性 name のsetterメソッドが見つかりません」と表示されます。最初に表示されるはずのindex.jspファイル内に<html:form action="Lookup" name="lookupForm" type="wiley.LookupForm">と記述しており、ここの解析で出たエラーだと思われるのですが、ActionFormであるLookupFormクラスにはEclipseによるSetter/Getterメソッドの自動生成を行って記述しており、なぜエラーになるのかが分からない状態です。原因となりそうな点をお教えください。宜しくお願いします。

  • データベース(テーブル情報)操作方法に関して

    まだJAVAを初めて1ヶ月ちょいの初心者です。ぜひ教えて頂きたいことがあります。 データベースのテーブル操作に関してなんですが、どうコーディングしたら効率のよいプログラムになるのか検討段階でつまずいています。 今考えているのが、スーパークラスにてテーブルの各カラム変数を宣言し、そのサブクラスにてテーブル操作毎のSQL発行(スーパークラスから継承した抽象メソッドを用いて)をしたほうがいいのかなと考えてます。 つまり・・・ ----<<super class(抽象クラス)>>----- public abstract class InfoTable { private String name; private int age; : public String getName() { return Staff_ID; } public String setName(String name){ this.name = name } //抽象クラス(SQLを発行しテーブルを操 //作する抽象メソッド) public abstract boolean exec(); } とし、サブクラスにて継承&実装すればよいのかと・・・。 実際にテーブルのカラムが多くなれば、setter・getterを多く繰り替えし処理をしなければならなくなり、それは大変だし、プログラム的にもよくないんじゃないかと考えています。実際にサブクラスはサーブレットからデータを取得してから処理を行う予定なので、Vectorを使えばいいのかなとは思いますが、どう使ったらよいのか検討がつきません。 長々と書いてしまい申し訳ございません。 どなたか良い知恵をお貸し下さい!

    • ベストアンサー
    • Java
  • C++のfriend classについて

    C++のfriend classについて C++の初心者です。 C++でのfriend classは基本的に、全プロパティに対するsetter,getterを持たせて 集約、コンポジションにより代替が可能だと思うのですが、今勉強の為に読解して いるソースではsetter,getterの実装がなされているクラスの使用に対しても friend 宣言が多発していて中途半端なルールになっていると感じてしまいます。 friend 宣言によって別途実現可能になる事や、パフォーマンス的に有利(微々たる 物なはず)な事ってあるのでしょうか?

  • アノテーションを利用したアクセサメソッドの自動定義というのは実現可能?

    近年、デフォルトコンストラクタと各フィールドに対するアクセサメソッド(setter/getter)を備えたJavaBeansが話題になっていると思います。例えばこんなクラス。 class TestBeans {  private int number;  public void setNumber(int number) {   this.number = number;  }  public int getNumber() {   return number;  } } しかし、フィールドの数が増えてくると、コードがどんどん冗長になってくると思います。 そこで、ふと思ったのですが、リフレクションとJDK5のアノテーションを使って、下記のようにスッキリとアクセサメソッドが利用できるようになったりしないかなぁ、と。 class TestBeans {  @Getter @Setter  private int number; } こうすることによって、getNumber / setNumber が利用できるようになったりしないかな、ということです。 アノテーションの自作やリフレクションに関する知識が乏しいので、私にはよくわかりませんでした。 こういったことは実現可能なのでしょうか? また可能ならばどのように実装するのでしょうか? よろしくお願いいたします。

    • ベストアンサー
    • Java
  • ある特定の値(変数)を持たせたい時のクラスの設計法は?

    例えば、「人」クラスと、それを拡張した「杉山」、「鈴木」等具体的な名前を与えるクラスを設計する時、「名前」にあたるものはクラスを作った時点で分かるはずです。 また、「人」クラスをスーパークラスとして持つことも共通しています。 こういった場合、名前にあたる変数はどのように実装するべきなのでしょうか? 例えば、 class Person{ } class Suzuki extends Person{ String name = "suzuki"; } のように、するべきなのか class Person{    STring name_;    void setName(String name){       name_ = name;    } } class Suzuki extends Person{    setName("Suzuki"); } のようにするべきなのか、何がベターなのかよく分かりません。 出来れば、Personクラスを拡張したクラスには、忘れないようにnameフィールドに値を入れるようにしたいのですが、抽象クラスも何か違うのかなぁ…と(よく分かりませんが)。 よろしくお願いします。

    • ベストアンサー
    • Java
  • c# ポインタ代わりの配列 改定

     こんにちは、c#初心者です。  先ほどの質問に回答がつかなかったので、内容が分かりにくいのだろうと思い改定しました。  汎用ライブラリを作っている途中で、引数にではなく、フィールドにポインタをもてたら良いのになと思う場面が時々あります。  「c#じゃ、クラスがポインタみたいなものだろ!」とおっしゃる方もいるかと思います。  Control c1 = new Control();  Control c2 = c1;  とすれば、確かにc1もc2も同じインスタンスを参照することになりますから、メンバ書き換えても当然もう一方も変わっていることになります。  しかし、問題は互いにスコープ上見えていないクラス同士で同じ値を持ちたい場合、具体的にはあるクラスAのインスタンス内にbとcがあり、bとcで同じ値を参照したい場合です。 class SampleClassA {   SampleClassB b:   SampleClassC c: }  上記のような構造で、b, cともにある方のメンバ変数「value」を持っていたとします。  そして、例えばvalueがクラスのstring型だったとすると、  string text = "テキスト";  b.value = text;  c.value = text;  とすれば同じ値を参照することになります。が、  b.value = "あいうえお"  とすると当然のことながらbのアドレスだけが変更され、cの値は変更されません。これをaの内部で行うのであれば、  b.value = "あいうえお";  c.value = b.value; のようにすればいいわけですが、bやcの中で  value = "あいうえお"; としてしまうと完全にaもcも手も足も出ないわけです。  *value = "あいうえお"; が出来ないわけです。  何とかしようとすると、初心者は3つの方法を思いつきました。 1、イベントやデリゲート 2、SampleClassAに値を置いて、b, cからaを参照できるようにする。 1、ほとんど何でもでき、ある意味完璧ですが、消費メモリが増える上にデリゲートはパフォーマンス上ベストではない(ライブラリなので、別にAPIを作っているわけではないのですが)。 2、「スコープが大変混沌としてよろしくない」と初心者は思いました(多分あっていますよね?)。 3、それで、一度はこんなクラスを作りました。 public class Pointeric<T> {   internal T _cont;   public T Containt   {     get { //略 }     set { //略 }   }   public SampleClass(T val) { //略 } }  これでこのクラスのインスタンスを持っていれば  *b.value = "あいうえお";  の代わりに  b.value._cont = "あいうえお";  ができる。 また当然  c.value._cont  は"あいうえお"になる  しかし、msdnさんのクラス ライブラリ開発のデザイン ガイドラインとやらに「ライブラリはpublicなフィールドを持っちゃダメ」と怒られたのでinternalに。すると同じソリューション(ライブラリ)でもプロジェクトが異なればプロパティを使わざるを得ません。すると速度が全然出ないわけです。  そこで代わりに長さ1の配列をポインタ代わりに使うという手を(最近)思いつきました。  具体的には var _sharedValue = new Pointeric<int>(10); ------------------ _sharedValue.Containt = 5; などとしていたのが、 var _sharedValue = new int[1] { 10 }; ------------------ _sharedValue[0] = 5; という形になります。  気になるのが「この配列はポインタ代わりに使われているんだな」ということにXMLコメントと名前だけで気づいてもらえるかどうかという事です。  まだ経験が浅いので判断しかねます。皆さんのご意見を伺わせてください。また、「こんな方法もあるよ」というのがあればお願いします。

専門家に質問してみよう