web-dev-qa-db-ja.com

Javaのコンストラクタの目的は?

コンストラクターの目的は何ですか?私は学校で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
    }
}

コンストラクターの目的は私を逃れますが、それでも私たちがこれまでやってきたことはすべて非常に初歩的なものです。

19
gator

コンストラクターは、クラスのインスタンスを初期化するために使用されます。多くの場合、コンストラクターを使用して、オブジェクトに関する初期状態またはその他の重要な情報を指定するパラメーターを持つ新しいオブジェクトを作成します。

公式Javaチュートリアル

クラスには、クラスブループリントからオブジェクトを作成するために呼び出されるコンストラクターが含まれます。コンストラクター宣言はメソッド宣言のように見えますが、クラスの名前を使用し、戻り値の型を持たない点が異なります。たとえば、自転車には1つのコンストラクターがあります。

_public Bicycle(int startCadence, int startSpeed, int startGear) {
    gear = startGear;
    cadence = startCadence;
    speed = startSpeed;
}
_

myBikeという名前の新しい自転車オブジェクトを作成するには、new演算子によってコンストラクターが呼び出されます。

自転車myBike = new Bicycle(30、0、8);

new Bicycle(30, 0, 8)は、オブジェクト用にメモリ内にスペースを作成し、そのフィールドを初期化します。

Bicycleにはコンストラクターが1つしかありませんが、引数なしのコンストラクターなど、他のコンストラクターを含めることができます。

public Bicycle(){gear = 1;ケイデンス= 10;速度= 0; }

Bicycle yourBike = new Bicycle();は、引数なしのコンストラクターを呼び出して、yourBikeという新しいBicycleオブジェクトを作成します。

45
LotusUNSW

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

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

_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;
     }
}
_

上記のコードでは、冗長な処理を行っているように見えますが、実際は、番号が何であれ常に有効であることを保証しています。

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

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

別の例を次に示します。

_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のインスタンスを持つことはできません。

29
Akira

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

例:

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

_class Animal{
   private String name;
   private String type;
}
_

Animalクラスのインスタンス、たとえばDogという名前のPuppyを作成しようとするとどうなるかを見てみましょう。ここで、_name = Puppy_および_type = Dog_を初期化する必要があります。だから、どうすればそれを行うことができます。それを行う方法は、次のようなコンストラクタを持つことです

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

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

今、あなたは私が私のコンストラクタに何かのような引数を提供しなかったらどうするか尋ねるかもしれません

_Animal xyz = new Animal();
_

これは、オブジェクトをデフォルト値で初期化する_default Constructor_です。つまり、Animalクラスのnameおよびtypeオブジェクトに対応するxyz値は_name = null_および_type = null_

9
Prateek

コンストラクターは、作成時にオブジェクトを初期化します。クラスと同じ名前を持ち、構文的には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
4
Ashish Thapa
  • コンストラクター(パラメーター付き)を使用して、必要な依存関係についてそのクラスのユーザーに「質問」できます。
  • インスタンス変数を初期化するために使用されます
  • スーパークラス(super(...))のコンストラクターに引数を渡すため、基本的に同じことを行います
  • instance initializer scopeとは対照的に、例外をスローする可能性のあるコードで(最終)インスタンス変数を初期化できます。
  • ローカルまたは派生クラスで初期化が完了/十分でない可能性があるため、コンストラクターからメソッドを盲目的にnot呼び出す必要があります。
3
Sam

Javaコンストラクターは、それが属するクラスの名前と同じ名前を持っています。

コンストラクターは値を返さないため、コンストラクターの構文には戻り値の型は含まれません。

コンストラクターは、オブジェクトの作成時に常に呼び出されます。 例:-デフォルトのコンストラクター

class Student3{  
    int id;  
    String name;  
    void display(){System.out.println(id+" "+name);}  
    public static void main(String args[]){  
        Student3 s1=new Student3();  
        Student3 s2=new Student3();  
        s1.display();  
        s2.display();  
    }  
} 

出力:

0 null
0 null

説明:上記のクラスでは、コンストラクターを作成しないため、コンパイラーはデフォルトのコンストラクターを提供します。ここでは、デフォルトのコンストラクターによって0およびnull値が提供されます。

パラメーター化されたコンストラクターの例

この例では、2つのパラメーターを持つStudentクラスのコンストラクターを作成しました。コンストラクターには任意の数のパラメーターを含めることができます。

class Student4{  
    int id;  
    String name;  
    Student4(int i,String n){  
        id = i;  
        name = n;  
    }  
    void display(){System.out.println(id+" "+name);}  
    public static void main(String args[]){  
        Student4 s1 = new Student4(111,"Karan");  
        Student4 s2 = new Student4(222,"Aryan");  
        s1.display();  
        s2.display();  
    }  
}  

出力:

111 Karan
222 Aryan
1
Naresh Kumar

コンストラクターは、インスタンスが非現実的な値を取得するのを防ぐのに役立ちます。例として、身長、体重でPersonクラスを設定します。 0mと0kgの人はいられません

1
rinjan

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

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

1
andy.xyz

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

1

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

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

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

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

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

お役に立てば幸いです。

1
Vidya

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

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

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

1
user6646964

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

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

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);
    }
}

出力:

Student1の詳細は
学生番号:101
学生の年齢:33
学生名は次のとおりです。ジョン
学生部:CSE
student2の詳細は
学生番号:102
学生の年齢は:99
学生名:Peter
学生部:CSE
student2の詳細は
学生番号:102
学生の年齢は:99
学生名:Peter
学生部:CSE

0
user9151823

まず、最初に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
    } 
}
_

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

可能な解決策はこれです、

最初のコードスニペット

_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

http://www.flowerbrackets.com/learn-constructor-in-Java/

http://www.flowerbrackets.com/Java-constructor-example/

0
Shiva