2016-05-18 10 views
0

JavaとOOPの新機能はここにあります。Javaでのオブジェクト作成の流れはどのようになりますか?

オブジェクトのメンバーがいつ使用できるかを理解しようとしています。具体的には、クラス内でインスタンス変数を呼び出すときに、インスタンス変数をコンストラクタに渡すことができないのはなぜですか?以下のコード例:

public class Point { 

    public String name; 

    { 
     name = "Henry"; 
    } 

    public Point() 
    { 
     this(this.name); // cannot reference this before supertype constructor has been called 
    } 

    public Point(String name) 
    { 
     this.name = name; 
    } 

} 

このような何かをする前に頼まれましたが、私はここで説明するよ何Googleに依頼する方法を知りませんでした。オブジェクト参照がまだ作成されていないので、this(this.name)コール内でthis.nameを参照することはできませんが、コンストラクタをどのように呼び出しているのですか?オブジェクトは、new Point()使用して作成された時点でのオブジェクトの参照利用できるようになりますし、コンパイラは文句を言うために何を持っていないだろうというとき

そのコンストラクタが実行されようとしている唯一の時間です。変数にthis.nameを割り当てて、それをthis(variable)に渡すことができれば、それはうまくいかないでしょうか?大きな違いは何ですか?私はここで何かを完全に誤解している。

これは明らかに間違っていた、私はそれを視覚化しています方法です:

Point myPoint = new Point();

myPoint.name今あなたが達成できthis(this.name) // which should be "Henry"

+0

ボーリングの詳細は、主にhttps://docs.oracle.com/javase/specs/jls/se8/html/jls-12.htmlに記載されています(あなたの場合、スーパークラスがそれを宣言していればどうなるでしょうか?あなたが何かを使う前にスーパーが走っていなければならない理由は大体です) – zapl

+0

'new Point()'を実行すると 'new'のようなものが'ちょうどヒープ上に構築された「ポイント」オブジェクト(すべてのインスタンス変数/参照を保持するちょっとしたメモリ/ https://dzone.com/articles/java-object-memory)があります。最初に 'Object'を作成するつもりはありません。それは直接「ポイント」です。しかし、 'Point'は' Object'(継承を介して)なので、 'Object'コンストラクタはそれが期待するものを見つけるでしょう。したがって、あなたが '伸びる 'ときにあなたは持ち去ることができません。 – zapl

答えて

1

そのコンストラクタが実行されようとしている唯一の時間であり、コンパイラは文句を何も持っていません約。

私はここでのキーポイントは、オブジェクト参照がコンストラクタが呼び出された後にのみ利用可能であることであることを言うと思います。したがって、中にこのを参照すると、コンストラクタの操作は実際には意味をなさない。

また、継承を使用すると、特定のオブジェクトがインスタンス化/作成される前に複数のコンストラクタを呼び出すことができます。たとえば:

public class ParentPoint { 
    public String name = "Parent Point"; 

    public ParentPoint() { 
     // do something 
    } 
} 

public class Point extends ParentPoint { 

    public Point() { 
     super(); 
     // do something else 
    } 

} 

この場合、あなたはポイントが完全にインスタンス化される前に呼び出される2つのコンストラクタを持っています(そのため、あなたのOPに言及流れは常にその簡単ではありません)。

ザビエル・シルバの答えコードが良いものであり、また、ゲッターとセッターを持つことが、あまりにも理想的である:

public class Point { 

    public String name = "Henry"; 

    public Point() { 

    } 

    public Point(String name) { 
     this.name = name; //changes current value (Henry) to the one sent as an argument. 
    } 

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

    public String getName() { 
     return this.name; 
    } 


    public static void main(String[] args) { 
     Point pointA = new Point(); 
     Point pointB = new Point("Other name"); 

     System.out.println(pointA.name); // Henry 
     System.out.println(pointB.name); // Other name 

     pointA.setName("New name"); 
     System.out.println(pointA.getName()); // New name 
    } 
} 

最終ビットがゲッターとセッターを示し、コードの残りの部分はそのままです。

+0

ありがとうございます。もう少し読んで、コンストラクタの実行後にオブジェクトが初期化されることを理解しています。 'this()'の中で 'this.name'を参照することはできませんでした。スーパークラスのコンストラクタを実行する前に参照を操作しようとしているからです。私は、コンストラクタが他のコンストラクタと1つだけにチェーンできることも発見しました。だから 'this()'が ''() ''を指していた '' Point(String name) ''を期待する '' super() 'の代わりに' 'this(this.name) 'this.name'はコンストラクタが' super() 'を実行する前です。それは正しいですか? –

+0

遅れのためのお詫び - 私はあなたのコメントのいくつかの側面について少し不明ですが、はい、あなたが言うことは全体的に正しいようです。 –

0

を実行し、Point()コンストラクタ内"Henry"

に等しいです。あなたの目標は、この(this.name)コンストラクタを空にすることによって - 空のコンストラクタを呼び出す - new Point() - naを残す私はHenryとして、他のコンストラクタを使用しています。新しいPoint( "Bob") - その名前( "Bob")を名前として設定します。

私はあなたも、最初の "this"を "super"に置き換えてやるといいと思います。

2

それは少し混乱しているので、これはあなたの質問に完全に答えるかどうかは知りませんが、私は自分のベストを与える:

あなたはPoint point = new Point();のように、newオペランドを使用して新しいオブジェクトを作成するために。 オブジェクトには属性が含まれている必要がありますが、public String name;を作成するときにはそれを正しく開始しました(ただし、パブリックではないので検索する必要があります)。属性にデフォルト値を割り当てる必要がある場合は、宣言の直後に行う必要があります(例:public String name = "Henry";)。この問題を解決するためにJava定数を検索することもできます。

このコードは、あなたがしたい(と思う)か理解:あなたは空のオブジェクト(new Point();)と名称「その他の名称」(new Point("Other name");)との1のインスタンス化を見つけることができます。このコードでは

public class Point { 

    public String name = "Henry"; 

    public Point() { 

    } 

    public Point(String name) { 
     this.name = name; //changes current value (Henry) to the one sent as an argument. 
    } 


    public static void main(String[] args) { 
     Point pointA = new Point(); 
     Point pointB = new Point("Other name"); 

     System.out.println(pointA.name); 
     System.out.println(pointB.name); 
    } 
} 

を実行すると、両方のインスタンス化の違いがわかります。

これはあなたを助けますように!

編集: P.S.また、getter/setterについて検索することもできます。オブジェクトは、その時点でオブジェクト参照がを利用できるようになり、新たなポイント()、を使用して作成されたときに

+0

これはすばらしい答えですが、長いルートを利用したい場合は、この問題に関する詳細な文書を見つけることができます。 https://docs.oracle.com/javase/tutorial/java/concepts/ –

関連する問題