zoukankan      html  css  js  c++  java
  • 14.多态

    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/

     

  • 相关阅读:
    206. Reverse Linked List
    简介AngularJS中使用factory和service的方法
    如何写一手漂亮的模型:面向对象编程的设计原则综述
    webpack入门操作教程
    webpack4.0.1安装问题和webpack.config.js的配置变化
    webpack.config.js配置遇到Error: Cannot find module '@babel/core'&&Cannot find module '@babel/plugin-transform-react-jsx' 问题
    解决webpack打包报错: Cannot find module '@webassemblyjs/wasm-parser'
    docker-compose介绍
    .NET Core+MySql+Nginx 容器化部署
    .net core使用ef core操作mysql数据库
  • 原文地址:https://www.cnblogs.com/yangyunnb/p/6096025.html
Copyright © 2011-2022 走看看