23

コンストラクターの目的は何ですか? 私は学校で Java を学んでいますが、コンストラクターはこれまで行ってきたことのほとんどが冗長であるように思えます。目的が達成されるかどうかはまだわかりませんが、今のところ意味がないように思えます。たとえば、次の 2 つのコード スニペットの違いは何ですか?

public class Program {    
    public constructor () {
        function();
    }        
    private void function () {
        //do stuff
    }    
    public static void main(String[] args) { 
        constructor a = new constructor(); 
    }
}

これは私たちが割り当てのために物事を行うように教えられた方法ですが、以下は同じ取引を行うのではないでしょうか?

public class Program {    
    public static void main(String[] args) {
        function();
    }        
    private void function() {
        //do stuff
    }
}

コンストラクターの目的は私にはわかりませんが、これまで行ってきたことはすべて非常に初歩的なものでした。

4

13 に答える 13

31

コンストラクターは基本的に、クラスのオブジェクトが有効であることを保証するために使用できるメソッドです。これがコンストラクターの主な動機です。

クラスに、常にゼロより大きい整数フィールドを 1 つ持たせたいとします。信頼できる方法でそれをどのように行いますか?

public class C {
     private int number;

     public C(int number) {
        setNumber(number);
     }

     public void setNumber(int number) {
        if (number < 1) {
            throws IllegalArgumentException("C cannot store anything smaller than 1");
        }
        this.number = number;
     }
}

上記のコードでは、冗長なことをしているように見えるかもしれませんが、実際には、何があっても数値が常に有効であることを保証しています。

「クラスのインスタンスを初期化する」ことはコンストラクターが行うことですが、コンストラクターがある理由ではありません。質問は、コンストラクターの目的についてです。上記の例を使用して、クラスのインスタンスを外部で初期化することもできますc.setNumber(10)。したがって、インスタンスを初期化する方法はコンストラクターだけではありません。

コンストラクターはそれを安全な方法で行います。つまり、クラスだけで、オブジェクトが常に有効な状態であることを保証するという問題全体を解決できます。コンストラクターを使用しないと、そのような検証が外の世界に委ねられます。これは悪い設計です。

別の例を次に示します。

public class Interval {
    private long start;
    private long end;

    public Interval(long start, long end) {
        changeInterval(start, end);
    }

    public void changeInterval(long start, long end) {
        if (start >= end) {
            throw new IllegalArgumentException("Invalid interval.");
        }
        this.start = start;
        this.end = end;
    }
    public long duration() {
        return end - start;
    }
}

Interval クラスは時間間隔を表します。時間は long を使用して格納されます。開始する前に終了する間隔を設けても意味がありません。上記のようなコンストラクターを使用すると、システム内の任意の時点で、意味をなさない間隔を格納する Interval のインスタンスを持つことができなくなります。

于 2013-11-12T23:15:07.017 に答える
10

LotusUNSWの回答で述べたように、コンストラクタはクラスのインスタンスを初期化するために使用されます。

例:

Animal次のようなクラスがあるとします

class Animal{
   private String name;
   private String type;
}

DogAnimal クラスのインスタンス、たとえば名前付きを作成しようとするとどうなるか見てみましょうPuppy。ここで、 と を初期化する必要がname = Puppyありtype = Dogます。それで、どうすればそれができますか。それを行う方法は、次のようなコンストラクターを持つことです

    Animal(String nameProvided, String typeProvided){
         this.name = nameProvided;
         this.type = typeProvided;
     }

class のオブジェクトを作成すると、コンストラクターAnimalのようなものAnimal dog = new Animal("Puppy", "Dog");が呼び出され、name と type を指定した値、つまり Puppy と Dog にそれぞれ初期化します。

ここで、コンストラクターに次のような引数を提供しなかった場合はどうなるかを尋ねるかもしれません

Animal xyz = new Animal();

