导语 多态也叫动态绑定 后期绑定 运行时绑定
- 输入错误的数字,如何得到正确的结果呢 方法调用tune(Instruments i) tune(wind)
- 多态通过分离做什么和怎么做,从另一个角度讲接口和实现分离开来。接口就是公开调用的方法,而实现就是具体的方法,
父类(或抽象类,或inteface接口)来声明做什么,子类来实现怎么做。 - 封装 通过合并特征和行为来创建新的数据类型。实现隐藏则通过将细节“私有化”把接口和实现分离开来。
- 多态方法允许一种类型表现出与其他相似类型之间的区别,只要他们都是从同一基类导出的子类。
- 继承允许对象视为它自己本身的类型或者基类型来处理。
- 多态的好处:多态不带能够改善代码的组织结构和可读性,还能够创建可扩展的程序。(这些都需要大量编程才能理解的)
- 多态的作用是消除类型之间的耦合关系,即一个类型不依赖于另一个类型。
1.什么叫多态(动态绑定、后期绑定和运行时绑定)
- 讲一个方法调用同一个方法主体关联起来被称作绑定。绑定机制是由java语言所定的,不必深究他为什么会在前期绑定......。
List list = new ArrayList(); list.remove(0);
如上述代码,list.remove(0),这个方法调用将与ArrayList类里面的remove()方法主体关联,并执行主体里面的代码,这就叫做绑定。这个是后期绑定。、 - 前期绑定:方法调用在程序执行前进行绑定。(由编译器和连接程序实现)就是说方法调用明确与那个方法主体关联。只有明确只有这个类有这个方法的情况。不必深究为什么,这是java的机制,java自己可以知道怎样关联。
- 动态绑定:也就是多态,在运行时根据对象的类型进行绑定,也就是说程序在运行过程中进行方法的调用是可以知道其对象类型的。【子类继承同一个父类,调用父类的可被复用方法,不知道调用哪一个,
因为向上转型可能会new一个子类,如上面的list】
也就是说在程序运行过程中的方法调用后java自己会根据对象类型进行判断与那个方法主体关联并执行其中的代码。这是多么的神奇,不过不必深究。 - 如果一种语言想实现多态,就必须有某种机制,以便在运行时能判断对象的类型。就像java的多态机制一样。
- java中除了static和final方法(private 属于final方法)之外,其他所有方法都是后期绑定的。
有人可能会问 public等修饰的方法,别的类中可以有相同名字的public方法
2.通过代码说明什么是多态【产生正确的行为】,而什么有是前期绑定
package com.yue.dt; import java.util.Random; //父类 class Shape { //公开的接口 public void draw(){} public void erase(){} } //子类 class Circle extends Shape{ public void draw() { System.out.println("Circle.draw()!"); } public void erase() { System.out.println("Circle.erase()!"); } } class Square extends Shape{ public void draw() { System.out.println("Square.draw()!"); } public void erase() { System.out.println("Square.erase()!"); } } class Triangle extends Shape{ public void draw() { System.out.println("Triangle.draw()!"); } public void erase() { System.out.println("Triangle.erase()!"); } } class RandomShapeGenerator { private Random rand = new Random(47); public Shape next() { switch (rand.nextInt(3)) { default: case 0: return new Circle(); case 1: return new Square(); case 2: return new Triangle(); } } } public class Shapes { private static RandomShapeGenerator gen = new RandomShapeGenerator(); public static void main(String[] args) { Shape[] s = new Shape[9]; for (int i = 0; i < s.length; i++) { s[i] = gen.next(); } for (Shape shp : s) { shp.draw(); } } }
- 上面的代码,在Shapes的main方法中,我们使用gen.next()获取一个Shape子类并赋予Shape引用,Shape引用是父类,
那么问题来了为什么不执行父类中的draw(),这是因为java的机制,优先执行子类中重写的父类中的方法,子类那么多,怎么知道
执行的是哪一个子类的方法主体呢,这就是java的多态机制了,在运行时根据对象的类型将方法调用与相应的方法主体关联起来,
并执行其中的代码。 - 如果是个private 或final 或static 就是前期绑定啦,也就是说在程序执行前就将方法调用与方法体关联起来啦。
3.什么时候会产生多态,动态绑定、运行时绑定
- 如果2的解释还不明白的话,那下面的解释就很通透啦
- 方法调用不知道是调用哪个类中的方法主体时[代码],多态就会出现,也就是说可能会伴随着继承的情况,也有可能这个方法是public protect等权限修饰的。
- 一个名称的方法被多个类所拥有且不是static private final的时候,多态将会出现,因为在程序运行期间方法调用的时候,方法调用与那个类中的方法主体(方法代码)关联并执行需要多态进行判断。
当你 Shape s = new Circle();并执行s.draw(),你怎么知道s.draw()这个方法调用会执行Circle中的draw方法主体还是Shape中的方法主体,还是Square中方法主体呢????
这一切都依赖于多态。也就是在程序运行期间方法调用时判断对象的类型,并执行类中的方法主体。java会优先调用子类的覆盖方法,这就是多态机制(很片面)。