Java面向对象之:多态

"多态"是java语言的三大特征之一。

"多态"的含义是同一个行为具有多个不同表现形式或形态的能力,或者说就是同一个接口,使用不同的实例而执行不同操作。

“多态"是程序在执行过程中的一种"动态绑定"行为,所谓的"动态绑定”,简单说就是对象在不同情况下有不同的表现行为。

正文:

1. 多态的表现形式

“多态"的表现形式可以简单的总结为"两个方法,三个定义”:

  • “两个方法”:方法重载,方法重写;
  • “三个定义”:父类定义子类构建,接口定义类实现,抽象类定义实体类实现。

简单的理解就是,多态有三种实现方式,即:实体类的重写重载,接口的实现,抽象类的继承;

2. 多态的优点
  • 消除类型之间的耦合关系
  • 可替换性
  • 可扩充性
  • 接口性
  • 灵活性
  • 简化性
3. instanceof 关键字

当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,再去调用子类的同名方法。

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

以下是一个多态实例的演示,详细说明请看注释:

public class Test {
    public static void main(String[] args) {
      Animal a = new Animal ();
      Cat cat = new Cat ();
      Dog dog = new Dog ();
      a.show(cat);						// 调用cat方法
      a.show(dog);    					// 调用dog方法
  }       
    public static void show(Animal a)  {
        // 类型判断
        if (a instanceof Cat)  {  		// 猫做的事情 
            Cat c = (Cat)a;  			// 向下造型
            c.work();  
        } else if (a instanceof Dog) { 	// 狗做的事情 
            Dog c = (Dog)a;  			// 向下造型
            c.work();  
        }  
    }  
}
// Animal 类、Cat 类、 Dog 类 此处省略...
4. 动态绑定

我们已经讨论了方法的重写,也就是子类能够重写父类的方法。

当子类对象调用重写的方法时,调用的是子类的方法,而不是父类中被重写的方法。

要想调用父类中被重写的方法,则必须使用关键字super。

/* 文件名 : Employee.java */
public class Employee{
   private int id;
   private String name;
   public Employee(int id, String name) {
      System.out.println("Animal 的构造函数");
      this.id = id;
      this.name = name;
   }
   public void check() {
      System.out.println("我的基本信息:" + this.id
       + " " + this.name);
   }
   public String toString() {
      return id + " " + name;
   }
   public int getId() {
      return id;
   }
   public String getName() {
      return name;
   }
   public void setId(int newId) {
      id = newId;
   }
   public void setName(String newName) {
      name = newName;
   }
}
/* 文件名 : Weight.java */
public class Weight extends Employee {
   private double weight; 		// 全年工资
   public Food (int id, String name, double weight) {
       super(id, name);
       setWeight(weight);
   }
   public double getWeight() {
       return weight;
   }
   public void check() {
       System.out.println("Weight类的 check方法");
       System.out.println("体检对象是:" + getName()
       + " ,体重为:" + weight);
   }
   public void setWeight(double newWeight) {
       if(newWeight >= 0.0) {
          weight = newWeight;
       }else{
          System.out.println("体重数值异常");
       }
   }
}
/* 文件名 : CheckDemo.java */
public class CheckDemo{
   public static void main(String [] args) {
      Weight a = new Weight(1, "小猫", 10.5);
      Employee b = new Weight(2, "小狗", 21.1);	//向上造型
      System.out.println("使用 Weight 的引用调用 check -- ");
      a.check();
      System.out.println("使用 Employee 的引用调用 check--");
      b.check();
    }
}
//输出结果:
Employee 的构造函数
Employee 的构造函数
使用 Weight 的引用调用 check -- 
Weight类的 check方法
体检对象是:小猫 ,体重为:10.5
使用 Employee 的引用调用 check--
Weight类的 check方法
体检对象是:小狗 ,体重为:21.1

上面的实例是一个典型的"多态"应用,调用的方法在运行时进行了"动态绑定"。

例子解析

  • 当调用 a.check() 时,编译器在编译时会在 Weight 类中找到 check(),执行过程 JVM 就调用 Weight 类的 check();
  • 当调用 b.check() ,因为 b 是 Employee 的引用,所以调用 b 的 check() 方法时,编译器会去 Employee 类查找 check() 方法,使用 Employee 类中的 check() 方法验证该语句,但是在执行的时候,Java虚拟机(JVM)调用的是 Weight 类中的 check() 方法。

Java中所有的方法都能以这种方式表现,因此,重写的方法能在运行时调用,不管编译的时候源代码中引用变量是什么数据类型。

有"动态绑定"自然就有"静态绑定",所谓的"静态绑定"是在类定义完之后就确定了方法的绑定。做法就是父类的方法上加静态关键字"static",确保每次造型调用的都是父类方法,子类重写也没用(即所谓的父类静态方法不可以重写):

public class Animal{
   ...
   public static void check() {
      System.out.println("我的基本信息:" + this.id
       + " " + this.name);
   }
   ...
}

小结

  1. 多态的表现形式有"两个方法,三个定义";
  2. 构造器不可以重写,但可以重载,它也是多态的表现形式;
  3. "三个定义"中的对象只能使用声明时类型中的方法,不能使用自己的独特方法;
  4. 如果要使用自己的方法,则需要进行"强制类型转换",通常在进行"强制类型转换"时,需要使用"instanceof"运算符;
  5. 要想调用父类中被重写的方法,则必须使用关键字super。

更多精彩,请关注我的"今日头条号":Java云笔记
随时随地,让你拥有最新,最便捷的掌上云服务

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Java Punk

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值