これはdefault Constructor、オブジェクトをデフォルト値で初期化するものです。つまり、私たちのAnimalクラスnameでは、オブジェクトにtype対応する値はxyzname = nulltype = null

于 2013-11-12T23:20:22.367 に答える
4

コンストラクターは、作成時にオブジェクトを初期化します。クラスと同じ名前を持ち、構文的には method に似ていますが、コンストラクターには明示的な戻り値の型がありません。通常、コンストラクターを使用して、クラスによって定義されたインスタンス変数に初期値を与えるか、完全に形成されたオブジェクトを作成するために必要なその他の起動手順を実行します。

コンストラクターの例を次に示します。

class queen(){
   int beauty;

   queen(){ 
     beauty = 98;
   }
 }


class constructor demo{
    public static void main(String[] args){
       queen arth = new queen();
       queen y = new queen();

       System.out.println(arth.beauty+" "+y.beauty);

    }
} 

出力は次のとおりです。

98 98

コンストラクタは次のとおりです。

queen(){
beauty =98;
}

次に、パラメーター化されたコンストラクターの番です。

  class queen(){
   int beauty;

   queen(int x){ 
     beauty = x;
   }
 }


class constructor demo{
    public static void main(String[] args){
       queen arth = new queen(100);
       queen y = new queen(98);

       System.out.println(arth.beauty+" "+y.beauty);

    }
} 

出力は次のとおりです。

100 98
于 2016-01-06T13:46:45.273 に答える
1

クラスの内容と状態を設定するために使用されます。main メソッドを使用してより単純な例を作成できるのは事実ですが、アプリごとに 1 つの main メソッドしかないため、賢明なアプローチにはなりません。

プログラムを単純に開始する主な方法を考えてみてください。それを行う方法しか知らないはずです。また、main() は静的であるため、クラス インスタンスと関連付けられた状態を必要とする関数を呼び出すことはできません。main メソッドは new Program().function() を呼び出す必要があり、Program コンストラクターは、クラスのセットアップに必要な場合を除き、function() を呼び出さないでください。

于 2013-11-12T23:14:02.480 に答える
1

クラス定義は、クラスの API を定義します。つまり、クラスとそのクライアント (このクラスを使用する他のすべてのコード) の間に存在するコントラクトを定義する設計図です。コントラクトは、利用可能なメソッド、それらを呼び出す方法、および見返りとして何を期待するかを示します。

しかし、クラス定義は仕様です。このクラスの実際のオブジェクトを取得するまで、コントラクトは単なる「一枚の紙」です。ここでコンストラクターの出番です。

コンストラクターは、メモリ内にオブジェクトを作成し、それへの参照を返すことによって、クラスのインスタンスを作成する手段です。コンストラクターで発生する必要があるのは、オブジェクトに対する後続の操作が意味をなすために、オブジェクトが適切な初期状態にあることです。

コンストラクターから返されたこのオブジェクトは、クラス定義で指定されたコントラクトを尊重するようになり、このオブジェクトを使用して実際の作業を行うことができます。

このように考えてください。ポルシェのウェブサイトを見れば、馬力やトルクなど、どんなことができるかがわかります。しかし、実際にポルシェを運転するまでは楽しいものではありません。

それが役立つことを願っています。

于 2013-11-12T23:21:45.063 に答える
1

コンストラクタは、基本的にオブジェクトの作成時に変数を初期化するために使用されます

于 2015-02-24T08:03:36.353 に答える
1

コンストラクターは、変数とそれらを制御するメソッドを定義するだけのデータベースのように機能するのではないかと考えました

次に、コンストラクターで定義されていない変数とメソッドを使用するオブジェクトを見ました。したがって、私にとって最も理にかなった議論は、変数値の有効性をテストするものですが、クラスはコンストラクターで定義されていない変数とメソッドを作成できます-データベースのようではなく、蒸気の過圧バルブのようです機関車。車輪などを制御しません。

