2

Javaチュートリアル、ウィキペディア検索、スタックオーバーフロートローリング、およびコードサンプルの読み取りに何時間も費やしたにもかかわらず、コンストラクターは私を混乱させます。MEがコンストラクターを少しよく理解できるようにするために、私が答えようとしている3つの関連する質問があります。

まず、コンストラクターはクラスと同じ名前にする必要があるという印象を受けました。検討:

public class Money {
    public Money(long l) {
        this.value = l;
    }

    public Money(String s) {
        this.value = toLong(s);
    }

    public long getLong() {
        return this.value;
    }

    public String getString() {
        return toString(this.value);
    }
} 

私はこれを4つのコンストラクターとして見ています...正しいですか?したがって、コンストラクター、それらを含むクラスと同じ名前ではないようです。誰かがそれを確認できますか?

第二に、私はsetメソッドとgetメソッドを理解することを妨げているようです。検討:

 public class GetSetSample {
     public int getFoo()  {
 return int Foo;
 }
 public void setFoo(int fooValue) {
 int Foo = fooValue;
 } 
} 

なぜ私はこれを行うことができないのですか?

public class getFoo(int fooValue){
     foo=fooValue;
}

foo = getFoo(12)他のクラス/メソッドから使​​用しますか?

3番目の質問はもう少し難解ですが、全体像を理解するのに役立ちます...これは私の学習スタイルであり、デバッグ時にプログラムフローを追跡する能力に役立ちます。getおよびメソッドは、私とのset「to」および「from」の関係を示唆しています。たとえば、値をコンストラクターに「渡し」、結果をgetメソッドから「from」で受け取ります。「to」と「from」はあなたの視点によって変わるように思えます。setMethod変数が別のクラスまたはメソッドからのものであり、結果のオブジェクト(たとえば)に適切なパラメーターを設定している場合でも、オブジェクトのパラメーターを設定GetMethodgetthis.fooいると思いsetます。どこにいてgetsetが使用される場合、メインメソッドまたは単一のコンストラクターを持つスタンドアロンクラスでは、「set」は常にパラメーターの送信に関連付けられ、get常にそのパラメーターを持つオブジェクトの受信に関連付けられます。それは良い理解ですか?または私は重要な部分を逃していますか?

4

6 に答える 6

8

質問1:

これは 4 つのコンストラクターと見なされます...正しいですか?

いいえ、そのクラスには 2 つのコンストラクターと 2 つのメソッドがあります。(getLonggetStringはメソッドです。)

質問2:

なぜ私はこれを行うことができないのですか:

public class getFoo(int fooValue){
    foo=fooValue;
}

これは、パラメーターを使用してクラスを宣言しようとしている上に、 getメソッドで値を設定しているため、非常に奇妙です。ここで何を達成しようとしているのかは明確ではありませんが、そのコードは完全に無効です。

質問 3:

get メソッドと set メソッドは、"to" と "from" の関係を示唆しています。

まあ、それは本当に関係IMOではありません. 関係は、これらの方法のいずれよりも長期的なものを示唆しています。通常、setter は何らかの方法でオブジェクトの状態を変更し、getter は通常、オブジェクトの状態の一部を返すだけです。あなたは専門用語でやや速くてルーズに遊んでいるので、あなたの説明の残りの部分が何を意味するのかは本当に明確ではありません. たとえば、「getそのパラメーターを持つオブジェクトを受け取ることに常に関連付けられている」というのは、私には意味がありません。オブジェクトにはパラメーターがなく、メソッド/コンストラクターにはパラメーターがあり、ゲッターはプリミティブ値または参照をフェッチできます...

コンストラクターとメソッドについて説明している Java チュートリアル の「クラス」の部分を読むと役立つと思います。

于 2012-04-14T17:57:29.557 に答える
3

クラスと同じ名前を持つ必要がある 2 つのコンストラクターを示しました。

また、ユーザーが要求した形式でクラス変数の値を返す 2 つの "getter" メソッドも示しました。値をクラス変数に転送するために使用される「セッター」メソッドを作成することもできます。

コンストラクターを使用して特定のクラスのオブジェクトを作成し、オプションでその内部状態 (つまり、メンバー変数) の一部またはすべてを設定します。

