14.多态

来源:互联网 发布:java磁条读卡器 编辑:程序博客网 时间:2024/05/20 06:55

1.继承

上一片笔记中已经写了很多多态的东西,因为继承是多态的基础

2.多态

面向对象的三个特征:1.抽象、2.继承、3.多态

2.1 多态

我的理解,欢迎讨论

多态(Polymorphism)按字面的意思就是"多种状态",在运行的时候会根据传入的参数,做出不同的动作。

1.在JAVA中,接口中函数的可以有多种不同的实现方式,某个函数使用该接口作为参数的时候,在运行时根据具体的类型,决定调用哪一个实现类的同名函数

2.JAVA中还可以通过重写父类的方法实现多台,使用父类的引用指向子类的对象,对象会向上转型,通过引用调用该重写的函数,会调用子类的函数

2.2 向上转型

 使用父类或者接口的引用指向子类的对象

class Father{        public int num=10;        public void f(){              System.out.println("1");        }  }class Son extends Father{        public int num=20;        public void f(){              System.out.println("2");        }                public void display(){}}public class Main{      public static void main(String[] args){      Father father=new Son();//向上转型
    System.out.println(father.num);    father.f();    father.g();
    } }

 说明:

1.father对象会向上转型,也就是说father引用调用不了函数display了

2.father.num//结果10,因为属性不存在动态绑定

3.father.f()//结果2,多态的缘故,调用的是子类的函数

4.father.g()//结果1,动态绑定不支持static函数,对象引用调用静态函数的方式特别的不好。

2.3 动态绑定

Java中的函数绑定

  • 方法调用与方法主体之间的关联关系
  • eg:Instrument类 play()函数
  •       Wind、Brass都是Instrument的子类,都对父类的play()进行了覆盖
  •       有一个函数public void tune(Instrument instrument){instrument.play();}
  • 1.前期绑定:编译时就知道调用哪个函数体
  • 2.后期绑定:编译器不知道instrument对象调用的是哪个对象的play函数,运行时确定
  • Java中的函数绑定:
  • 除了static、final、private修饰的函数是前期绑定之外,所有的函数都是后期绑定
  • 所以传入函数的参数最好都是基类的对象

2.4 动态连接

Java的类加载过程分为以下的七个步骤

  • 加载、验证、准备、解析、初始化、使用、卸载

  • 其中验证、准备、解析称为java的连接过程、这几个过程并不是顺序进行的,其中Java的解析过程可以发生在初始化之前、也可以发生在初始化之后,这是为了支持Java的动态绑定机制
  • 解析其其实把Java的符号引用转换为直接引用的过程,直接引用可以确定具体调用的函数

      • 符号引用:位于常量池的Constant_Class_info,Constant_Filed_info,Constant_Methodref_info中,通过其中的索引可以找到常量表中对应的类、方法、字段信息
      • 直接引用:目标对象的指针,或者说是操作句柄,与内存的布局相关,一般一个符号引用解析出来的直接引用一般是不一样的,一个对象有直接引用说明它已经存在于内存中了


2.5 动态加载

类加载

类加载器加载类的顺序如下:
1、检查这个类是否已经被加载。
2、如果没有被加载,则首先调用父加载器加载。
3、如果父加载器不能加载这个类,则尝试加载这个类。


动态类加载--运行时加载类

动态加载一个类十分简单。你要做的就是获取一个类加载器然后调用它的loadClass()方法。下面是个例子:

public class MainClass {  public static void main(String[] args){    ClassLoader classLoader = MainClass.class.getClassLoader();    try {        Class aClass = classLoader.loadClass("com.jenkov.MyClass");        System.out.println("aClass.getName() = " + aClass.getName());    } catch (ClassNotFoundException e) {        e.printStackTrace();    }}



参考文献:

[1].http://blog.csdn.net/sureyonder/article/details/5569617

[2].http://ifeve.com/dynamic-class-loading-reloading/

 

0 0