1、多态

  1. 方法的多态

    //方法重载体现多态
    A a = new A();
    //这里我们传入不同的参数,就会调用不同sum方法
    System.out.println(a.sum(10,20));
    System.out.println(a.sum(10,20,30));
    //方法重写体现多态
  2. 对象的多态

    • 一个对象的编译类型和运行类型可以不一致
    • 编译类型在定义对象时,就确定了,不能改变
    • 运行类型是可以变化的
    • 编译类型看定义时 = 号 的左边,运行类型看 = 号的右边
    Animal animal = new Dog();//animal编译类型是Animal,运行类型是Dog
    animal = new Cat(); //animal 的运行类型变成了 Cat,编译类型仍然是 Animal
  3. 多态的向上转型

    • 本质:父类的引用指向了子类的对象

    • 语法:父类类型 引用名 = new 子类类型();

    • 特点:编译类型看左边,运行类型看右边。

      ​ 可以调用父类中的所有成员(须遵循访问权限)

      ​ 不能调用子类中特有的成员

      最终运行效果看子类(运行类型)的具体实现,

      ​ 即调用方法时,按照从子类开始查找方法,然后调用,规则按方法的调用规则一致

      ​ (从子类找,子类有,则调用,子类无,则在父类找,父类有,并可以调用,则调用,父类无,从祖父类找,祖父类 有,并可以调用,则调用,祖父类无,从Object类找) 如果查找方法的过程中,找到了,但是不能访问,则报错

  4. 多态的向下转型

    • 语法:子类类型 引用名 = (子类类型)父类引用;
    • 只能强转父类的引用,不能强转父类的对象
    • 要求父类的引用必须指向的是当前目标类型的对象
    • 当向下转型后,可以调用子类类型中所有的成员
    Animal animal = new Cat();
    Cat cat = (Cat) animal;
  5. 属性没有重写之说!属性的值看编译类型

  6. instanceOf 比较操作符,用于判断对象的运行类型是否为XX类型或XX类型的子类型

  • System.out.println(aa instanceof AA); // true
  1. 属性看编译类型,方法看运行类型

  2. Java的动态绑定机制

    • 当调用对象方法的时候,该方法会和该对象的内存地址/运行类型绑定

      (子类中没有get方法,调用了父类的get方法,但是父类的get方法中又有一个say方法,这个say方法子类也有,则这个时候调用 子类的say方法)

    • 当调用对象属性时,没有动态绑定机制,哪里声明,哪里使用

  3. 多态数组:数组的定义类型为父类类型,里面保存的实际元素类型为子类类型

    public class PloyArray {
    public static void main(String[] args){ Person[] person = new Person[5];
    person[0] = new Person("jack",20);
    person[1] = new Student("mary",18,100);
    person[2] = new Student("smith",19,30.1);
    person[3] = new Teacher("scott",30,20000);
    person[4] = new Teacher("king",50,25000); //循环遍历多态数组,调用say
    for (int i = 0; i < person.length; i++) {
    //person[i] 编译类型是 Person ,运行类型是根据实际情况由JVM来判断
    System.out.println(person[i].say()); //动态绑定机制
    //类型判断 + 向下转型
    if (person[i] instanceof Student){//判断person[i] 的运行类型是不是Student
    Student student = (Student)person[i];//向下转型
    student.study();
    }else if(person[i] instanceof Teacher){
    ((Teacher)person[i]).teach();
    }else if(person[i] instanceof Person){ }else{
    System.out.println("你的类型有误,请自己检查...");
    }
    } }
    } public class Person { //父类
    private String name;
    private int age; public Person(String name, int age) {
    this.name = name;
    this.age = age;
    } public String getName() {
    return name;
    } public void setName(String name) {
    this.name = name;
    } public int getAge() {
    return age;
    } public void setAge(int age) {
    this.age = age;
    } public String say(){ //返回名字和年龄
    return name + "\t" + age;
    }
    } public class Student extends Person{
    private double score; public Student(String name, int age, double score) {
    super(name, age);
    this.score = score;
    } public double getScore() {
    return score;
    } public void setScore(double score) {
    this.score = score;
    } //重写父类的say方法
    @Override
    public String say() {
    return "学生 " + super.say() + " score =" + score;
    } //特有方法
    public void study(){
    System.out.println("学生 " + getName() + "正在学习...");
    }
    } public class Teacher extends Person{
    private double salary; public Teacher(String name, int age, double salary) {
    super(name, age);
    this.salary = salary;
    } public double getSalary() {
    return salary;
    } public void setSalary(double salary) {
    this.salary = salary;
    } //重写父类的say方法
    @Override
    public String say() {
    return "老师 " + super.say() + " salary =" + salary;
    } //特有方法
    public void teach(){
    System.out.println("老师 " + getName() + "正在授课...");
    }
    } /*
    运行结果
    jack 20
    学生 mary 18 score =100.0
    学生 mary正在学习...
    学生 smith 19 score =30.1
    学生 smith正在学习...
    老师 scott 30 salary =20000.0
    老师 scott正在授课...
    老师 king 50 salary =25000.0
    老师 king正在授课...
    */
  4. 多态参数:方法定义的形参类型为父类类型,实参类型允许为子类类型

    public class PloyParameter {
    public static void main(String[] args) {
    Worker tom = new Worker("tom", 2500);
    Manager milan = new Manager("milan", 5000, 200000);
    PloyParameter ployParameter = new PloyParameter(); ployParameter.showEmpAnnual(tom);
    ployParameter.showEmpAnnual(milan); ployParameter.testWork(tom);
    ployParameter.testWork(milan); } public void showEmpAnnual(Employee e) { //形式参数为父类类型
    System.out.println(e.getAnnual());
    } public void testWork(Employee e) {
    if (e instanceof Worker) {
    ((Worker) e).work(); //有向下转型
    }else if(e instanceof Manager) {
    ((Manager) e).manager(); //有向下转型
    }else {
    System.out.println("不做处理");
    }
    }
    } public class Employee { //父类
    private String name;
    private double salary; //月工资 public Employee(String name, double salary) {
    this.name = name;
    this.salary = salary;
    } //得到年工资的方法
    public double getAnnual() {
    return 12 * salary;
    } public String getName() {
    return name;
    } public void setName(String name) {
    this.name = name;
    } public double getSalary() {
    return salary;
    } public void setSalary(double salary) {
    this.salary = salary;
    } } public class Worker extends Employee{
    public Worker(String name, double salary) {
    super(name, salary);
    }
    public void work() {
    System.out.println("普通员工" + getName() + "is working");
    } @Override
    public double getAnnual() { //普通员工没有其他收入,则直接调用父类方法
    return super.getAnnual();
    }
    } public class Manager extends Employee{ private double bonus; public Manager(String name, double salary, double bonus) {
    super(name, salary);
    this.bonus = bonus;
    } public double getBonus() {
    return bonus;
    } public void setBonus(double bonus) {
    this.bonus = bonus;
    } public void manager() {
    System.out.println("经理" + getName() + "is managing");
    } //重写获取年薪的方法
    @Override
    public double getAnnual() {
    return super.getAnnual() + bonus;
    }
    } /*
    运行结果
    30000.0
    260000.0
    普通员工tomis working
    经理milanis managing
    */

