当前位置: 首页 > article >正文

03_面向对象高级_多态

多态

1. 什么是多态?

“多态” 是在 “继承” 的基础上实现的一种现象,具体表现为:对象多态、行为多态。

public class HelloWorld {
    public static void main(String[] args) {
        // 1. 对象多态
        Human h1 = new Student();
        Human h2 = new Teacher();

        // 2. 行为多态
        h1.run();  // 学生跑得贼快~~
        h2.run();  // 老师跑得贼快~~
    }
}

class Human {
    public void run() {
        System.out.println("人会跑步~~");
    }
}

class Student extends Human {
    public void run() {
        System.out.println("学生跑得贼快~~");
    }
}

class Teacher extends Human {
    public void run() {
        System.out.println("老师跑得贼快~~");
    }
}
2. 注意事项

多态是对象或行为的多态,Java中的属性 (成员变量) 不谈多态。

public class HelloWorld {
    public static void main(String[] args) {
        // 1. 对象多态
        Human h1 = new Student();
        Human h2 = new Teacher();

        // 2. 属性(成员变量)是没有多态的
        System.out.println(h1.name);  // "父类 Human"
        System.out.println(h2.name);  // "父类 Human"
    }
}

class Human {
    public String name = "父类 Human";
}

class Student extends Human {
    public String name = "子类 Student";
}

class Teacher extends Human {
    public String name = "子类 Teacher";
}
3. 多态的好处

3.1 在多态形式下,可以实现解耦合,右边对象可以随时切换,后续业务随机改变

// 当 Student() 不好用时,完全可以不改变下面的h1.run()...等代码,直接换成 Teacher() 即可
        Human h1 = new Student();
        h1.run();
        h1.get();
        h1.xxx......
        ......

3.2 定义方法时,使用父类类型的形参,可以接收一切子类对象,扩展性更强,更便利

public class HelloWorld {
    // main方法,程序入口
    public static void main(String[] args) {
        Human h1 = new Student();
        Human h2 = new Teacher();

        // 可以使用父类类型的变量作为形参,可以接收一切子类对象,方便到时候修改
        goToSchool(h1);
        goToSchool(h2);
    }

    // 自定义方法
    public static void goToSchool(Human h) {
        System.out.println(h + "去学校了");
    }
}

class Human {

}

class Student extends Human {

}

class Teacher extends Human {

}
4. 多态的类型转换

种类

  • 自动类型转换 —— 例如 Human h = new Teacher()
  • 强制类型转换 —— 例如 Teacher t = (Teacher) h

作用:通过把对象转换成真正的类型,从而解决了多态下不能调用子类独有方法的问题。

注意

  • 存在继承时,就可以强制类型转换,编译阶段不会报错;
  • 但是在运行阶段,如果发现对象的真实类型与强制转换后的类型不同,就会报错!( ClassCastException )
  • 因此,强制类型转换前,使用 instanceof 判断当前对象的真实类型。
public class HelloWorld {
    public static void main(String[] args) {
        // 1. 对象多态
        Human h1 = new Student();
        Human h2 = new Teacher();

        // 2. 行为多态
        h1.run();  // 学生跑得贼快~~
        h2.run();  // 老师跑得贼快~~

        // 3. 对象无法使用自己的独有功能
//      h1.test()    // 报错
//      h2.teach()   // 报错

        // 4. 想要使用独有的功能,就必须强制类型转换
        Student s = (Student) h1;
        Teacher t = (Teacher) h2;

        s.test();  // 学生需要考试
        t.teach();  // 老师需要教学

        // 5. 如果你不确定 h1 是什么类型的,强制类型转换在编译时没问题,但是运行时可能会报错
//      Teacher tt = (Teacher) h1;  // 运行报错,因为 h1 本质是Student类的对象,不可能转为Teacher类的对象

        // 6. 解决上面的问题
        judge(h1);  // 学生需要考试
    }

    // 自定义方法
    public static void judge(Human h) {
        // 6. 为了解决上面的问题方案,需要利用instanceof做个判断(类型一致返回true,否则返回false)
        if (h instanceof Teacher) {
            Teacher t = (Teacher) h;
            t.teach();
        } else if (h instanceof Student) {
            Student s = (Student) h;
            s.test();
        }
    }
}

class Human {
    public void run() {
        System.out.println("人会跑步~~");
    }
}

class Student extends Human {
    public void run() {
        System.out.println("学生跑得贼快~~");
    }

    // 学生独有功能
    public void test() {
        System.out.println("学生需要考试");
    }
}

class Teacher extends Human {
    public void run() {
        System.out.println("老师跑得贼快~~");
    }

    // 老师独有功能
    public void teach() {
        System.out.println("老师需要教学");
    }
}

http://www.kler.cn/a/133653.html

相关文章:

  • 软件测试面试大全(含答案+文档)
  • 使用API有效率地管理Dynadot域名,编辑账户中whois联系人信息
  • 鸿蒙next版开发:相机开发-适配不同折叠状态的摄像头变更(ArkTS)
  • 前端请求后端php接口跨域 cors问题
  • @ComponentScan:Spring Boot中的自动装配大师
  • WebSocket和HTTP协议的性能比较与选择
  • C++11的互斥包装器
  • 怎样助力IT运维团队更专业、更协作、更高效
  • 详解如何使用Jenkins一键打包部署SpringBoot项目
  • 华媒舍:怎样成为谷歌竞价排名羸家?10个方法
  • HIT 模式识别 手写汉字分类 Python实现
  • 038、语义分割
  • C++--哈希表--散列--冲突--哈希闭散列模拟实现
  • LintCode 1394 · Goat Latin (字符串处理题)
  • NET8 ORM 使用AOT SqlSugar
  • RabbitMQ-高级篇-黑马程序员
  • jsp中使用PDF.js实现pdf文件的预览
  • php mysql 如何处理查询中存在正则特殊字符的查询
  • Element-UI el-select下拉框多选实现全选
  • 生命在于学习——主板跳线的学习
  • OPPO发布AndesGPT大模型;Emu Video和Emu Edit的新突破
  • 正则表达式去掉代码末尾的数字
  • Hive默认分割符、存储格式与数据压缩
  • Linux环境的Windows子系统
  • C语言基础篇4:变量、存储、库函数
  • 【Seata源码学习 】篇三 seata客户端全局事务开启、提交与回滚