zoukankan      html  css  js  c++  java
  • Java多态和虚方法调用

    多态(polymorphism)

    多态的概念

    ·多态是指一个程序中相同的名字表示不同的含义的情况。

    ·多态有两种情形:

             1、编译时多态:

                       1.重载(overload)多个同名的不同方法;

                       2.如:p.sayHello();p.sayHello(“wang”);

             2、运行时多态:

                       1.覆盖(override)子类对父类方法进行覆盖

                       2.动态绑定(dynamic binding)也称为虚方法调用(virtual method invoking),真正的方法在运行时才确定

                       3.在调用方法时,程序会正确地调用子类对象的方法。

    ·多态的特点大大提高了程序的抽象程度和简洁性。

    上溯造型(upcasting)

    ·是把派生类型当作基本类型处理,如:

    Person p = new Sudent();
    
    void fun(Person p){…}
    fun(new Person)); or fun(new Student());
    View Code

    虚方法(virtual methods)

    虚方法调用

    ·虚方法调用,可以实现运行时的多态

             ·子类重载了父类的方法时,运行时系统根据调用该方法的实例的类型来决定选择哪一个方法调用;

             ·所有的非final方法都会自动地进行动态绑定

    public class TestVirtualInvoke{
        static void doStuff(Shape s){//Shape为形式参数类型
            s.draw();
    }
    public static void main(String[] args){
        Shape s = new Shape();
        Circle c = new Circle();
        Triangle t = new Triangle();
        Shape l = new Line();//可以将父类类型的引用指向子类的实例对象
        
        doStuff(s);
        doStuff(c);//调用的时候,使用其子类实例作为参数
        doStuff(t);//运行时,系统根据调用方法的实例类型,来决定哪一个方法被调用
        doStuff(l);
    }
    }
    
    class Shape{
        void draw(){System.out.println(“Draw Shape”);}
    }
    class Circle extends Shape{
        //子类重载了父类的方法
        void draw(){System.out.println(“Draw Circle”);}
    }
    class Triangle extends Shape{
        void draw(){System.out.println(“Draw Triangle”);}
    }
    class Line extends Shape{
        void draw(){System.out.println(“Draw Line”);}
    }
    
    -----------OUTPUT------------
    Draw Shape
    Draw Circle
    Draw Triangle
    Draw Line
    View Code

    动态类型确定

    ·使用运算符 instanceof

             ·作用:运行时用来指出对象是否是特定类的一个实例。通过返回一个布尔值,来指出对象是否是这个特定类或者是它的子类的一个实例

             ·用法: flag = Object instanceof class

                       ·如果Object是class的一个实例,则返回true,否则,返回false。

    public class InstanceOf{
        public static void main(String[] args){
            Object things[] = new Object[3];
            things[0] = new Integer(1);
            things[1] = new Double(1);
            things[2] = new String(“1”);
            for(int i=0; i<things.length; ++i){
                System.out.println(“the type of things[“+i+”]is”+things[i].getClass());
    }
    }
    }
    ---------------OUTPUT---------------
    the type of things[0] is class java.lang.Integer
    the type of things[1] is class java.lang.Double
    the tyoe of things[2] is class java.lang.String
    View Code

    什么情况不是虚方法的调用

    ·Java中,普通方法是虚方法。既,不用做出特殊声明的方法都是虚方法。既,在被调用时是根据实际的对象实例选择调用哪个方法。

    ·static、private方法不是虚方法调用。因为你它们与虚方法编译后用的指令是不同的。(static是属于类的,不是具体某个类的;被private修饰的方法是不能被子类所override的)

    三种非虚的方法

    ·static的方法,以声明的类型为准,与实例类型无关

    ·private方法子类看不见,也不会被虚化

    ·final方法子类不能覆盖,不存在虚化问题

    public class TestVirtualInvoke2{
        static void doStuff(Shape s){
            s.draw();//由于draw是static方法,所以只跟声明的类型有关,与实例无关
    }
    public static void main(String[] args){
        Shape s = new Shape();
        Triangle t = new Triangle();
        Shape l = new Line();
        doStuff(s);
        doStuff(t);
        doStuff(l);
        System.out.println();
        Shape s2 = new Circle();
        //只和声明的类型(Shape)有关,而跟后面的实例(Circle)无关
        doStuff(s2);
        s2.draw();
        Circle c = new Circle();
        c.draw();
    }
    }
    class Shape{
        //把draw都改成static方法,与具体实例无关
        static void draw(){System.out.println(“Draw Shape”);}
    }
    class Circle extends Shape{
        static void draw(){System.out.println(“Draw Circle”);}
    }
    class Triangle extends Shape{
        static void draw(){System.out.println(“Draw Triangle”);}
    }
    class Line extends Shape{
        static void draw(){System.ou.println(“Draw Line”);}
    }
    
    -----------OUTPUT------------
    Draw Shape
    Draw Shape
    Draw Shape
    
    Draw Shape
    Draw Shape
    Draw Circle
    View Code
  • 相关阅读:
    《MySQL必知必会》第六章:过滤数据
    《MySQL必知必会》第七章:数据过滤
    《MySQL必知必会》第五章:排序检索数据
    Java高级特性:clone()方法
    Java基础知识详解:abstract修饰符
    Java虚拟机:虚拟机内存区域和内存溢出异常
    Java虚拟机:源码到机器码
    Java虚拟机:本地方法栈与Native方法
    [LeetCode] 1481. Least Number of Unique Integers after K Removals
    [LeetCode] 331. Verify Preorder Serialization of a Binary Tree
  • 原文地址:https://www.cnblogs.com/arrows/p/10431085.html
Copyright © 2011-2022 走看看