私が思っていたよりもはるかに少ない定義です。

于 2016-07-27T21:59:11.237 に答える
0

3 人の生徒の生徒の詳細を保存しているとします。この 3 人の学生は、sno、sname、sage の値が異なりますが、3 人の学生はすべて同じ学部 CSE に属しています。そのため、コンストラクター内で「dept」変数を初期化して、3 つの学生オブジェクトすべてがこの値を取得できるようにすることをお勧めします。

明確に理解するために、以下の簡単な例を参照してください。

class Student
{
    int sno,sage;
    String sname,dept;
    Student()
    {
        dept="CSE";
    }
    public static void main(String a[])
    {
        Student s1=new Student();
        s1.sno=101;
        s1.sage=33;
        s1.sname="John";

        Student s2=new Student();
        s2.sno=102;
        s2.sage=99;
        s2.sname="Peter";


        Student s3=new Student();
        s3.sno=102;
        s3.sage=99;
        s3.sname="Peter";
        System.out.println("The details of student1 are");
        System.out.println("The student no is:"+s1.sno);
        System.out.println("The student age is:"+s1.sage);
        System.out.println("The student name is:"+s1.sname);
        System.out.println("The student dept is:"+s1.dept);


        System.out.println("The details of student2 are");`enter code here`
        System.out.println("The student no is:"+s2.sno);
        System.out.println("The student age is:"+s2.sage);
        System.out.println("The student name is:"+s2.sname);
        System.out.println("The student dept is:"+s2.dept);

        System.out.println("The details of student2 are");
        System.out.println("The student no is:"+s3.sno);
        System.out.println("The student age is:"+s3.sage);
        System.out.println("The student name is:"+s3.sname);
        System.out.println("The student dept is:"+s3.dept);
    }
}

出力:

学生1の詳細は
学生番号:101
学生の年齢は:33
学生の名前は:ジョン
学生部門は:CSE 学生
2の詳細は
学生番号は:102
学生の年齢は:99
学生の名前は: Peter
学生 部門 :
CSE
_


于 2017-12-29T05:12:52.043 に答える
0

まず、2 つのコード スニペットでエラーを説明します。

最初のコード スニペット

public class Program
{
    public constructor() // Error - Return type for the method is missing
    {
        function();
    }        
    private void function()
    {
        //do stuff
    }   
    
    public static void main(String[] args)
    {
        constructor a = new constructor(); // Error - constructor cannot be resolved to a type
    }
}

上記のコードを見るとわかるように、コンストラクター名はクラス名と同じではありません。main()メソッドでは、戻り値の型を持たないメソッドからオブジェクトを作成しています。

2 番目のコード スニペット

public class Program
{
    public static void main(String[] args)
    {
        function(); // Error - Cannot make a static reference to the non-static method function() from the type Program
    }
    
    private void function()
    {
        //do stuff
    } 
}

このコード スニペットでは、 type から非静的メソッド function() への静的参照を作成しようとしていますがProgram、これは不可能です。

したがって、可能な解決策はこれです、

最初のコード スニペット

public class Program
{
    public Program()
    {
        function();
    }        
    private void function()
    {
        //do stuff
    }   
    
    public static void main(String[] args)
    {
        Program a = new Program();
        a.function();
    }
}

2 番目のコード スニペット

public class Program
{
    public static void main(String[] args)
    {
        Program a = new Program();
        a.function();
    }
    
    private void function()
    {
        //do stuff
    } 
}

最後に、コード スニペットの違いは、最初のコード スニペットのクラス名がクラス名と同じではないことです。

2 番目のコード スニペットでは、コンストラクターが定義されていません。

一方、コンストラクターの目的を理解するには、以下のリソースを参照してください。

https://docs.oracle.com/javase/7/docs/api/java/lang/reflect/Constructor.html

https://www.flowerbrackets.com/constructor-in-java/

于 2017-11-29T13:36:33.273 に答える