面向对象基础10(多态)

多态的定义

同一个类型的多个实例、在执行同一个方法,呈现出多种行为特征。

变态的定义

同一个类型的实例在执行统一个方法,但是个别对象呈现出变异的行为特征。

态的概念不是状态,而是行为

多态存在的意义

当Java执行方法时,方法的执行是动态绑定的:

方法总师执行该变量实际所指向对象的方法。

例1:

  1. public class Bird {
  2. public void fly(){
  3. System.out.println("Birds Flying");
  4. }
  5. }
  6. class Sparrow extends Bird{
  7. }
  8. class Ostrich extends Bird{
  9. @Override
  10. //用于报错,要求被修饰的方法必须重写父类方法,否则就报错
  11. //重写fly方法
  12. public void fly(){
  13. System.out.println("can not fly");
  14. }
  15. }
  1. public class Polymorphism {
  2. public static void main(String[] args) {
  3. //向上转型
  4. Bird b1=new Sparrow();
  5. Bird b2=new Ostrich();
  6. b1.fly();//动态绑定Sparrow的fly方法
  7. b2.fly();//动态绑定Ostrich中的fly方法
  8. }
  9. }

向上转型:子类对象可以直接赋值给父类对象;

自动完成

向下转型:父类变量赋值给子类变量;

强制转换完成——(类型)变量名

变量的类型

编译时类型:声明该变量指定的类型。

在Java的编译阶段,Java编译器只认编译时类型;

运行时类型(实际类型):该变量实际引用的对象的类型。

强制转换 例2:

  1. class Shape {
  2. public void draw(){
  3. System.out.println("画图");
  4. }
  5. }
  6. class rect extends Shape{
  7. public void info(){
  8. System.out.println("矩形");
  9. }
  10. }
  11. class circle extends Shape{
  12. public void round(){
  13. System.out.println("绕圈");
  14. }
  15. }
  16. public class Transform{
  17. public static void main(String[] args) {
  18. Shape s1=new rect();
  19. /*
  20. 在编译时s1是Shape类型不存在info方法
  21. 可以运行,但编译器无法调用
  22. */
  23. Shape s2=new circle();
  24. //此时s2无法调用circle类下的round方法,需要强制转换
  25. circle c=(circle) s2;
  26. c.round();
  27. }
  28. }
  • 只能在具有父子关系之间的变量进行强转,否则会产生编译错误。

  • 如果在具有继承关系的变量进行转化时,如果被转化变量的实际类型不是要转化的目标类型
    就会出现异常——ClassCastException

instanceof运算符的存在就是避免上述异常。

语法:变量名 instanceof 类型

作用:当变量所引用的对象是后面类或子类的实例时,该运算符返回true

该运算符只能在变异类型具继承关系时进行判断,否则会报错

该运算符可以保证:强转换的变量是可以转换的,避免ClassCastException

例:

  1. public class InstenceofTest {
  2. public static void main(String[] args) {
  3. //声明hello时使用Object类,这样Hello的变异类型是Object
  4. //Object是所有类的父类,但hello变量的实际类型是String
  5. Object hi = "hello";
  6. //String和Object类存在继承关系,可以用instanceof进行运算,结果返回true
  7. System.out.println("字符串是否是Object类的实例" + (hi instanceof Object));
  8. System.out.println("字符串是否是String类的实例" + (hi instanceof String));
  9. //Math和Object类存在继承关系,结果返回false
  10. System.out.println("字符串是否是Math类的实例" + (hi instanceof String));
  11. //String实现了Comparable接口,结果返回true
  12. var hello = "hello";
  13. System.out.println("字符串是否是Comparable接口的实例" + (hello instanceof Comparable));
  14. //String类与Math类不存在继承关系,编译无法运行
  15. System.out.println(hello instanceof Math);
  16. }
  17. }

一般的,当向下强制转换类的时候都需要运用instanceof进行判断