やあ!これまでのレッスンで、継承の概念についてはすでに簡単に理解しました。今日はこのトピックについてもう一度触れますが、これもあまり深くは考えません。これについては今後さらに詳しくレッスンする予定です。今日は、いくつかの実用的な例を簡単に見て、Java の興味深い演算子について説明します。
継承は、既存のクラスに基づいて新しいクラスを宣言できるようにするプログラミング メカニズム (Java を含む) です。その後、派生クラスは親クラスのフィールドとメソッドにアクセスできるようになります。なぜこれが必要なのでしょうか? プログラム内で、トラック、レースカー、セダン、ピックアップなどのいくつかの車のクラスを作成する必要があると想像してください。コードを記述する前でも、これらすべてのクラスには多くの共通点があることがわかります。すべての車にはモデルがあります。名前、製造年、エンジンサイズ、最高速度など(ホイールやその他の部品が共通しているという事実は言うまでもありません)。この状況では、次のことができます。
継承
では、継承とは何でしょうか?
- これらのフィールドをクラスごとに作成します (新しい車のクラスを作成するときにフィールドを追加します)。
- すべての車に共通のフィールドを
Car
親クラスに取り込み、キーワードextendsCar
を使用して、そのクラスから特定のタイプの車のすべてのクラスを派生します。
public class Car {
private String model;
private int maxSpeed;
private int yearOfManufacture;
public Car(String model, int maxSpeed, int yearOfManufacture) {
this.model = model;
this.maxSpeed = maxSpeed;
this.yearOfManufacture = yearOfManufacture;
}
}
public class Truck extends Car {
public Truck(String model, int maxSpeed, int yearOfManufacture) {
super(model, maxSpeed, yearOfManufacture);
}
}
public class Sedan extends Car {
public Sedan(String model, int maxSpeed, int yearOfManufacture) {
super(model, maxSpeed, yearOfManufacture);
}
}
少なくとも、コードの不必要な重複は避けます (プログラムを作成するときは、常にそのように努めるべきです)。さらに、すべての車両に共通するすべてのフィールドが 1 つのクラスに統合された、シンプルでわかりやすいクラス構造になっています。トラックに他の車両にはない特別なフィールドがある場合は、クラス内で宣言できますTruck
。メソッドについても同様です。すべての車には、メソッドで記述できる特定の共通の動作があります。たとえば、車の始動、加速/ブレーキなどです。これらの共通メソッドは親クラスに統合でき、特定の種類の車ごとに派生クラスで独自のアクションを定義できますCar
。 。
public class Car {
public void gas() {
// Accelerate
}
public void brake() {
// Brake
}
}
public class F1Car extends Car {
public void pitStop() {
// Only race cars make pit stops
}
public static void main(String[] args) {
F1Car formula1Car = new F1Car();
formula1Car.gas();
formula1Car.pitStop();
formula1Car.brake();
}
}
全車共通のメソッドをCar
クラスに追加しました。しかし、F1Car
「F1」レースカーを代表するクラスを見てください。ピットストップ (緊急の車両メンテナンスのための停止) はレースでのみ行われるため、この特定の機能を関連する派生クラスに追加しました。 
インスタンス演算子
Java には、オブジェクトが特定のクラスに基づいて作成されたかどうかを確認するための特別な演算子、instanceofがあります。チェックの結果に応じてtrueまたはfalseを返します。車の例のクラスを使用して、それがどのように機能するかを見てみましょう。
public class Truck extends Car {
public static void main(String[] args) {
Truck truck = new Truck();
System.out.println(truck instanceof Car);
}
}
出力: true オブジェクトがあり、すべてのトラックが車であるため、演算子はtrueinstanceof
を返します。クラスはクラスから派生します。すべてのトラックは、共通の親であるクラスに基づいて作成されます。演算子がどのように使用されているかをよく見てください。これはメソッド (「オブジェクトのインスタンス」) ではなく演算子であるため、ピリオドなしで記述します。別の方法を試してみましょう。 Truck
Truck
Car
Car
instanceof
public static void main(String[] args) {
Car car = new Car();
System.out.println(car instanceof Truck);
}
出力: false クラスCar
(および車オブジェクト) はクラスから派生しませんTruck
。すべてのトラックは自動車ですが、すべての自動車がトラックであるわけではありません。Car
オブジェクトはクラスに基づいていませんTruck
。もう 1 つの例:
public static void main(String[] args) {
Car car = new Car();
Truck truck = new Truck();
System.out.println(car instanceof Object && truck instanceof Object);
}
出力: True ここでのロジックも単純です。作成したクラスを含む Java のすべてのクラスは、そのObject
クラスから派生します (たとえ「extends Object」と書かなくても、それはすでに暗黙的に示されています)。これはいつ、どのように役立つのでしょうか? 演算子は、メソッドinstanceof
をオーバーライドするときに最も一般的に使用されますequals()
。たとえば、equals
メソッドがクラスに実装される方法は次のとおりですString
。
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String) anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
メソッドは、渡されたオブジェクトと を比較する前にString
、オブジェクトが文字列であるかどうかをテストします。その後初めて、2 つのオブジェクトのプロパティの比較が開始されます。このテストが存在しなかった場合、値フィールドと長さフィールドを持つオブジェクトはメソッドに渡され、文字列と比較される可能性がありますが、これはもちろん間違っています。
GO TO FULL VERSION