電子書籍の厳選無料作品が豊富!

いつも御世話になっています。

クラス作成時に、
オブジェクト型(クラス型)を変数として宣言している時がある気がするのですが、ClassB classB = new ClassB();
この場合の利点は何かあるのでしょうか?
普通に考えれば、この記述を宣言することで、この宣言がされているクラス自身が、ClassBの実体を持つことになり、このクラスだけで多数のクラスの実体を利用できるようになる。
と思ったのですが。

クラスとしては、
ClassA {
private ClassB classB = new ClassB();
}
という場合です。
ここで、private ClassB classB;でない理由:
むやみに、上記の書き方をすると、外部から書き換えられてしまう恐れがあるから、、なるべくその可能性を回避するため

宜しくお願いします。

A 回答 (7件)

>ClassBの実体を持つことになり、このクラスだけで多数のクラスの実体を利用できるようになる。


「ClassBの実体を持つことにより、このクラスでClassBそのものを利用できるようになる。」です。

>この場合の利点は何かあるのでしょうか?
これは
class ClassA {
private ClassB classB;
public ClassA() {
classB = new ClassB();
}
}
と同等です。

>ここで、private ClassB classB;でない理由:
>むやみに、上記の書き方をすると、外部から書き換えられてしまう恐れがあるから、、なるべくその可能性を回避するため
たとえば以下の場合なら正しいです。
class ClassA {
private ClassB classB = new ClassB();
public void add(String value) {
classB.add(value);
}
public String getString() {
return classB.getValue();
}
}
(ClassBにはadd、getStringというメソッドがあるとします。)
この場合ならclassBのインスタンスは変更できません。
メリットとしてはインスタンスを変更せずに内部の値(ClassBのフィールドの値)を特定の処理を行ってから設定、取得を行うことが出来るようになります。

privateでかつインスタンスを変更させたくない場合は
private ClassB classB = new ClassB();

private final ClassB classB = new ClassB();
に変えてしまった方がいいと思います。

この回答への補足

回答ありがとうございます。
遅くなりました。

丁寧な回答ありがとうございます。
インスタンス変数をnewしてしまったほうが見栄え上も良さそうですね。

だいたいの処理、がわかりました。

また、わからなければ質問させて頂きます。
宜しくお願いします。

補足日時:2009/07/24 01:45
    • good
    • 0
この回答へのお礼

遅くなり申し訳ありません。
皆さんの回答を読んで、大体理解できました。
ありがとうございました。

お礼日時:2009/09/06 19:11

他の方への返答を見ていると、どのように理解されたのか少し不安になります。



Javaでは、フィールドxを明示的に初期化せずに
ClassA {
private ClassB x;
}
と書いたら
ClassA {
private ClassB x = null;
}
と同じ意味になります。

xの値がnullのままではxに対してメソッドを呼び出したりすることができませんから、ClassAのインスタンスを生成した後に適切なタイミングでClassBのインスタンスへの参照をxに代入する必要があります。xに対して何も操作をしない場合であればnullのままでも構いませんが。

xに代入する値としては、new ClassB()以外にも
・ClassB型の他の変数やフィールドから値をコピーする
・ClassB型を返すメソッドの結果を代入する
などがあります。
ClassAのインスタンス生成ごとに毎回必ず新しいClassBのインスタンスを使うのであれば
ClassA {
private ClassB x = new ClassB();
}
の書き方でいいですが、逆に、new ClassB()以外の値を使うのであれば "= new ClassB()" の部分は不要というか、単に実行時間とメモリの無駄です。

この回答への補足

回答ありがとうございます。
今、思っているのはnew演算子を使用する場合は、
複数のメソッドで、毎回新しいインスタンスを作るなら、
一つにまとめて宣言してしまえば、忘れないし、実行時間とメモリを省略できる
ex)
public class ClassB {
public void setName() {
}
}

public class ClassA {
public void delete() {
private ClassB classB = new ClassB();
classB.setName();
}
public void update() {
private ClassB classB = new ClassB();
classB.setName();
}
public void add() {
private ClassB classB = new ClassB();
classB.setName();
}
}

public class ClassA {
private ClassB classB = new ClassB(); //複数箇所で利用されているので一つにまとめて宣言
public void delete() {
classB.setName();
}
public void update() {
classB.setName();
}
public void add() {
classB.setName();
}
}
といった感じで理解しています。
単に
private ClassB classB;
これは単なる「カタ」=容器のようなものなので、使用時にはインスタンス化する必要がある。
もし、使用する可能性があるかわからないときに、宣言する、といった感じなのですが。
=毎回、使用するのでないなら、使用時にインスタンス化した方がいい気はします。

宜しくお願いします。

補足日時:2009/07/27 21:25
    • good
    • 0
この回答へのお礼

遅くなり申し訳ありません。
何とか、みなさんの回答を読んで、大体の意味は理解できました。
ありがとうございました。

お礼日時:2009/09/06 19:08

ClassAのコンストラクタが2つ以上ある場合を考えてみましょう。



ClassA {
private ClassB classB = new ClassB();
private int x;

public ClassA() {
x = 10;
}
public ClassA(int i) {
x = i;
}
}

