A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 梁耀今 中级黑马   /  2013-4-12 14:16  /  1508 人查看  /  7 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 梁耀今 于 2013-4-13 18:15 编辑

静态覆盖和非静态覆盖有什么区别?

7 个回复

倒序浏览
静态覆盖只能用来覆盖静态的,而非静态没有这个限制;还有就是静态方法可以用类名去直接调用它,而非静态的方法,必须要先创建对象才能去调用它;在内存中,静态方法的执行优先于非静态的方法,且静态方法存储在方法区而不是在每个新建的对象中,这也一定程度上提高了程序的复用性。
回复 使用道具 举报
本帖最后由 杨冉 于 2013-4-12 14:42 编辑

尝试写这么一串简单的代码就能很清楚的分析出静态方法和非静态方法覆盖的特点了:
  1. class Father {     
  2.            
  3.         public void method() {        
  4.                System.out.println("父类非静态方法");     
  5.         }      
  6.            
  7.         public static void staticMethod() {      
  8.                       System.out.println("父类静态方法");      
  9.         }
  10. }     
  11.            
  12. class Son extends Father {     
  13.            
  14.         public void method() {      
  15.            
  16.                   System.out.println("子类非静态方法");      
  17.            
  18.         }      
  19.            
  20.         public static void staticMethod() {     
  21.            
  22.                        System.out.println("子类静态方法");      
  23.         }      
  24.            
  25. }     

  26. public class OverrideTest {

  27.         public static void main(String[] args) {
  28.                 Father f1 = new Father();
  29.                 Father f2 = new Son();         
  30.                 Son s = new Son();
  31.                
  32.                
  33.                 f1.method();
  34.                 f2.method();
  35.                 Father.staticMethod();
  36.                 f1.staticMethod();
  37.                 f2.staticMethod();
  38.                
  39.                
  40.                
  41.                 s.method();
  42.                 Son.staticMethod();
  43.                 s.staticMethod();
  44.         }

  45. }
复制代码

评分

参与人数 1技术分 +1 收起 理由
冯海霞 + 1

查看全部评分

回复 使用道具 举报
子类的静态方法不能覆盖父类当中的非静态方法,否则编译失败,如:
  1. class Fu
  2. {
  3. public  void run()
  4. {
  5.   System.out.println("bbbbbbbb");
  6. }
  7. }
  8. class Zi extends Fu
  9. {
  10. public static void run()
  11. {
  12.   System.out.println("aaaaaaaa");
  13. }
  14. }
  15. 编译失败
复制代码
子类的非静态方法不能覆盖父类的静态方法,否则编译失败,如:
  1. class Fu
  2. {
  3. public  static void run()
  4. {
  5.   System.out.println("bbbbbbbb");
  6. }
  7. }
  8. class Zi extends Fu
  9. {
  10. public  void run()
  11. {
  12.   System.out.println("aaaaaaaa");
  13. }
  14. }
  15. 编译失败
复制代码
子类的可以继承父类当中的静态方法,但是不能覆盖,如:
  1. class F
  2. {
  3. public static void show()
  4. {
  5.   System.out.println("AAAAAAAAA");
  6. }
  7. }
  8. class  Z extends F
  9. {
  10. public static void main(String[] args)
  11. {
  12.   F f = new Z();
  13.   f.show();
  14. }
  15. public static void show()
  16. {
  17.   System.out.println("aaaaaaaaaa");
  18. }

  19. }
  20. 输出:AAAAAAAAA
复制代码
子类的非静态方法可以覆盖父类的非静态方法,这就不用我举例了吧!

总结:
子类的静态方法不能覆盖父类当中的非静态方法,否则编译失败
子类的非静态方法不能覆盖父类当中的静态方法,否则编译失败
即只有子类和父类同是静态方法或者同是非静态才能编译通过。
子类的可以继承父类当中的静态方法,但是不能覆盖。
子类的非静态方法可以覆盖父类的非静态方法。
你可以这样理解:静态是随着类的加载而加载的,先于对象而存在,当然不能被覆盖了~~

评分

参与人数 1技术分 +1 收起 理由
冯海霞 + 1

查看全部评分

回复 使用道具 举报
首先看一个JAVA文件:Test.java


class A{
    public static void testP(){
       System.out.println("A");
       }
    public void testM(){
       System.out.println("X");
       }
}

class B extends A{
    public static void testP(){
       System.out.println("B");
       }
    public void testM(){
       System.out.println("Y");
       }
}

public class Test{
    public static void main(String[] args){
       A a=new A();
       B b=new B();
       a.testP();//结果是 A
       b.testP();//结果是 B
       a.testM();//结果是 X
       b.testM();//结果是 Y
       a=b;
       a.testP();//结果是  A
       b.testP();//结果是  B
       a.testM();//结果是  Y
       b.testM();//结果是  Y
       }
}


这样可以看到结果:
    非静态方法的继承覆盖的原则是向上转型,从他的实例中可而已看出来,但是静态方法却不是像非静态方法那样工作,虽然静态方法可以被继承但是为什么不能覆盖呢?
    原因是这样的,静态方法跟其他非静态方法不一样的区别在于静态方法不用NEW一个实例就可以调用的,即它的调用是根据他的类型来判断的,所以我总结一句话就是:静态方法的继承和覆盖是跟着引用类型的,而非静态方法是跟着实例本身的。

评分

参与人数 1技术分 +1 收起 理由
冯海霞 + 1

查看全部评分

回复 使用道具 举报
本帖最后由 lyg2013 于 2013-4-12 20:01 编辑

