黑马程序员技术交流社区

标题: 父类中的static方法能被子类重写吗 [打印本页]

作者: zcbyzcb    时间: 2013-5-15 22:05
标题: 父类中的static方法能被子类重写吗
本帖最后由 zcbyzcb 于 2013-5-17 09:47 编辑

今天学习过程中把老师的计算程序运行时间时方法都加了static,发现没有像想象中那样的结果,代码如下:
class GetTime//父类
{
        public static void  getTime()
        {
                long start=System.currentTimeMillis();
                runCode();
                long end=System.currentTimeMillis();
                System.out.println("\n毫秒数:"+(end-start));
        }
        public  static void runCode()
        {
                for(int i=0; i<1000; i++)
                {
                        System.out.print(i);
                }
        }
}

class MyTime extends GetTime
{
        public static void runCode()
        {
                for(int i=0; i<4000; i++)
                {
                        System.out.print(i);
                }
        }
}
class  Demo
{
        public static void main(String[] args)
        {
                //GetTime.getTime();
               
                GetTime M=new MyTime();
                M.getTime();
                //MyTime.getTime();
        }
}

子类中的runCode方法应该能覆盖父类中的方法呀,加了static,执行的是父类中的runCode,而不加static执行的是子类中的runCode,static方法应该可以被继承的,为何会出现这种结果?
作者: 刘学明       时间: 2013-5-15 22:50
楼主 您的这个问题毕老师有讲到过而且很全面
包括非静态成员函数,成员变量 ,静态成员函数在多态中的特点。

下面以一个例子来说明:

  1.   class Fu   //定义了一个父类
  2.   {
  3.         int num = 5;
  4.         void method1()
  5.         {
  6.                 System.out.println("父类的非静态方法");
  7.         }
  8.         static void method2()
  9.         {
  10.                 System.out.println("父类的静态方法");
  11.         }
  12.        
  13.   
  14.   class Zi extends Fu  //定义了一个子类 继承父类
  15.   {
  16.         int num = 8;
  17.         void method1()
  18.         {
  19.                 System.out.println("子类的非静态方法");
  20.         }
  21.         static void method2()
  22.         {
  23.                 System.out.println("子类的静态方法");
  24.         }
  25.   }
  26.   public class  DuoTai        
  27.   {
  28.         public static void main(String[] args)
  29.         {
  30.                 Fu f = new Zi();      //父类的引用f指向了子类的对象
  31.                 System.out.println(f.num);
  32.                 f.method1();
  33.                 f.method2();
  34.                

  35.                 Zi z = new Zi();  //子类的引用z指向了子类对象
  36.                 System.out.println(z.num);
  37.                 z.method1();
  38.                 z.method2();
  39.         }
  40.   }

  41. 打印结果:

  42. 5
  43. 子类的非静态方法
  44. 父类的静态方法
  45. 8
  46. 子类的非静态方法
  47. 子类的静态方法
复制代码
根据打印结果总结如下:
  (1)多态中成员函数的特点:成员函数在多态调用时,编译看左边,运行看右边。
  (2)多态中成员变量的特点:无论编译和运行,都参考左边(引用型变量所属的类).
  (3)多态中静态成员函数的特点 :无论编译和运行,也都参考左边。

作者: 第一枭雄    时间: 2013-5-15 22:52
不用static修饰的时候就不用解释了,直接继承重写,,但是用static的时候要考虑下static修饰符的作用
在方法中加不加static是完全不同的,可以这样认为,在内存的方法区中有两块放方法的区域,一块是静态方法区,还有一块儿非静态方法区
不用static修饰的方法放在非静态方法区中,每创建一个对象就会有一个这个方法。此方法是每个对象私有的。
而用static修饰的方法在静态方法去中,他只加载一次,是所有方法公用的。
而你说的继承中static其实跟这原因一样,不用static的时候这个方法可以出现多次,父类和子类各是各的,所以你执行的时候是子类的
而用static的时候加载了父类的这个方法后就被以后的这个方法共享,就是不会再加载
所有就造成了你这个问题

我也是学员,反正我是这么认为的,你可以参考一下
作者: 张迁    时间: 2013-5-15 23:09
静态的话,没有重写这一说,直接用类名调用。 M.getName(),当然运行父类的静态方法
作者: 飞鸟青崖    时间: 2013-5-16 07:21
第一:你这叫多态:GetTime M=new MyTime();其中的M是父类的引用 ,后面又是子类的对象。很明显是父类的引用指向子类的对象。
对于多态来说:静态方法和成员变量都是按照父类中进行运行的。
第二:即使你写成MyTime M= new MyTime(),再通过M来调用getTime()方法时,运行的还是父类的,因为你在子类中没有重写父类的这个方法,
那么这个方法调用的别的方法都是父类中的。如果你想运行子类中的runCode()方法,只能在子类中重写父类的getTime()方法。
第三:静态的方法可以被覆盖,但是只能用静态去覆盖静态。
下面的这个代码运行的就是子类中的runCode()方法


  1. class GetTime//父类
  2. {
  3.         public static void  getTime()
  4.         {
  5.                 long start=System.currentTimeMillis();
  6.                 runCode();
  7.                 long end=System.currentTimeMillis();
  8.                 System.out.println("\n毫秒数:"+(end-start));
  9.         }
  10.         public  static void runCode()
  11.         {
  12.                 for(int i=0; i<1000; i++)
  13.                 {
  14.                         System.out.print(i);
  15.                 }
  16.                 System.out.println("父类中的");//加上这句是为了看的方法些
  17.         }
  18. }

  19. class MyTime extends GetTime
  20. {
  21.         public static void runCode()
  22.         {
  23.                 for(int i=0; i<4000; i++)
  24.                 {
  25.                         System.out.print();
  26.                 }
  27.                 System.out.println("子类中的");
  28.         }
  29.         public static void  getTime()//覆盖父类的方法,不然运行的时候调用的还是父类中的runCode。
  30.         {
  31.                 long start=System.currentTimeMillis();
  32.                 runCode();
  33.                 long end=System.currentTimeMillis();
  34.                 System.out.println("\n毫秒数:"+(end-start));
  35.         }
  36. }
  37. class  Demo
  38. {
  39.         public static void main(String[] args)
  40.         {
  41.                 //GetTime.getTime();
  42.                
  43.                 MyTime M=new MyTime();//用子类来创建对象,不是用父类的引用来指向子类的对象
  44.                 M.getTime();
  45.                 //MyTime.getTime();
  46.         }
  47. }
复制代码

作者: zcbyzcb    时间: 2013-5-16 15:54
多谢各位的指点,明白了,多态还没有看到,不过明白了。
作者: zcbyzcb    时间: 2013-5-16 16:10
哎,真心的感觉到了,这里真是个好地方,任何问题都能再最快的时间得到解决。




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2