セッターとゲッターを使用してクラス変数を外部から分離するため、他のコードがそれらに直接アクセスできるようにする必要はありません。なんで?セッターが変数を更新する前に、新しい値が有効であること、および操作がクラスが適切に機能するために必要なルール (「ビジネス ロジック」) に違反していないことを確認できるためです。

したがって、セッターを追加し、コンストラクターを更新してそれを使用できます。

public Money(long l) {
    setValue(l);
}

public Money(String s) {
    setValue(toLong(s));
}

// Example setter that validates `l` by prohibiting negative values
public Money setValue(long l) {
  if (l < 0) {
    // Warn about negative values
  }
  this.value = l;
  return this;  // Return the current object to allow chaining; see below.
}

通常、setter は値を返す必要はありません (つまり、 type である可能性がありますvoid) が、オブジェクト自体を返すと便利な場合が多いことに注意してください。これにより、次のようなコードを記述できます。

Money earnings = new Money().setValue(4).setOtherField("foo");

これにより、 type のオブジェクトが作成され、Moneyさまざまな属性が設定され、変数に格納されますearnings。明らかに、これはこのような単純なクラスにはあまり役に立ちませんが、より複雑なクラスには非常に役立ちます。

Paycheck check = new Paycheck("MyCompany")
  .setEmployee("YourName")
  .setSalary(50,000)
  .setPaySchedule(Schedule.BIWEEKLY)
  .setAccountNumber("1234567")
  .setDefaultTaxRate();
于 2012-04-14T17:57:20.573 に答える
3

最初の答えに関しては、コンストラクターは 2 つしかありません。違いは、それらがどのように呼び出されるかです (文字列を使用して呼び出されると、文字列にパラメーターがある構造が使用され、long を使用して呼び出されると、もう一方が使用されます)。答えるために、はい、コンストラクターはクラスと同じ名前を持っています。

2 つのコンストラクター:

public Money(long l) {
        this.value = l;
    }

    public Money(String s) {
        this.value = toLong(s);
    }

2番目の答えに関しては、ゲッターとセッターはクラスになることを意図していません。それらはクラス自体の中にあるはずです。

getter と setter を使用してプリンタ クラスの設定値を取得する次の例を考えてみましょう。

public class Printer {

    @Inject @Informal Greeting greeting;

    private String name;
    private String salutation;

    public void createSalutation() {
        this.salutation = greeting.greet(name);
    }

    public String getSalutation() {
        return salutation;
    }

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

    public String getName() {
       return name;
    }
}

このリンクをよく読むと、間違いなくあなたを助けることができます! Java 指向オブジェクトの原則

于 2012-04-14T17:58:47.773 に答える
0

私はあなたの暗黙の概念的な質問に答えようとします-あなたはすでにこれとあれの例をたくさん持っているので、私はただ説明しようとしています。私はあなたがこれのほとんど-おそらくこれのすべて-を以前に聞いたことがあることは間違いありませんが、どの部分かはわかりません。

オブジェクト指向プログラミングは、主にオブジェクトを中心にしています。オブジェクトは、コードとデータの融合です。クラスを記述してオブジェクトを定義し、クラスコンストラクター(クラスのインスタンス化と呼ばれる)を使用して、そのクラスによって定義されたオブジェクトの1つ以上のコピーを作成します。

他の言語との類似点:関連するアイテムのデータ構造と、そのデータ構造を操作する一連のサブルーチンを使用できます。クラスは、そのデータ構造内のアイテムと、それを操作するサブルーチンを1つのユニットに収集する方法と考えてください。

コンストラクターを呼び出した後、そのクラスで定義されたデータのコピーと、そのコピーを参照する方法があります。クラスメソッドを呼び出すときにそのインスタンスを参照することにより、そのクラスで定義されたメソッドを使用してデータのそのコピーを操作します。

オブジェクト指向以外の言語でこれを行う場合は、メモリ内にデータ構造のコピーを作成し、そのデータ構造で規定された方法のみを使用するルーチンを作成できます。メモリ内のコピーへのポインタを持ち、そのポインタをパラメータとして、それを操作するすべてのサブルーチンに渡すことができます。実際、これは、一部のOO以前のシステムがプログラムされた方法です。

コンストラクターは、値を返すメソッド呼び出しに似ています。これには、ステートメントの実行が含まれます(または含まれる可能性があります)。また、常にそのクラスのオブジェクトを返します。コンストラクターとメソッドの間にも違いがあります。たとえば、コンストラクターが完了するまで、オブジェクトは完全には作成されておらず、いくつかのメソッドが呼び出されるべきではありません。

