先看下面的代码。 class A { public static void f() { System.out.println("hello,A"); } }class B extends A { public static void f() { System.out.println("hello,B"); } }public class TestA { public static void main(String [] args) { A a = new B(); a.f(); } }
override指的是父类的某个行为被子类改变了,例如, 父类Parent有一个方法 run 定义如下 public void run(){} 而Parent的一个子类Child 也定义了这个方法:public void run(){ //.....}那么这时候对于Child 的对象以及Child子类的对象来说,当他们调用run方法的时候,他们调用的是Child中的run方法,而不是Parent中的run方法,也就是说,他们从Parent类中继承的run方法的行为改变了,也即 Child类中的run方法覆盖了Parent的run方法。而在我上面的那段代码中,当f为static方法的时候,尽管子类B也可以写一个public static void f()方法,但是这B的f方法并没有覆盖A的f方法,因为可以看到其实变量a指向的是一个B的对象,调用a.f()时,程序依然调用的是类A的方法,因此可以说f没有被覆盖。
static method不能被override,可以overload
谢谢大家,基本明白了,还有一个问题 tangqs(leon_tangqs) 写的代码中 Class B中public static void f(); 如果改成public static int f(); 编译器为何报"Retrun Type is imcompatible with A.f()", 既然没有override为和会报这个错???
同意jidongxx() 昨天看了本delphi的面向对象编程的书,说得比较清楚,因为delphi中将override/overload等都作为显式的关键字了,能更清楚地认识这些内容static的方法能被隐藏; 而普通方法能被覆盖,覆盖的结果是产生多态;例子: package test;class Test { public static void main(String[] args) { A a = new B(); a.f(); a.m(); } }class A { public static void f() { System.out.println("hello,A"); }
public void m() { System.out.println("hello,A"); } }class B extends A { public static void f() { System.out.println("hello,B"); }
public void m() { System.out.println("hello,B"); } }结果是:hello,A hello,B
To jidongxx() :有一点不明白,既然你说“子类中的static方法会隐藏父类中形构相同的static方法”,那为什么 tangqs(leon_tangqs)给出的程序中,输出结果是“Hello A”?不是被隐藏了吗?
static 独立于类, 没有override这一说法。
rcom10002(KNIGHTRCOM) 的例子很好的说明了继承时出现的 override 和 hide 两中情况。to shenpipi(皮皮): 静态方法是可以被继承的,可以用例子检验一下。to jide_123() “子类中的static方法会隐藏父类中形构相同的static方法”是相对子类说的,如果子类和父类具有形构相同的static方法,使用子类名或子类的对象调用这个static方法时,真正调用的是子类的static方法; 这个现象称为“隐藏”,或者说“隐藏了父类中同构的static方法”。 这与 static方法的静态绑定并不矛盾,tangqs(leon_tangqs)给出的程序中, public static void main(String [] args) { A a = new B(); a.f(); } a 是 类A 的对象,而方法f是静态方法,因为静态绑定,所以调用的是 A的静态方法。
但是在继承的时候就会发生问题 1.在对象构造上 2.构造器重载上 3.数据封装上 等
class A {
public static void f() {
System.out.println("hello,A");
}
}class B extends A {
public static void f() {
System.out.println("hello,B");
}
}public class TestA {
public static void main(String [] args) {
A a = new B();
a.f();
}
}
定义如下 public void run(){}
而Parent的一个子类Child 也定义了这个方法:public void run(){ //.....}那么这时候对于Child 的对象以及Child子类的对象来说,当他们调用run方法的时候,他们调用的是Child中的run方法,而不是Parent中的run方法,也就是说,他们从Parent类中继承的run方法的行为改变了,也即 Child类中的run方法覆盖了Parent的run方法。而在我上面的那段代码中,当f为static方法的时候,尽管子类B也可以写一个public static void f()方法,但是这B的f方法并没有覆盖A的f方法,因为可以看到其实变量a指向的是一个B的对象,调用a.f()时,程序依然调用的是类A的方法,因此可以说f没有被覆盖。
Class B中public static void f(); 如果改成public static int f();
编译器为何报"Retrun Type is imcompatible with A.f()", 既然没有override为和会报这个错???
有道理.
class A
{
static void f()
{
System.out.println("hello,A");
}}class B extends A
{
static void f()
{
System.out.println("hello,B");
}
}public class TestA
{
public static void main(String [] args)
{
B b = new B();
b.f(); //JDK1.4 中结果输出 “hello,B”
}
}这个程序中,执行的结果为 “hello,B”。类B中的方法f() 与它的父类A中的方法f() 形构完全一致,这样是否可以称为“覆盖(重写)”呢?
本问题的关键点是“动态绑定”的问题,而不是说“static方法不能重写”;
请高手排砖。
但不能重载的,既然是static那么在内存中就只有一个单位了,重载了那不又产生一个单位了吗
个人认为是不能重载的 但可以覆盖,想上面的例子
希望高人出来指正啊
你用的是 B b = new B();而不是A b = new B();
当然是调用B的f()方法拉~
1.根据Java Language Specification (Version 3) 8.4.8 的描述,子类在继承父类时,对于方法而言,存在两种关系:
A. override 即覆盖,这是对实例方法(instance method)而言的;子类与父类中形构相同的方法(原文中是 subsignature,它的范围比“形构相同”要大,请参考原文)会override 父类中的那个方法。 B. hide 即隐藏,这是对类方法(class method)即static 方法而言的。如果子类中定义了静态方法,则它会隐藏父类中形构相同的(原文中是 subsignature,它的范围比“形构相同要”大,请参考原文)所有方法,但如果隐藏了父类中的实例方法,则会编译报错。2.根据上面的规范:
“override 覆盖”的前提是 实例方法,只有实例方法在继承时才会出现override情况。
如果是static方法,在继承时出现的现象根本就不能用“override”这个词描述,如果static方法在父类和子类中形构一致,则被成为 hide(隐藏)。3.因为static方法是类方法,实现时是静态绑定的(引用“JAVA 核心技术 卷1 第六版”中149页内容“private、static、final”修饰的方法是静态绑定的。其他的方法在运行时动态绑定。“interhanchi”所说的“static和final方法外都是后期绑定”并不精确),只与类相关,不会有多态性。 从编程的角度看,效果好像是“static方法不能被覆盖”;4.从术语上看,“static方法能否被覆盖”这种说法本身就是错误的,因为“覆盖”定义的前提和基础是实例方法。5.结论: 子类中的static方法会隐藏父类中形构相同的static方法。附:关于Java 的隐藏 机制,几本经典的书都没有详细说明。准备写一个这方面的材料,请有兴趣的朋友关注 http://blog.csdn.net/jidongxx。
B.f();
就可以了,
你在程序中将B向上转型为A后再调用f()
其实等于A.()
所以STATIC 方法在继承中要特别注意
如果是public属性,那么它就好比一个全局方法.
前面提到的子类改变静态方法的返回类型会编译出错,个人认为仅仅是编译器把它当成了override行为,实际上跟override是不相干的.
而普通方法能被覆盖,覆盖的结果是产生多态;例子:
package test;class Test {
public static void main(String[] args) {
A a = new B();
a.f();
a.m();
}
}class A {
public static void f() {
System.out.println("hello,A");
}
public void m() {
System.out.println("hello,A");
}
}class B extends A {
public static void f() {
System.out.println("hello,B");
}
public void m() {
System.out.println("hello,B");
}
}结果是:hello,A
hello,B
没有override这一说法。
静态方法是可以被继承的,可以用例子检验一下。to jide_123()
“子类中的static方法会隐藏父类中形构相同的static方法”是相对子类说的,如果子类和父类具有形构相同的static方法,使用子类名或子类的对象调用这个static方法时,真正调用的是子类的static方法; 这个现象称为“隐藏”,或者说“隐藏了父类中同构的static方法”。
这与 static方法的静态绑定并不矛盾,tangqs(leon_tangqs)给出的程序中,
public static void main(String [] args) {
A a = new B();
a.f();
}
a 是 类A 的对象,而方法f是静态方法,因为静态绑定,所以调用的是 A的静态方法。