package com.example.demo; import java.util.Objects; public class Test { public static void main(String[] args) { Animal animal = new Cat(); Animal a = new Dog(); Cat cat = new Cat(); cat.eat(); System.out.println(a.getClass()); animal.eat();//这里点击进去的是anmial的方法 Dog dog = (Dog) a; System.out.println(dog.getClass()); dog.eat(); } } class Animal { public void eat() { System.out.println("吃动物"); } public void work() { System.out.println("动物工作"); } } class Cat extends Animal { public void eat() { System.out.println("吃鱼"); } public void work() { System.out.println("抓老鼠"); } } class Dog extends Animal { public void eat() { System.out.println("吃骨头"); } public void work() { System.out.println("看家"); } }
吃鱼
class com.example.demo.Dog
吃鱼
class com.example.demo.Dog
吃骨头
同一个行为具有多个不同表现形式或形态的能力就是多态
重载式多态,也叫编译时多态。也就是说这种多态再编译时已经确定好了。重载大家都知道,方法名相同而参数列表不同的一组方法就是重载。在调用这种重载的方法时,通过传入不同的参数最后得到不同的结果。
重写式多态,也叫运行时多态。这种多态通过动态绑定(dynamic binding)技术来实现,是指在执行期间判断所引用对象的实际类型,根据其实际的类型调用其相应的方法。也就是说,只有程序运行起来,你才知道调用的是哪个子类的方法。 这种多态通过函数的重写以及向上转型来实现。
import java.util.ArrayList; import java.util.List; public class Composite { private final List<Composite> list; public void add(Composite c) { list.add(c); } final private String name; public Composite(String name) { this.list = new ArrayList<>(); this.name = name; } //多态 void printComposite() { System.out.println(name); for (Composite com : list) { com.printComposite(); } } public static void main(String[] args) { Composite CEO = new Composite("CEO"); Composite SubCeo1 = new Composite("SubCeo1"); Composite SubCeo2 = new Composite("SubCeo2"); Composite SubSubCeo1 = new Composite("SubsubCeo1"); Composite SubSubCeo2 = new Composite("SubsubCeo2"); Composite SubSubCeo3 = new Composite("SubsubCeo3"); Composite SubSubCeo4 = new Composite("SubsubCeo4"); SubCeo1.add(SubSubCeo1); SubCeo1.add(SubSubCeo2); SubCeo2.add(SubSubCeo3); SubCeo2.add(SubSubCeo4); CEO.add(SubCeo1); CEO.add(SubCeo2); CEO.printComposite(); } }
package com.example.demo; class A { public String show(D obj) { return ("A and D"); } public String show(A obj) { return ("A and A"); } } class B extends A{ public String show(B obj){ return ("B and B"); } public String show(A obj){ return ("B and A"); } } class C extends B{ } class D extends B{ } public class Demo { public static void main(String[] args) { A a1 = new A(); A a2 = new B(); B b = new B(); C c = new C(); D d = new D(); System.out.println("1--" + a1.show(b)); System.out.println("2--" + a1.show(c)); System.out.println("3--" + a1.show(d)); System.out.println("4--" + a2.show(b)); System.out.println("5--" + a2.show(c)); System.out.println("6--" + a2.show(d)); System.out.println("7--" + b.show(b)); System.out.println("8--" + b.show(c)); System.out.println("9--" + b.show(d)); } } //当父类对象引用变量引用子类对象时,被引用对象的类型决定了调用谁的成员方法,引用变量类型决定可调用的方法。如果子类中没有覆盖该方法,那么会去父类中寻找。
1--A and A
2--A and A
3--A and D
4--B and A
5--B and A
6--A and D
7--B and B
8--B and B
9--A and D
package com.example.demo; abstract class A { void sayA() { System.out.println("A"); } void sayB() { System.out.println("A"); } abstract void write(); } class B extends A { void sayB() { System.out.println("B"); } @Override void write() { System.out.println("write"); } } public class Demo { public static void main(String[] args) { A a = new B(); A b = new B(); a.sayA(); b.sayB(); a.write(); } }
A
B
write
A决定了解释器哪些可以调用,B决定了编译器哪些可以调用(实际运行时候调用的的),如果是A类抽象方法子类实现了则父类调用抽象方法即调用子类方法,个人理解