だから私はそれが役に立ったことを願っています。まだ疑問がある概念的なことがある場合は、ここにある何かが特定の質問を形成するのに役立つので、さらに説明することができます。

于 2012-04-14T18:33:54.597 に答える
0

多くの人々は、COBOLやFORTRANなどの言語の学習に何年も費やした場合、オブジェクト指向プログラミングへの変更には古い言語の学習を取り消すことを伴うことに気づきました。20年前に最初にC++に取り組んだとき、私は確かにこれを見つけました。あなたの説明から、あなたは明らかに概念に苦労しています、そして私は同情します。

簡単なレシピはないと思います。簡単な例で練習し、がっかりしないでください。SOについて質問することを恐れないでください-質問が明確に尋ねられれば、あなたは有用な答えを得るでしょう。

デバッガーでオブジェクトの「内部を見る」ことができる優れたIDE(Eclipse、Netbeansなど)を入手してください。うまくいけば、いくつかの段階で物事がクリックされるでしょう!

于 2012-04-14T18:34:58.483 に答える
0

質問 1 - 基本的な Java クラス:

Java クラスで見つけようとしているものはほとんど 3 つだけです。

  • フィールド/属性 (出身言語による)
  • 方法
  • コンストラクター (特別な種類のメソッドのように見えます)

すべてのクラスには、それが配置されているファイルの名前を共有するクラス名があります。したがって、Money を少し拡張するには:

Money.java
----------
public class Money {
   // This is a field/attribute
   Long value;

   // This is a constructor
   public Money() {
      this.value = Long(0L);
   }

   // This is a method
   public Long getValue() {
      return value;
   }

   // Another method
   public void makeMoney(Long moreMoney) {
      this.value = this.value + moreMoney;
   }
} // Everything in here is part of the Money class

コンストラクターとメソッドの唯一の違いは、コンストラクターには指定された戻り値がないことです。これは、潜在的なメソッドの名前の直前に型として宣言されます。コンストラクターは、それらが含まれているクラスと同じ名前にする必要がありますが、その理由は、それらがどのように記述されているかに暗示されています。

別の見方としては、型に関係のない Java キーワード (public、private など。ただし、float や int などは除く) を、参照しているメソッドの先頭からすべて削除する場合があります (そのリストここで見つけることができます)、メソッドの前に何か残っていますか?

現時点での Money を使用すると、次のようになります。

  • お金()
  • 長い getValue()
  • void makeMoney()

コンストラクターは、宣言で暗黙的に指定されているため、戻り値の型を持たないコンストラクターです。

質問 2/3 - Get/Set メソッド:

物議を醸す可能性のあることを言うつもりですが、まだ心配する必要はありません。Get/Set は基本的にオブジェクト指向開発のパターンであり、一般的に優れた Java スタイルですが、必須ではありません (最後に確認したところ、Android 開発では、最適化の理由から可能な場合は使用を推奨していません)。さらに、オブジェクトのすべてのフィールドがアクセス可能または変更可能であるとは限らないため、それらの書き込みは必須ではありません。

すべてのフィールドを public として宣言すると (「値」フィールドが現在暗示されているように)、簡単にこれを行うことができます。

Money myMoney = new Money(new Long(40L));
System.out.println(myMoney.value) // 40
myMoney.value = new Long(20L);
System.out.println(myMoney.value) // 20

それを除けば、get() と set() の概念は単なるメソッドです。それらについて特別なことは何もありません。それらが存在する主な理由は、一般的なオブジェクト指向プログラミングでは、オブジェクトの内部動作を直接変更する必要がないためです (これはカプセル化の原則です)。状態に影響を与えたり、状態から何かを取得したりするために必要なものはすべて、メソッドで処理する必要があります。

簡単に言うと、オブジェクトを使用するためにそのフィールドを知る必要がある場合は、それを正しく設計していません。

全体 像 したがって、get() と set() は実際には、非常に単純な方法でオブジェクトのフィールドに影響を与える一般的に記述されたメソッドのペアです (get() はフィールドへの単純なアクセスであり、set() はそのフィールドへの代入)。あなたが書いた他のメソッドがたまたまそれよりも複雑なことをするだけです。

于 2012-04-14T18:53:50.437 に答える