Java中的多态

1.概念

对于同一行为,不同的子类对象有不同的表现。例如:动物吃东西,狗吃肉,猫吃鱼
多态是同一个行为具有多个不同表现形式或形态的能力。

多态就是同一个接口,使用不同的实例而执行不同操作,如图所示:
在这里插入图片描述
例子:比如电脑上的按键,在不同的情况下有不同的作用。比如我们按下 F1 键这个动作:

1.如果当前在 Flash 界面下弹出的就是 AS 3 的帮助文档;
2.如果当前在 Word 下弹出的就是 Word 帮助;
3.在 Windows 下弹出的就是 Windows 帮助和支持。
4.同一个事件发生在不同的对象上会产生不同的结果。

2.分类

(1)静态多态(早绑定):在程序编译阶段,已经确定了方法的具体行为:已经确定了具体调用的方法-----典型代码:方法重载(2)动态多态(晚绑定):

3.实现多态条件

1. 必须要在继承体系下
2. 子类必须要对父类想要实现多态的方法进行重写---子类对父类的方法进行重写(对重写方法调用:只能通过基类的引用去调用重写的方法(在执行时,根据基类引用不同类的都西昂,就会调用对应类中被重写方法))
3.父类引用指向子类对象

注意:1子类对象可以看成是一个基类对象 猫是动物 狗是动物 结论:基类引用可以引用子类对象
在这里插入图片描述

class Shape {
    void draw() {}
}
 
class Circle extends Shape {
    void draw() {
        System.out.println("Circle.draw()");
    }
}
 
class Square extends Shape {
    void draw() {
        System.out.println("Square.draw()");
    }
}
 
class Triangle extends Shape {
    void draw() {
        System.out.println("Triangle.draw()");
    }
}

多态的好处:可以使程序有良好的扩展,并可以对所有类的对象进行通用处理。

4.重写

重写(override):也称为覆盖。重写是子类对父类非静态、非private修饰,非final修饰,非构造方法等的实现过程
重写的规则:
1.子类在重写父类的方法时,一般必须与父类方法原型一致:修饰符 返回值类型 方法名(参数列表) 要完全一致
2.JDK7以后,被重写的方法返回值类型可以不同,但是必须是具有父子关系的
3.访问权限不能比父类中被重写的方法的访问权限更低。例如:如果父类方法被public修饰,则子类中重写该方法就不能声明为 protected
4.父类被static、private修饰的方法、构造方法都不能被重写。
5.子类和父类在同一个包中,那么子类可以重写父类所有方法,除了声明为 private 和 final 的方法。
6.子类和父类不在同一个包中,那么子类只能够重写父类的声明为 public 和 protected 的非 final 方法。
7.重写的方法, 可以使用 @Override 注解来显式指定. 有了这个注解能帮我们进行一些合法性校验. 例如不小心将方法名字拼写错了 (比如写成 aet), 那么此时编译器就会发现父类中没有 aet 方法, 就会编译报错, 提示无法构成重写

public class Employee {
   private String name;
   private String address;
   private int number;
   public Employee(String name, String address, int number) {
      System.out.println("Employee 构造函数");
      this.name = name;
      this.address = address;
      this.number = number;
   }
   public void mailCheck() {
      System.out.println("邮寄支票给: " + this.name
       + " " + this.address);
   }
   public String toString() {
      return name + " " + address + " " + number;
   }
   public String getName() {
      return name;
   }
   public String getAddress() {
      return address;
   }
   public void setAddress(String newAddress) {
      address = newAddress;
   }
   public int getNumber() {
     return number;
   }
}
public class Salary extends Employee
{
   private double salary; // 全年工资
   public Salary(String name, String address, int number, double salary) {
       super(name, address, number);
       setSalary(salary);
   }
   public void mailCheck() {
       System.out.println("Salary 类的 mailCheck 方法 ");
       System.out.println("邮寄支票给:" + getName()
       + " ,工资为:" + salary);
   }
   public double getSalary() {
       return salary;
   }
   public void setSalary(double newSalary) {
       if(newSalary >= 0.0) {
          salary = newSalary;
       }
   }
   public double computePay() {
      System.out.println("计算工资,付给:" + getName());
      return salary/52;
   }
}
public class VirtualDemo {
   public static void main(String [] args) {
      Salary s = new Salary("员工 A", "北京", 3, 3600.00);
      Employee e = new Salary("员工 B", "上海", 2, 2400.00);
      System.out.println("使用 Salary 的引用调用 mailCheck -- ");
      s.mailCheck();
      System.out.println("\n使用 Employee 的引用调用 mailCheck--");
      e.mailCheck();
    }
}

运行结果:
Employee 构造函数
Employee 构造函数
使用 Salary 的引用调用 mailCheck –
Salary 类的 mailCheck 方法
邮寄支票给:员工 A ,工资为:3600.0

使用 Employee 的引用调用 mailCheck–
Salary 类的 mailCheck 方法
邮寄支票给:员工 B ,工资为:2400.0

5.向下转型和向上转型

向上转型:让基类的引用去引用子类的对象

  1. 直接赋值
  2. 方法传参
  3. 方法
    向上转型的优点:让代码实现更简单灵活。
    向上转型的缺陷:不能调用到子类特有的方法。

向下转型:向下转型是把父类对象转为子类对象

6.多态的优缺点

1.使得代码灵活
2.降低代码的圈复杂度
3.可扩展性强
4.接口性
5.可扩充性
6.可替换性

缺陷:1.代码运行效率降低 (自己写代码测试:可以测试代码总的运行时间 了解多态的底层实现原理)

代码的圈复杂度:是一种代码复杂度的衡量标准,也称为条件复杂度或循环复杂度,它可以用来衡量一个模块判定结构的复杂程度,数量上表现为独立现行路径条数,也可理解为覆盖所有的可能情况最少使用的测试用例数。简称 CC 。其符号为 VG 或是 M 。

圈复杂度 在 1976 年由 Thomas J. McCabe, Sr. 提出。

圈复杂度大说明程序代码的判断逻辑复杂,可能质量低且难于测试和维护。程序的可能错误和高的圈复杂度有着很大关系。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值