http://school.cnd8.com/java/jiaocheng/19109.htm首先我们提供两个类,基类为Parent,派生类为Child。在Parent中我们提供两个方法,一个是静态方法staticMethod(),一个是非静态方法nonStaticMethod()。在Child类中我们覆盖着两个方法。
  1. class Parent
  2.   {
  3.    public void nonStaticMethod()
  4.    {
  5.     System.out.println("Parent's Non-Static Method is Called");
  6.    }
  7.   
  8.    public static void staticMethod()
  9.    {
  10.     System.out.println("parent's static method is called");
  11.    }
  12.   }

  13.   class Child extends Parent
  14.   {
  15.    public void nonStaticMethod()
  16.    {
  17.     System.out.println("child's non-static method is called");
  18.    }
  19.   
  20.    public static void staticMethod()
  21.    {
  22.     System.out.println("child's static method is called");
  23.    }
  24.     
  25.   }
复制代码
在Test类中我们分别使用Parent p1 = new Parent(),Parent p2 = new Child(),Child c = new Child()得到三个实例,并分别调用静态方法和非静态方法,我们来看程序的运行结果
  1. public class Test
  2.   {
  3.            public static void main(String args[])
  4.            {
  5.             Parent p1 = new Parent();
  6.             Parent p2 = new Child();
  7.             Child c = new Child();
  8.             System.out.print("Parent.static: "); Parent.staticMethod();
  9.             System.out.print("p1.static: "); p1.staticMethod();
  10.             System.out.print("p2.static: "); p2.staticMethod();
  11.             System.out.print("p1.nonStatic: "); p1.nonStaticMethod();
  12.             System.out.print("p2.nonStatic: "); p2.nonStaticMethod();
  13.             System.out.print("Child.static: "); Child.staticMethod();
  14.             System.out.print("c.static: "); c.staticMethod();
  15.             System.out.print("c.nonStatic: "); c.nonStaticMethod();
  16.            }

  17.   }
复制代码
  1. 程序的运行结果为:
  2.   Parent.static: parent's static method is called
  3.   p1.static: parent's static method is called
  4.   p2.static: parent's static method is called
  5.   p1.nonStatic: Parent's Non-Static Method is Called
  6.   p2.nonStatic: child's non-static method is called
  7.   Child.static: child's static method is called
  8.   c.static: child's static method is called
  9.   c.nonStatic: child's non-static method is called
复制代码
值得注重的是p2实际上是一个Child的类型的引用,然而在调用静态方法的时候,它执行的却是父类的静态方法,而不是Child的静态方法,而调用 p2的非静态方法的时候执行的是Child的非静态方法,为什么呢?原因是静态方法是在编译的时候把静态方法和类的引用类型进行匹配,而不是在运行的时候和类引用进行匹配。因此我们得出结论:当我们在子类中创建的静态方法,它并不会覆盖父类中相同名字的静态方法。

引用。。

评分

参与人数 1技术分 +1 收起 理由
冯海霞 + 1

查看全部评分

回复 使用道具 举报
  1. public class StaticTest {
  2.         public static void main(String[] args) {
  3.                 Son son = new Son();
  4. //                子类调用非静态方法
  5.                 son.show();
  6. //                子类调用静态方法
  7.                 Son.show_1();
  8.         }
  9. }

  10. class Father {
  11.         public static void show() {
  12.                 System.out.println("这是父类中的静态方法");
  13.         }

  14.         public void show_1() {
  15.                 System.out.println("这是父类中的非静态方法");
  16.         }
  17. }

  18. class Son extends Father {
  19.         //此处会提示:“This static method cannot hide the instance method from Father”
  20.         public static void show_1() {
  21.                 System.out.println("这是子类中的静态方法");
  22.         }
  23.         //此处会提示:This instance method cannot override the static method from Father
  24.         public void show() {
  25.                 System.out.println("这是子类中的非静态方法");
  26.         }
  27. }
复制代码
如果尝试使用静态方法去覆盖动态,或者动态覆盖静态,就会出现像以上代码注释处提示的编译错误。
这说明静态和非静态方法不能互相覆盖。
  1. public class StaticTest {
  2.         public static void main(String[] args) {
  3.                 Father son = new Son();
  4. //                子类调用非静态方法
  5.                 son.show();
  6. //                子类调用静态方法
  7.                 Son.show();
  8.         }
  9. }

  10. class Father {
  11.         public static void show() {
  12.                 System.out.println("这是父类中的静态方法");
  13.         }

  14.         public void show_1() {
  15.                 System.out.println("这是父类中的非静态方法");
  16.         }
  17. }

  18. class Son extends Father {
  19.         //此处会提示:“This static method cannot hide the instance method from Father”
  20.         public static void show() {
  21.                 System.out.println("这是子类中的静态方法");
  22.         }
  23.         //此处会提示:This instance method cannot override the static method from Father
  24.         public void show_1() {
  25.                 System.out.println("这是子类中的非静态方法");
  26.         }
  27. }
复制代码
稍作修改,多态的情况,都试图调用子类中的静态show()方法,但是结果会显示调用的show()不是同一个,第一个调用的其实是父类的show(),这说明,静态方法只跟编译时调用它的对象有关系,而不是多态的运行期绑定。

总结下:
静态方法只能覆盖静态方法。
非静态方法只能覆盖非静态方法。



评分

参与人数 1技术分 +1 收起 理由
冯海霞 + 1

查看全部评分

回复 使用道具 举报
hacket 高级黑马 2013-4-13 01:07:18
8#
本帖最后由 hacket 于 2013-4-13 01:08 编辑

静态方法是在编译的时候把静态方法和类的引用类型进行匹配,而不是在运行的时候和类引用进行匹配。因此我们得出结论:当我们在子类中创建的静态方法,

它并不会覆盖父类中相同名字的静态方法。

详情请参考,写的很详细:http://blog.csdn.net/cynhafa/article/details/6903102
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马