美文网首页
12.虚方法

12.虚方法

作者: 乙腾 | 来源:发表于2020-10-29 07:57 被阅读0次

非虚方法

  • 如果方法在编译器就确定了具体的调用版本,这个版本在运行时是不可变的。这样的方法称为非虚方法
  • 静态方法、私有方法、final方法、实例构造器、父类方法都是非虚方法
  • 其他方法称为虚方法

notice:

n1.非虚方法实际就是非多态的方法。

第一条对应的多态的继承和实现。

第二条对应的多态的重写,方法不能被重写。

n2.多态的前提

子类对象的多态性使用前提:①类的继承关系②方法的重写

n3.不能被重写的方法

1.private static final修饰的方法不能被重写。

2.构造器不能被重写:

首先,构造器是不能被继承的,因为每个类的类名都不相同,而构造器名称与类名相同,所以根本谈不上继承。

又由于构造器不能继承,所以就不能被重写。但是,在同一个类中,构造器是可以被重载的。

3.父类方法

直接调用父类父类方法,相当于直接指定类型了。属于静态链接,早期绑定。

n4.重载和重写

重载概念:对于同一个类,如果这个类里面有两个或者多个重名的方法,但是方法的参数个数、类型、顺序至少有一个不一样,这时候局构成方法重载

重写概念:当一个子类继承一父类,而子类中的方法与父类中的方法的名称,参数个数、类型都完全一致时,就称子类中的这个方法重写了父类中的方法。

字节码调用指令

普通调用指令:
1.invokestatic:调用静态方法,解析阶段确定唯一方法版本;
2.invokespecial:调用方法、私有及弗雷方法,解析阶段确定唯一方法版本;
3.invokevirtual调用所有虚方法;(除final修饰外,final调用也是通过invokevirtual指令)
4.invokeinterface:调用接口方法;
动态调用指令:
5.invokedynamic:动态解析出需要调用的方法,然后执行 .
前四条指令固化在虚拟机内部,方法的调用执行不可人为干预,而invokedynamic指令则支持由用户确定方法版本。其中invokestatic指令和invokespecial指令调用的方法称为非虚方法,其余的(final修饰的除外)称为虚方法。

/**
 * 解析调用中非虚方法、虚方法的测试
 */
class Father {
    public Father(){
        System.out.println("Father默认构造器");
    }

    public static void showStatic(String s){
        System.out.println("Father show static"+s);
    }

    public final void showFinal(){
        System.out.println("Father show final");
    }

    public void showCommon(){
        System.out.println("Father show common");
    }

}

public class Son extends Father{
    public Son(){
        super();
    }

    public Son(int age){
        this();
    }

    public static void main(String[] args) {
        Son son = new Son();
        son.show();
    }

    //不是重写的父类方法,因为静态方法不能被重写
    public static void showStatic(String s){
        System.out.println("Son show static"+s);
    }

    private void showPrivate(String s){
        System.out.println("Son show private"+s);
    }

    public void show(){
        //invokestatic
        showStatic(" 大头儿子");
        //invokestatic
        super.showStatic(" 大头儿子");
        //invokespecial
        showPrivate(" hello!");
        //invokespecial
        super.showCommon();
        //invokevirtual 因为此方法声明有final 不能被子类重写,所以也认为该方法是非虚方法
        showFinal();
        //虚方法如下
        //invokevirtual
        showCommon();//没有显式加super,被认为是虚方法,因为子类可能重写showCommon
        info();

        MethodInterface in = null;
        //invokeinterface  不确定接口实现类是哪一个 需要重写
        in.methodA();

    }

    public void info(){

    }

}

interface MethodInterface {
    void methodA();
}

notice:

invokedynamic指令

JVM字节码指令集一直比较稳定,一直到java7才增加了一个invokedynamic指令,这是Java为了实现【动态类型语言】支持而做的一种改进
但是java7中并没有提供直接生成invokedynamic指令的方法,需要借助ASM这种底层字节码工具来产生invokedynamic指令.直到Java8的Lambda表达式的出现,invokedynamic指令的生成,在java中才有了直接生成方式
Java7中增加的动态语言类型支持的本质是对java虚拟机规范的修改,而不是对java语言规则的修改,这一块相对来讲比较复杂,增加了虚拟机中的方法调用,最直接的受益者就是运行在java平台的动态语言的编译器

动态类型语言和静态类型语言

动态类型语言和静态类型语言两者的却别就在于对类型的检查是在编译期还是在运行期,满足前者就是静态类型语言,反之则是动态类型语言。
直白来说 静态语言是判断变量自身的类型信息;动态类型语言是判断变量值的类型信息,变量没有类型信息,变量值才有类型信息,这是动态语言的一个重要特征
Java是静态类型语言(尽管lambda表达式为其增加了动态特性),js,python是动态类型语言.

//变量没有类型信息,变量值才有。
items.forEach((k,v)->{
        System.out.println("Item : " + k + " Count : " + v);
        if("E".equals(k)){
            System.out.println("Hello E");
        }
    });

相关文章

  • 12.虚方法

    非虚方法 如果方法在编译器就确定了具体的调用版本,这个版本在运行时是不可变的。这样的方法称为非虚方法 静态方法、私...

  • 25、虚方法和抽象类

    虚方法: •用virtual修饰的方法叫做虚方法•虚方法可以在子类中通过override关键字来重写•常见的虚方法...

  • 虚方法

    虚方法实际上是多态的实现形式之一(虚方法、抽象方法、接口) 如果在父类中标记了虚方法 如果子类没有重写虚方法,那么...

  • 12.方法

    方法是与某些特定类型相关联的函数。 self 属性 类型的每一个实例都有一个隐含属性叫做 self,self 完全...

  • 虚方法

    1.如果子类重写了父类的虚方法,那么通过父类变量来调用这个方法的时候,会调用子类的2.属性的本质也是方法所以可以是虚的

  • 虚方法、抽象方法、实例方法、静态方法

    参考:JAVA中虚方法、抽象方法、实例方法、静态方法的辨别虚方法:可以被覆写(override)的方法。实例方法:...

  • Maple符号 实数虚数

    方法1 提取实部和虚部 计算 方法2 提取实部和虚部 计算 方法3 提取实部和虚部 计算

  • C#

    虚方法 1.方法替换---在子类中重新实现父类中定义的方法。 2.只有方法和属性是虚,字段不能是虚。 多态 使用父...

  • Python OOP-5

    12. 所用软件 画图软件:Faststone capture 13. 抽象类 抽象方法:没有具体实现内容的方法称...

  • 方法 Day0816

    重写方法override:用相同的签名重写所继承的虚方法 重写是对虚方法(virtua)进行override...

网友评论

      本文标题:12.虚方法

      本文链接:https://www.haomeiwen.com/subject/dfzhvktx.html