やあ!私たちは引き続き、Java のネストされたクラスのトピックを調査していきます。前回の演習では、内部クラスとも呼ばれる非静的入れ子クラスについて説明しました。今日は、別のクラスのグループに移ります。静的ネストされたクラスについて考えてみましょう。他のクラスとどう違うのですか?この種のクラスを宣言するときは、すでによく知られている static キーワードを使用します。
public class Boeing737 {
private int manufactureYear;
private static int maxPassengersCount = 300;
public Boeing737(int manufactureYear) {
this.manufactureYear = manufactureYear;
}
public int getManufactureYear() {
return manufactureYear;
}
public static class Drawing {
public static int getMaxPassengersCount() {
return maxPassengersCount;
}
}
}
Boeing737
この例には、このタイプの飛行機を表す外側のクラスがあります。これには、製造年 ( int manufactureYear
) という 1 つのパラメーターを持つコンストラクターがあります。最大乗客数 ( ) という静的変数も 1 つありますint maxPassengersCount
。同じモデルのすべての平面で同じ値を持つため、必要なインスタンスは 1 つだけです。さらに、静的に入れ子になったクラスがあります: Drawing
(飛行機の工学設計図を表す)。このクラスを使用して、航空機に関するすべての公式情報をカプセル化します。この例では、わかりやすくするためにこのクラスを製造年に限定していますが、他の多くの情報が含まれる可能性があります。 前回のレッスンで述べたように、このような入れ子になったクラスを作成すると、カプセル化が改善され、より現実的な抽象化に貢献します。静的ネストされたクラスと非静的ネストされたクラスの違いは何ですか? 1. 静的Drawing
クラスのオブジェクトは、外部クラスの特定のインスタンスへの参照を格納しません。前回のレッスンの自転車の例を思い出してください。
public class Bicycle {
private String model;
private int maxWeight;
public Bicycle(String model, int maxWeight) {
this.model = model;
this.maxWeight = maxWeight;
}
public void start() {
System.out.println("Let's go!");
}
public class Handlebar {
public void right() {
System.out.println("Steer right!");
}
public void left() {
System.out.println("Steer left!");
}
}
}
Handlebar
そのレッスンでは、内部クラスの各インスタンスが、私たちには気づかれないように、外部クラスのインスタンスへの参照を渡すという 事実について話しましたBicycle
。外部クラスのインスタンスがなければ、内部クラスのオブジェクトは存在できません。静的ネストされたクラスの場合、これは当てはまりません。静的ネストされたクラスのオブジェクトは、完全に単独で存在できます。この点において、静的クラスは非静的クラスよりも「独立性」が高くなります。知っておく必要がある唯一のことは、そのようなオブジェクトを作成するときに、外部クラスの名前を指定する必要があるということです。
public class Main {
public static void main(String[] args) {
Boeing737.Drawing drawing1 = new Boeing737.Drawing();
Boeing737.Drawing drawing2 = new Boeing737.Drawing();
}
}
Drawing
前回のレッスンでクラスを静的に したのはなぜですかSeat
クラス (自転車のシートを表す) は非静的ですか? 前回と同様に、例を理解するために少し「哲学」を追加しましょう :) 自転車のシートとは異なり、設計図面の概念は航空機の概念に厳密に結び付けられていません。自転車がなければ、別個の自転車シート オブジェクトはほとんどの場合意味がありません (ただし、常にではありませんが、これについては前回のレッスンで説明しました)。設計図面の概念はそれ自体で意味を成します。たとえば、飛行機のメンテナンスを計画しているエンジニアに役立つ可能性があります。計画を立てるのに飛行機は必要なく、どこにでも配置できます。必要なのは設計図のみです。さらに、同じモデルのすべての航空機には同じ設計図面が使用されるため、自転車のシートのように密接な関係はありません。したがって、Drawing
オブジェクトは特定の飛行機オブジェクトへの参照を必要としません。2. 外部クラスの変数とメソッドへの異なるアクセス。静的にネストされたクラスは、外部クラスの静的フィールドにのみアクセスできます。この例では、クラスには、外部クラスの静的変数の値を返すメソッドがDrawing
あります。ただし、クラス内に の値を返すメソッドを作成することはできません。結局のところ、変数は非静的です。つまり、 の特定のインスタンスに属している必要があります。そして、すでに発見したように、静的に入れ子になったクラスの場合、外側のクラスのオブジェクトが簡単に存在しない可能性があります。したがって、制限があります:) 静的変数が外部クラスにどのアクセス修飾子を持っているかは関係ありません。たとえそうだったとしてもgetMaxPassengersCount()
maxPassengersCount
getManufactureYear()
Drawing
manufactureYear
manufactureYear
Boeing737
private
、静的なネストされたクラスは引き続きアクセスできます。上記はすべて、静的変数へのアクセスだけでなく、静的メソッドにも当てはまります。 重要!内部クラスの宣言では、static
キーワードはオブジェクトを 1 つだけ作成できるという意味ではありません。オブジェクトと変数を混同しないでください。静的変数について話している場合、はい、静的クラス変数のインスタンスが 1 つ存在します (例: ) maxPassangersCount
。ただし、 がstatic
ネストされたクラスに適用される場合、それはそのオブジェクトに外部クラスのオブジェクトへの参照が含まれていないことだけを意味します。そして、オブジェクト自体は必要なだけ作成できます。
public class Boeing737 {
private int manufactureYear;
private static int maxPassengersCount = 300;
public Boeing737(int manufactureYear) {
this.manufactureYear = manufactureYear;
}
public int getManufactureYear() {
return manufactureYear;
}
public static class Drawing {
private int id;
public Drawing(int id) {
this.id = id;
}
public static int getPassengersCount() {
return maxPassengersCount;
}
@Override
public String toString() {
return "Drawing{" +
"id=" + id +
'}';
}
public static void main(String[] args) {
for (int i = 1; i < 6; i++) {
Boeing737.Drawing drawing = new Boeing737.Drawing(i);
System.out.println(drawing);
}
}
}
}
ネストされたクラスでメソッドを直接宣言しmain()
(これに特別な理由はありません。これが可能であることを知らせるだけです)、5 つのDrawing
オブジェクトを作成しました。外部クラスのオブジェクトが 1 つも存在しないにもかかわらずです。ご覧のとおり、これによって問題は発生しませんでした:) コンソール出力:
Drawing{id=1}
Drawing{id=2}
Drawing{id=3}
Drawing{id=4}
Drawing{id=5}
これでレッスンは終わりです。念のため、Oracle ドキュメントのそれらに関するセクションへのリンクを残しておきます。まだ不明な点がある場合は、読んでください。今度は、いくつかのタスクを解決する番です。:)
GO TO FULL VERSION