ポリモーフィズムとは何ですか? ?文字通り、複数の形式として理解されます。つまり、異なるクラスからインスタンス化されたオブジェクトが同じメソッドを呼び出します。また、異なるクラスのオブジェクトが同じ動作の後に異なる状態を生成することも理解できます。これがポリモーフィズムです。
ポリモーフィズムを理解するには、上向き変換と書き換えの 2 つの重要なポイントを理解してから、ポリモーフィズムの概念を深く理解する必要があります。上向き変換と書き換えを読んだ後、ポリモーフィズムの概念を見てみましょう。 、あなたは突然悟りを開き、一度に多くの明晰さを得るでしょう。ポリモーフィズムの条件は上方変換、書き換え、継承だからです。
まずポリモーフィズムの前提は継承ですが、継承なので親クラスとサブクラスの間には関係がなければなりません。
サブクラス オブジェクトと親クラス オブジェクトの作成方法を思い出してみましょう。
class Animal{ public String name;//名字 public int age; public void eat() { System.out.println("我要吃饭!!!"); } public void sleep() { System.out.println("我要睡觉!!!"); } } class Cat extends Animal{ public void mew() { System.out.println("喵喵喵!!!"); } } public class TestDemo1 { public static void main(String[] args) { Cat cat =new Cat();//实例化子类对象 cat.name="mimi"; Animal animal = new Animal();//实例化父类对象 animal.eat(); } }
ここで cat クラスが作成され、Animal クラスを継承します。 Cat オブジェクトと Animal オブジェクトをインスタンス化することで、メソッドとプロパティを呼び出すことができます。
それでは、上向きの変革とは何でしょうか? ? ?
元々、サブクラスのオブジェクトの参照がサブクラスのオブジェクトを参照していたのが、親クラスの参照がサブクラスのオブジェクトを参照するという上方変換です。
コードを使用して理解しましょう:
これは上方変換です。親クラス参照も使用できます。動物の Call メソッド;
# 現時点では、この参照を使用して親クラスのメソッドとプロパティを呼び出すことができますが、メソッドを呼び出すことはできないことがわかります。とサブクラスのプロパティがあるのに、なぜ? ? ?その理由は、親クラスのサブクラスにこのメソッドがないため、呼び出すことができないためです。概要: 上方変換中、親クラス参照はサブクラス オブジェクトを参照します。この親クラス参照は、親クラスの属性とメソッドのみを呼び出すことができますが、サブクラスは呼び出すことができません。
最初の形式: 直接代入
これが上で書いた方法です:
Animal animal1 = new Cat();//父类对象的引用 引用子类对象--->向上转型 Animal animal2 = new Dog();
2 番目の形式:メソッドのパラメータ:
3 番目の型は戻り値です:
出力された結果に戻りましょう。 ;
#しかし、親クラスのメソッドを変更して、キャットフードを食べたいと言うようにしたらどうなるでしょうか?その結果、mimi がキャットフードを食べたがるのも不思議ではありません。
しかし、これは問題を引き起こします。犬クラスを作成してから、eat メソッドを呼び出した場合、犬もキャットフードを食べる必要があるのでしょうか?これでは問題が発生するため、サブクラスに Eat メソッドを記述します。
class Animal{ public String name;//名字 public int age; public void eat() { System.out.println(this.name+"要吃饭!!!"); } } class Dog extends Animal{ public void dark() { System.out.println("汪汪汪!!!"); } public void eat() { System.out.println(this.name+"吃狗粮!!!"); } } class Cat extends Animal{ public void mew() { System.out.println("喵喵喵!!!"); } public void eat() { System.out.println(this.name+"吃猫粮!!!"); } } public class TestDemo1 { public static void main(String[] args) { //语法形式 : 父类 变量 = new 子类(); Animal animal1 = new Cat();//父类对象的引用 引用子类对象--->向上转型 Animal animal2 = new Dog();//父类对象的引用 引用子类对象--->向上转型 animal1.name = "小猫";//访问父类属性 animal2.name = "小狗";//访问父类属性 animal1.eat(); animal2.eat(); // animal.mew();//访问子类特有的方法 } }
この時点では、dog クラスが作成され、2 つのサブクラスに 2 つの Eat メソッドが作成されます。
# この時点で、私たちが望んでいた効果を達成することが非常に明確になったことがわかりました。
しかし、もう一度考えてみましょう。なぜ親クラスではなくサブクラスの Eat メソッドを呼び出すのでしょうか?
動的バインディングはこの時点で実際に発生します。バイトコード ファイルを確認して PowerShell ウィンドウを開くことができます
##プログラムを実行するには、まずコンパイルしてから実行する必要があることは誰もが知っています。コンパイル時に動物の Eat メソッドが呼び出され、実行時に cat メソッドが呼び出されます。これが私たちが行うことです。ランタイム バインディング、または動的バインディングと呼ぶこともできます。
次に、動的バインディングがあるため、静的バインディングも存在する必要があります。
動的バインディングはコンパイル時にメソッドを呼び出し、最終的に呼び出されるメソッドは実行時に決定されます。つまり、呼び出されるメソッドは実行時に決定されます。
静的バインディングとは、呼び出すメソッドがコンパイル中に決定されることを意味します。
その中で、動的バインディングの最も明白な代表的なものはメソッドの書き換えです。
静的バインディングの最も明白な代表例は、メソッドのオーバーロードです。
上記のメソッドを振り返ってみましょう ε=(´ο`*)))...なぜ前の Eat メソッドの戻り値、パラメータリスト、メソッド名がすべて同じなのか Woolen布?見てみましょう。
メソッドのオーバーロードについては前に学習しました。メソッドのオーバーロードについて復習しましょう。メソッドのオーバーロードとは、メソッド名が同じであり、戻り値が同じであることを意味します。値が異なるため、リクエストを行う際のパラメータリストが異なります。今日学んだメソッドの書き換えとは、戻り値が同じ、メソッド名が同じ、パラメータリストが同じということをメソッド書き換えと言いますが、メソッドの上書きとも言えます。
メソッドの書き換えにはいくつかの要件があります。
メソッドの書き換えでは、同じメソッド名、同じメソッド パラメーター リスト、および同じメソッド戻り値が必要です。
ワンクリックでリライトを生成することもできます
有几个注意事项:
不能重写被private修饰的方法。
不能重写被final修饰的方法。
子类的方法的访问权限一定要大于等于父类的访问权限。
重写的方法, 可以使用 @Override 注解来显式指定. 有了这个注解能帮我们进行一些合法性校验. 例如不小心将方法名字拼写错了 (比如写成eat), 那么此时编译器就会发现父类中没有 aet 方法, 就会编译报错, 提示无法构成重写.
被static修饰的方法也不能被重写
总结方法重写的注意事项:
被private,final修饰的方法不能被重写。
被staitc修饰的方法也不能被重写。
@override 可以检查你重写的方法名是否正确,最好要加上。
方法重写一定满足方法名相同,参数列表相同,返回值相同。
对比方法重写与方法重载:
最后:重写不是进行在原来基础的修改,而是在原来基础上进行迭代和更新。
场景:画一个图形
class Shape{//创建一个图形类---->作为多种图形的父类 public int length;//图形的长 public int wide;//图形的宽 public int height;//图形的高 public void draw() { System.out.println("我要画一个图形!!!"); } } class rectangle extends Shape{//长方形 @Override public void draw() { System.out.println("我要画一个长方形!!!"); } } class square extends Shape{ @Override public void draw() { System.out.println("我要画一个正方形!!!"); } } class circular extends Shape{ @Override public void draw() { System.out.println("我要画一个圆形!!!"); } } public class TestDemo1 { public static void method(Shape shape) { shape.draw(); } public static void main(String[] args) { Shape shape1 = new circular(); Shape shape2 = new rectangle(); Shape shape3 = new square(); method(shape1); method(shape2); method(shape3); } }
创建一个Shape(父类),然后创建三个子类分别是square ,circular,rectangle,利用父类引用这三个子类,接着调用method方法。
这就是多态,不同的对象,调用同一个方法最后结果产生出不同的状态。
我们再来总结多态产生的条件:
要在继承体系下
子类要对父类的方法进行重写
通过父类的引用调用重写的方法
也就是 在继承体系下 进行向上转型 和 方法重写
优点:
能够降低代码的 "圈复杂度", 避免使用大量的 if - else
如果使用多态, 则不必写这么多的 if - else 分支语句, 代码更简单.
可扩展能力更强
缺点:
代码的运行效率降低
还有一个重要点就是不要在构造方法中调用重写方法
以上がJava オブジェクト指向ポリモーフィック インスタンス分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。