Java SE 多态的更多相关文章

  1. Java SE 简介 & 环境变量的配置

    Java SE 简介 & 环境变量的配置 一.Java 技术的三个方向 Java 技术分为三个方向 javaSE( Java Platform Standard Edition 标准版)用来开 ...

  2. Java Se 基础系列(笔记) -- OO

    记录所学到的关于Java Se的一些基础知识 1.对象是通过“属性(成员变量)”和“方法”来分别对应事物所具有的静态属性和动态属性 2.类(Class)是对某一类事物的抽象,对象(Object)为某个 ...

  3. 黑马程序员 ——Java SE(1)

    ----<a href="http://www.itheima.com" target="blank">Java培训.Android培训.iOS培训 ...

  4. Java SE 基础知识(一)

    一.基础知识 1. Java SE : Java Standard Edition Java ME : Java Micro Edition Java EE : Java Enterprise Edi ...

  5. Java SE教程

    第0讲 开山篇 读前介绍:本文中如下文本格式是超链接,可以点击跳转 >>超链接<< 我的学习目标:基础要坚如磐石   代码要十份规范   笔记要认真详实 一.java内容介绍 ...

  6. Java SE 开篇

    一.  Java SE 开篇 1.  Java 基本数据类型及其对应的包装类 基本数据类型 对应的包装类 * byte Byte * boolean Boolean * char Character ...

  7. JAVA SE回顾及思考(1)——面向对象的特点

    学习Java已经三年了,现在开始做Android开发,虽说还在用Java语言但本人现在才真真的意识到无论学什么基础才是最重要的,可能一些刚接触Java或者Android的朋友现在还体会不到基础的重要性 ...

  8. Java SE(1)

    Java SE基础回顾 1.循环语句中的break是终止全部循环,跳出循环体:而continue是终止本次循环,跳执行下一循环 2.return语句有两个作用:返回值:结束方法的运行 3.对于java ...

  9. Java SE —— 专栏总集篇

    前言: Java 语言,是相对于其他语言而言,门槛低,而且功能还强大的一门编程语言,本人十分看好这一门语言,但是,它也是有深度的,看过本人的<数据结构与算法>专栏的同学们有福了,因为本人在 ...

