除封装和继承之外,面向对象程序设计的第三个支柱。简单来说,多态意味着父类型的变量可以引用子类型的对象
多态:同一个行为具有不同表现形式或形态的能力,即对象多种表现形式的体现,例如子类的实例也可作为父类的实例(Student类是Person类的子类,则一个Student的对象便既是Student,也是Person)
-
定义与使用格式
定义格式:父类类型 变量名=new 子类类型();
例如,通过Object p = new Person(); 代码定义一个变量p
-
多态中成员的特点
成员变量:
Father f=new Son(); System.out.println(f.num);//f是Father中的值,只能取到父中的值
成员方法:
Father f1=new Son(); System.out.println(f1.show());//f1的门面类型是Father,但实际类型是Son,所以调用的是重写后的方法。
例如Object p = new Person();中的变量p只能调用Person类的方法,只能访问Object类的属性
如图所示,扫描二维码可以对映三种不同的支付方式
-
//支付抽象类或者接口 public abstract class Pay { abstract public String pay(); } //支付宝支付 public class AliPay extends Pay { @Override public String pay() { System.out.println("支付宝pay"); return "success"; } } //微信支付 public class WeixinPay extends Pay { @Override public String pay() { System.out.println("微信pay"); return "success"; } } //银联支付 public class YinlianPay extends Pay { @Override public String pay() { System.out.println("银联支付"); return "success"; } } //测试支付 public static void main(String[] args) { //支付宝支付 Pay pay = new AliPay(); pay.pay(); //微信支付 pay = new WeixinPay(); pay.pay(); //银联支付 pay = new YinlianPay(); pay.pay(); } 输出结果如下: 支付宝pay 微信pay 银联支付 -
多态产生的必要条件
- 继承
- 重写
- 父类引用指向子类对象
-
对象转换和instanceof操作符
对象转换:一个对象的引用可以类型转换为对另外一个对象的引用
-
隐式转换
将对象 new Student() 赋值给一个 Object 类型的参数→ Object o = new Student();
由于Student的实例也是Object的实例,所以语句合法。
-
显式转换
Object o = new Student(); Student b = o;//编译错误
编译错误原因:通过隐式转换虽然看上去o是一个Student的实例,但是本质仍然为Object,故不能赋值给Student类型的b
//将(目标对象的类型)放到要转换的对象前面 Object o = new Student(); Student b = (Student)o;
-
向上转换(多态本身就是向上转型过的过程)
将子类的实例转换为父类的变量
父类类型 变量名=new 子类类型();
-
向下转换(使用(子类名)进行显示转换)
将父类的实例转换为子类变量
子类类型 变量名=(子类类型) 父类类型的变量;
-
-
instanceof操作符
instanceof操作符:用来判断某个对象是否属于某种数据类型,返回值为布尔类型
- 多态的优点
- 可替换性。多态对已存在代码具有可替换性。例如,多态对圆Circle类工作,对其他任何圆形几何体,如椭圆,也同样工作。
- 可扩充性。多态对代码具有可扩充性。增加新的子类不影响已存在类的多态性,继承性,以及其他特性的运行和操作。实际上新加子类更容易获得多态功能。例如,对等边三角形的操作,不会影响直角三角形
- 接口性。多态是超类通过方法签名, 向子类提供了一个共同接口,由子类来完善或者覆盖它而实现的。
- 灵活性。它在应用中体现了灵活多样的操作,提高了使用效率。
- 简化性。简化了对应用软件的代码编写和修改过程,尤其在处理大量对象的运算和操作时,这个特点尤为突出和重要。
//实例
public class A {
public String show(D obj) {
return ("A and D");
}
public String show(A obj) {
return ("A and A");
}
}
public class B extends A{
public String show(B obj){
return ("B and B");
}
public String show(A obj){
return ("B and A");
}
}
public class C extends B{
}
public class D extends B{
}
public class Test {
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));
}
}
//摘自https://blog.csdn.net/thinkGhoster/article/details/2307001
//运行结果 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



