浅谈java中静态方法的重写问题详解

2016-02-19 09:29 6 1 收藏

有了下面这个浅谈java中静态方法的重写问题详解教程,不懂浅谈java中静态方法的重写问题详解的也能装懂了,赶紧get起来装逼一下吧!

【 tulaoshi.com - 编程语言 】

首先来看看以下程序将会打印出什么:
代码如下:

class Dog {
    public static void bark() {
        System.out.print("woof ");
    }
}

class Basenji extends Dog {
    public static void bark() { }
}

(本文来源于图老师网站,更多请访问http://www.tulaoshi.com/bianchengyuyan/)

public class Bark {
    public static void main(String args[]) {
        Dog woofer = new Dog();
        Dog nipper = new Basenji();
        woofer.bark();
        nipper.bark();
    }
}

随意地看一看,好像该程序应该只打印一个woof。毕竟,Basenji扩展自Dog,并且它的bark方法定义为什么也不做。main方法调用了bark方法,第一次是在Dog类型的woofer上调用,第二次是在Basenji类型的nipper上调用。巴辛吉小鬣狗并不会叫唤,但是很显然,这一只会。如果你运行该程序,就会发现它打印的是woof woof。这只可怜的小家伙到底出什么问题了?

问题在于bark是一个静态方法,而对静态方法的调用不存在任何动态的分派机制[JLS 15.12.4.4]。当一个程序调用了一个静态方法时,要被调用的方法都是在编译时刻被选定的,而这种选定是基于修饰符的编译期类型而做出的,修饰符的编译期类型就是我们给出的方法调用表达式中圆点左边部分的名字。在本案中,两个方法调用的修饰符分别是变量woofer和nipper,它们都被声明为Dog类型。因为它们具有相同的编译期类型,所以编译器使得它们调用的是相同的方法:Dog.bark。这也就解释了为什么程序打印出woof woof。尽管nipper的运行期类型是Basenji,但是编译器只会考虑其编译器类型。

要订正这个程序,直接从两个bark方法定义中移除掉static修饰符即可。这样,Basenji中的bark方法将覆写而不是隐藏Dog中的bark方法,而该程序也将会打印出woof,而不是woof woof。通过覆写,你可以获得动态的分派;而通过隐藏,你却得不到这种特性。

(本文来源于图老师网站,更多请访问http://www.tulaoshi.com/bianchengyuyan/)

来源:http://www.tulaoshi.com/n/20160219/1590964.html

延伸阅读
运行效果: 控制台效果: ================================================== 代码部分 ================================================== /hello_test/src/com/b510/test/StaticTest.java 代码如下: /**   *   */  package com.b510.test;  /**   * 在程序运行时的区别:实例变量属于某个对象的...
首先看这两类都实现List接口,而List接口一共有三个实现类,分别是ArrayList、Vector和LinkedList。List用于存放多个元素,能够维护元素的次序,并且允许元素的重复。 3个具体实现类的相关区别如下: 1.ArrayList是最常用的List实现类,内部是通过数组实现的,它允许对元素进行快速随机访问。数组的缺点是每个元素之间不能有间隔,当数组大小...
内部类访问规则 •内部类可以直接访问外部类中的成员,包括私有。访问格式:外部类名.this •外部类要访问内部类必须创建内部类对象。 •内部类在成员位置上,可以被成员修饰符修饰。 代码如下: public class InnerClassDemo1 {      public static void main(String[] args){    &nbs...
想必你已经阅读了一两本这样的Java书籍,它们在开头都指出了面向对象编程的3个主要概念:封装、继续和多态。理解这3个概念对于领会Java 语言来说至关重要,而搞懂方法的覆盖又是理解继续概念的要害部分。 这个例子摘自 Java 语言规范 01: class Super 02: { 03: static String greeting() 04: { 05: return "Goodnight"; 06...
■JDBC ODBC Bridge的Bug及其解决方法 !-- frame contents -- !-- /frame contents -- 在编写一数据库治理程序时,发现JDBC-ODBC Bridge存在不易发现的Bug。在向数据表插入数据时,假如为英文字符,存储内容完全正确,假如存入中文字符,部分数据库只能存储前七八个中文字符,其他内容被截去,导致存储内容的不完整(有...

经验教程

405

收藏

68
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部