随机推荐

  1. Java已知图片路径下载图片到本地

    public static void main(String[] args) { FileOutputStream fos = null; BufferedInputStream bis = null ...

  2. NC13822 Keep In Line

    NC13822 Keep In Line 题目 题目描述 又到饭点了,SK同学靠着惯性走到了食堂,但长长的队伍顿时让他失去了食欲.突然,他注意到某个窗口前的队伍里明显存在插队的现象,于是他默默记录下了 ...

  3. C语言输出九九乘法表

    C语言学了有一阵子了,趁着假期没事练练手,没想到挺简单 基本思路是这样的 先写一个主函数,然后定义两个变量i1和i2;使用for语句循环嵌套,外层循环负责写循环9次,内循环里面写从1开始递增去和外层循 ...

  4. git的基本操作命令和码云的注册使用

    Git文件操作文件的四种状态版本控制就是对文件的版本控制,要对文件进行修改.提交等操作,首先要知道文件当前在什么状态,不然可能会提交了现在还不想提交的文件,或者要提交的文件没提交上. Untracke ...

  5. Java8 函数式【1】:一文读懂逆变

    Java8 函数式[1]:一文读懂逆变 禁止转载 pure function 协变 逆变 Java8 引入了函数式接口,从此方法传参可以传递函数了,有人说: 不就是传一个方法吗,语法糖! lambda ...

  6. 2022DASCTF Apr X FATE 防疫挑战赛-- SimpleFlow

    1.SimpleFlow 得到pcapng文件,协议分级统计显示大部分为TCP流和http流 过滤http流,发现了flag.zip,foremost分离,得到加密的zip 在pcapng中寻找pas ...

  7. Junit使用步骤和junit_@Before&@After

    测试: 1.定义一个测试类(测试用例) 建议: 测试类名:被测试的类型Test CalculatorTest 包名:xxx.xxx.xx.test com.li.Test 2.定义测试方法:可以独立运 ...

  8. redux和dva

    实习的时候,公司使用的是react,react说实话生态学的还不是很完善,就暂时先不做跟react相关的博客,等以后学好了react全家桶之后,专门再总结一下react的内容 这两天看了公司的alit ...

  9. DP の 百题大过关(5/100)

      动态规划自古以来是DALAO凌虐萌新的分水岭,但有些OIer认为并没有这么重要--会打暴力,大不了记忆化.但是其实,动态规划学得好不好,可以彰显出一个OIerOIer的基本素养--能否富有逻辑地思 ...

  10. 2511-Druid监控功能的深入使用与配置-如何记录监控数据(基于logback)

    Druid的监控很强大,但可惜的是监控数据是存在内存中的,需求就是定时把监控数据记录下来,以日志文件的形式或者数据库入库. 记录两种方式: 数据库入库 logback形式记录 原理(重点) 如果仅仅想 ...