作者:流川メイプルノックコード
ブログホームページ:流川楓のブログ
コラム:私と一緒にJavaを学ぼう
引用:ハングリーでいて、愚かでいて
良いことをしたいなら、まずツールを研ぎ澄ます必要があります.大手メーカーからのオファーを獲得するための超強力なツールを紹介しましょう-Niuke.com
記事ディレクトリ
アップキャスト: サブクラス オブジェクトを作成し、それを親クラス オブジェクトとして使用します。
ダウンキャスト: 親クラスの参照が子クラス オブジェクトに復元されます。
1.継承
1. 継承を理解するには?
クラスのインスタンス化によって生成されたオブジェクト間にいくつかの関連付けがある場合があります.継承とは、これらの共通性を抽出してコードの再利用を実現することです.
概念: 元のクラスの特性を維持したまま、拡張し、新しい機能を追加し、新しいクラスを生成するプロセス。このクラスは派生クラスと呼ばれます。
継承によって解決される主な問題は、共通の抽出とコードの再利用です。
2. 継承の構文
キーワード:拡張
フォーマット:
修饰符 class 子类 extends 父类 {
//...
}
サブクラスは、親クラスのメンバー変数またはメンバー メソッドを継承します。
サブクラスが親クラスを継承した後、独自の一意のメンバー、つまり親クラス以外の機能を追加する必要があります
class Animal{
public String name;
public int age;
public void eat() {
System.out.println(name+"吃饭");
}
}
class Dog extends Animal{
//新加的属性
public String silly;
public void houseGuard() {
System.out.println("看门");
}
}
class Cat extends Animal {
//没有添加新属性
public void catchMouse() {
System.out.println(name+"抓老鼠");
}
}
public class Test {
public static void main(String[] args) {
//name和age属性是从父类Animal中继承下来的
Dog dog = new Dog();
Cat cat = new Cat();
}
}
また、注意: Java では多重継承はサポートされていません。サブクラスは 1 つの親クラスしか継承できません。
3. サブクラスが親クラスのメンバーにアクセスする方法
3.1 メンバー変数へのアクセス
メンバー変数へのアクセスは近接の原則に従います。独自の優先順位がある場合は、親クラスで探します。
見つからない場合は、親クラスから継承したメンバー変数でアクセスするメンバー変数を探し、見つからない場合はコンパイルに失敗します
3.2 メンバーメソッドへのアクセス
メンバー メソッドには異なる名前があります。
自分自身へのアクセスを優先し、そうでない場合は親クラスから継承したものにアクセスします
メンバー メソッドは同じ名前です。
親クラスとサブクラスの同じ名前のメソッドのパラメータ リストが異なります (オーバーロード)。呼び出し元のメソッドから渡されたパラメータに従って、適切なメソッドを選択してアクセスします。そうでない場合は、エラーが報告されます。
3.3 スーパーキーワード
使用法: サブクラス メソッドで親クラスのメンバーにアクセスする
class Dog extends Animal{
public String silly;
public void houseGuard() {
System.out.println(super.name+"看门");
}
}
親クラスの名前は初期値が割り当てられていないためnullなので、同じ名前の親クラスのメンバー変数にアクセスします
this. 自問することが優先されます, そうでない場合, 親クラスから継承したアクセス
super. 直接アクセスは親クラスから継承されます. サブクラス メソッドでは、親クラスのメンバーに明示的にアクセスする場合は、super キーワードを使用できます.
要約:
super.data; 親クラスの通常のメンバー変数にアクセスする
super.func(); 親クラスの通常のメンバー メソッドにアクセスする
super(); 親クラスのコンストラクターにアクセスする
注: 上記の親クラスの通常のメンバー メソッドと変数は、非静的メンバー メソッドと変数を参照します。
4. サブクラス コンストラクター
サブクラス オブジェクトを構築するときは、最初に基本クラス コンストラクターを呼び出してから、サブクラス コンストラクターを実行する必要があります。
コードを見てください:
class Animal{
public String name;
public int age;
//提供一个两个该参数的构造方法
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
public void eat() {
System.out.println(name+"吃饭");
}
}
//此处报错
class Dog extends Animal{
public String silly;
public void houseGuard() {
System.out.println(super.name+"看门");
}
}
オブジェクトの初期化には、コンストラクターの呼び出しが必要です
2 つのパラメーターを持つコンストラクターを追加した後、コンパイラーはパラメーターなしのコンストラクターを提供しないため、エラー
次に、2 つのパラメーターを持つコンストラクターが提供された場合の初期化方法を見ていきます。
class Dog extends Animal{
public String silly;
public Dog(String name, int age, String silly) {
//先初始化父类部分
super(name, age);
this.silly = silly;
}
public void houseGuard() {
System.out.println(super.name+"看门");
}
}
super(name,age) は、最初に親クラスのコンストラクターを呼び出して初期化を完了します
this.silly = silly は自身のプロパティの初期化を完了します
要約:
1. 親クラスは引数なしまたはデフォルトのコンストラクターを明示的に定義し、サブクラスのコンストラクターの最初の行には、デフォルトで暗黙的な super() 呼び出しがあります。
2. 親クラスの構築メソッドにはパラメータがあります.この時点で、ユーザーはサブクラスの構築メソッドを明示的に定義し、サブクラスの構築メソッドで呼び出す適切な親クラスの構築メソッドを選択する必要があります.そうしないと、コンパイルが失敗します.
3. サブクラス コンストラクターで、super(...) がスーパークラス コンストラクターを呼び出す場合、それはサブクラス コンストラクターの最初のステートメントでなければなりません。
4. super(...) は、サブクラス コンストラクターで 1 回だけ使用でき、同時に使用することはできません。
5. 最後のキーワード
1. 変数またはフィールドを変更して定数を表す
2. 変更されたクラス: このクラスが継承できないことを示します
final で装飾された String String クラスは継承できません
3. 変更されたメソッド: メソッドをオーバーライドできないことを示します。
6. 継承と合成
継承と同様に、コンポジションもクラス間の関係を表現する方法であり、コードの再利用を可能にします
継承は、さまざまなクラスによって抽象化された共通性を表し、オブジェクト間の関係は is-a 関係です
構成は、全体、部分、および所有の関係、つまりhas -aの関係を反映します。
たとえば、車両と車両の組み合わせ:
class Tire {
public void run() {
System.out.println("轮胎转动");
}
}
class Light {
public void light() {
System.out.println("灯亮");
}
}
public class Vehicle {
private Tire tire;
private Light light;
public Vehicle(Tire tire,Light light) {
this.tire = tire;
this.light = light;
}
public void operation() {
light.light();
tire.run();
}
public static void main(String[] args) {
Tire tire = new Tire();
Light light = new Light();
Vehicle vehicle = new Vehicle(tire,light);
//灯亮
//轮胎转动
vehicle.operation();
}
}
2. ポリモーフィズム
1.多型を認識する
さまざまなオブジェクトが特定の動作を完了すると、さまざまな状態が生成されます。これはポリモーフィズムと呼ばれます。
例: モバイル決済中に生成されるポリモーフィズム
2. ポリモーフィズムの実装条件
1.相続制であること
2. サブクラスは、親クラスのメソッドをオーバーライドする必要があります
3. 親クラスの参照を通じてオーバーライドされたメソッドを呼び出す
ポリモーフィズムは次のように反映されます。コードが実行されると、異なるクラスのオブジェクトが渡されると、対応するクラスのメソッドが呼び出されます。
例えば:
class Animal{
public String name;
public int age;
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
public void eat() {
System.out.println(name+"吃饭");
}
}
class Dog extends Animal{
public String silly;
public Dog(String name, int age, String silly) {
super(name, age);
this.silly = silly;
}
@Override
public void eat() {
System.out.println(name+"吃狗粮");
}
public void houseGuard() {
System.out.println(super.name+"看门");
}
}
class Cat extends Animal {
public Cat(String name, int age) {
super(name, age);
}
@Override
public void eat() {
System.out.println(name+"吃猫粮");
}
//没有添加新属性
public void catchMouse() {
System.out.println(name+"抓老鼠");
}
}
public class Test {
public static void eat(Animal animal) {
animal.eat;
}
public static void main(String[] args) {
Dog dog = new Dog("dog",2,"silly");
Cat cat = new Cat("cat",3);
eat(dog);
eat(cat);
}
}
Test クラスの eat メソッドのパラメータは Animal です. メソッドは現在の a 参照がどのインスタンスを指しているかを認識していないか注意を払っていません. このとき, a 参照が eat メソッドを呼び出すとき, さまざまな表現が存在する可能性があります. (および a). 相関によって参照されるインスタンス)、この動作はポリモーフィズムと呼ばれます。
3.書き直す
概念: 戻り値と仮パラメータを変更できない サブクラスは、親クラスの非静的、非プライベートな変更、非最終的な変更、および非構築メソッドの実装プロセスを書き換えます。
オーバーライドの利点は、サブクラスが必要に応じて独自の特定の動作を定義できることです。つまり、サブクラスは必要に応じてスーパークラスのメソッドを実装できます
【メソッドオーバーライドルール】
サブクラスのメソッド プロトタイプはスーパークラスのメソッド プロトタイプと同じです。戻り値の型のメソッド名 (パラメータ リスト) はまったく同じでなければなりません。
オーバーライドされたメソッドの戻り値の型は異なる場合がありますが、親子関係が必要です
アクセス権は、親クラスのオーバーライドされたメソッドのアクセス権よりも低くすることはできません.親クラスのメソッドがパブリックによって変更された場合、サブクラスでオーバーライドされたメソッドは保護されていると宣言できません.
static および private によって変更された親クラスのメソッドとコンストラクターはオーバーライドできません
@Override アノテーションは正当性チェックの実行に役立ち、書き換えはエラーにはなりません
4. アップシフトとダウンシフト
アップキャスト: サブクラス オブジェクトを作成し、それを親クラス オブジェクトとして使用します。
//语法格式:父类类型对象名 = new 子类类型()
Animal animal = new Cat("cat",2);
使用する:
方法 1: 直接代入 (サブクラス オブジェクトを親クラス オブジェクトに代入)
public class Test {
public static void main(String[] args) {
Dog dog = new Dog("dog",2,"silly");
Animal animal = dog;
Animal animal1 = dog;
Animal animal2 = dog;
}
}
方法 2: メソッド パラメーターの転送 (仮パラメーターは、任意のサブクラスのオブジェクトを受け取ることができる親型への参照です)
public static void eat(Animal animal) {
animal.eat;
}
方法 3: メソッド return (戻り値として: 任意のサブクラス オブジェクトを返す)
public static Animal func(){
return new Cat("dog",2);
}
利点: コードの実装をよりシンプルかつ柔軟にする
不具合: サブクラス固有のメソッドを呼び出せない
ダウンキャスト: 親クラスの参照が子クラス オブジェクトに復元されます。
public class Test {
public static void main(String[] args) {
Animal animal = new Cat("haha",2);
if(animal instanceof Cat){
Cat cat = (Cat) animal;
cat.catchMouse();
}
}
}
ダウンキャストの安全性を向上させるために、instanceof が導入され、式が true の場合、安全にキャストできます
「この問題の共有はこちらです。ブロガーに 3 つのリンクを提供することを忘れないでください。あなたのサポートが私の創造の最大の原動力です!