ClassA {
private ClassB classB;
private int x;

public ClassA() {
classB = new ClassB();
x = 10;
}
public ClassA(int i) {
classB = new ClassB();
x = i;
}
}
と同じ意味になります。
つまり、共通するフィールドclassBの初期化を1カ所にまとめることができて、書き忘れの防止になります。

この回答への補足

回答ありがとうございます。
遅くなりました。

丁寧な内容ありがとうございます。
見ている限り、一つにした方が、見栄えがよさそうですね。
「書き忘れの防止」ですか。その通りですね。

わかりました。
またわからなければ、質問させて頂きます。
宜しくお願いします。

補足日時:2009/07/24 01:50
    • good
    • 0
この回答へのお礼

遅くなり申し訳ありません。
皆さんの回答を読んで大体理解できました。
ありがとうございました。

お礼日時:2009/09/06 19:10

#2の一部修正



>publicなgetterがある、コンストラクタで設定する、とかいう話なら別ですが。



>publicなsetterがある、コンストラクタで設定する、とかいう話なら別ですが。

sとg間違え、意味がまったく逆になっちゃう。

この回答への補足

回答ありがとうございます。
遅くなりました。

>ここで、private ClassB classB;でない理由:
>むやみに、上記の書き方をすると、外部から書き換えられてしまう恐れがあるから、、なるべくその可能性を回避するため

???どういう意味でしょ?
ClassB classB = new ClassB();とClassB classB;の利用は、違うと思うのですが、
初期化するか、変数宣言するかで、どう違うのかがよくわかっていません。
手持ちのjavaの本を見ると、クラス型変数は、実体ではなく、参照するために使用される変数=ClassBにアクセスしてデータ代入等を行うなら
初期化してインスタンスを生成して代入すべき、と感じたのですが。

一応、コンストラクタもsetterも使用しない場合で考えています。

以上宜しくお願いします。

補足日時:2009/07/24 01:40
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
皆さんの回答を読んで、大体理解できました。
ありがとうございました。

お礼日時:2009/09/06 19:12

そもそも「new 宣言」ってなんだ. new は宣言じゃないぞ.


たぶん, このようについでに new する理由は次の 1点でしょう:
確実に「ClassB のオブジェクト」として確保する.
言い換えると「確保し忘れるのを防ぐ」ということだ.
#2 でも言われるように, 「private にする」こと自体が「むやみに外部から書き換えられるのを防ぐ」ためです. 基本的に, private なメンバを外部から直接アクセスすることはできません (リフレクションは「基本的」じゃない). で, 「むやみ」じゃない変更 (設定) 手段がコンストラクタだったり public な setter だったりします.

参考URL:http://javafaq.jp/S010.html

この回答への補足

回答ありがとうございます。
遅くなりました。

なるほど、
ClassB classB = new ClassB();と、ClassB classB;では、
前は「ClassB」のオブジェクトを確保し忘れないためで、
後は、ClassB型の変数、という感じなのでしょうか?

一般に、ClassB classB; クラス型変数は、参照する場合のみに使用する感じなのでしょうか?

むやみやたらに、外部書き換えを防ぐなら、「private」を使用すればいいんですね。

勉強になりました。
URL参考にさせて頂きます。

宜しくお願いします。

補足日時:2009/07/24 01:39
    • good
    • 0
この回答へのお礼

遅くなり申し訳ありません。
皆さんの回答を読んで、大体理解できました。
ありがとうございました。

お礼日時:2009/09/06 19:14

>ここで、private ClassB classB;でない理由:


>むやみに、上記の書き方をすると、外部から書き換えられてしまう恐れがあるから、、なるべくその可能性を回避するため

???どういう意味でしょ?

privateのフィールドの中身を外部(他のクラス?)からどうやって書き換えるんでしょうか?(リフレクションは除くとして)

publicなgetterがある、コンストラクタで設定する、とかいう話なら別ですが。
    • good
    • 0

> オブジェクト型(クラス型)を変数として宣言している時がある気がするのですが、ClassB classB = new ClassB();



これは「オブジェクト型の変数をあるクラス(例: ClassA)のインスタンス変数として宣言をして、かつそこでインスタンス化している」ということでしょうか?


> ClassBの実体を持つことになり、このクラスだけで多数のクラスの実体を利用できるようになる。

このように考えられる理由が今ひとつ分かりません。

この回答への補足

回答ありがとうございます。
遅くなりました。

質問の件ですが、
>これは「オブジェクト型の変数をあるクラス(例: ClassA)のインスタンス変数として宣言をして、かつそこでインスタンス化している」ということで>しょうか?
>>大体、そのような感じ、です。

> ClassBの実体を持つことになり、このクラスだけで多数のクラスの実体を利用できるようになる。
>>クラスのインスタンスを複数宣言した場合に、そのインスタンスを使用してクラスにアクセスができるようになる、といった意味です。

宜しくお願いします。

補足日時:2009/07/24 01:20
    • good
    • 0
この回答へのお礼

遅くなり申し訳ありません。
みなさんの回答を読んで、大体理解できました。
ありがとうございました。

お礼日時:2009/09/06 19:15

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!