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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 danielzyj 于 2014-3-26 09:48 编辑

父类中的static方法能否在子类中被重写?

class Fu
{
        static void show()
        {
                  code.......;
         }

}
class Zi extends Fu
{
        static void show()
        {
                  code.......;
         }
}

这样算是重写吗?


Fu f = new Zi();
f.show();调用哪个方法?


在内存中他两个是不是在一起啊

评分

参与人数 1技术分 +1 收起 理由
枫儿 + 1 神马都是浮云

查看全部评分

9 个回复

倒序浏览
覆盖:
1,子类覆盖父类,必须保证子类权限大于等于父类权限,才可以覆盖,否则编译失败。

2,静态只能覆盖静态。
所以你上边的程序算是重写。
调用子类的方法
回复 使用道具 举报
  1. public class TestMain {

  2.         public static void main(String[] args) {
  3.                 Fu f = new Zi();
  4.                 f.show();
  5.                
  6.                 Zi z = new Zi();
  7.                 z.show();
  8.         }
  9.        
  10. }

  11. class Fu
  12. {
  13.         static void show()
  14.         {
  15.                 System.out.println("Fu show");
  16.          }

  17. }
  18. class Zi extends Fu
  19. {
  20.         static void show()
  21.         {
  22.             System.out.println("Zi show");
  23.          }
  24. }
复制代码


执行我这个代码,你就知道调用的父类还是子类的方法

评分

参与人数 1技术分 +1 收起 理由
枫儿 + 1 赞一个!

查看全部评分

回复 使用道具 举报
对于静态方法,只能是静态方法覆盖静态方法,你那种情况是覆盖。但是因为是Fu类引用f调用,所以调用的是父类的show()。  这时其实就是看是谁的引用,而不看对象了。对于静态的结合 类名.方法() ,这种调用方法来理解。
回复 使用道具 举报
官方文档是这样写的:

Class methods

If a subclass defines a class method with the same signature as a class method in

the superclass, the method in the subclass hides the one in the superclass.

如果一个子类定义了一个和父类静态方法中相同的方法(即方法名,参数和返回类型相同),

则该类隐藏了父类中的这个方法。

The distinction between hiding and overriding has important implications. The

version of the overridden method that gets invoked is the one in the subclass. The

version of the hidden method that gets invoked depends on whether it is invoked

from the superclass or the subclass

而该隐藏的静态方法是否被调用,取决于是父类(引用)还是子类(引用)调用了该静态方法
以下是一个例子:
  1. public class Test2
  2. {
  3.     public static void main(String[] args)
  4.     {

  5.        //需要注意的是,这里跟以往的父类引用指向子类对象有点不用

  6.        //这个子类创建的对象是由子类类型“N”引用的,所以调用output方法将输出“N”

  7.         N n = new N();
  8.         n.output();

  9.       //这个子类创建的对象是由父类类型“M”引用的,所以调用output方法将输出“M”
  10.         M m = new N();
  11.         m.output();
  12.     }
  13.    
  14. }

  15. class M
  16. {
  17.     public static void output()
  18.     {
  19.         System.out.println("M");
  20.     }
  21. }

  22. class N extends M
  23. {
  24.     public static void output()
  25.     {
  26.         System.out.println("N");
  27.     }
  28. }
复制代码

评分

参与人数 1技术分 +1 收起 理由
何伟超 + 1

查看全部评分

回复 使用道具 举报
父类中的方法不是静态的,那么子类中的同名方法也不可以是静态的,也就是说静态的方法不能被覆盖,静态的方法也不能覆盖非静态的,总之一句话:静态的都不能覆盖,要么全静态,要么全非静态。
回复 使用道具 举报
本帖最后由 caijunsong 于 2014-3-26 01:34 编辑

首先回答  父类的static方法是可以在子类重写的
我们把子类包含父类同名方法的现象称为覆盖
方法重写要遵从两同两小一大的原则
所谓两同就是 函数名和函数的参数列表必须相同
两小包括1、子类方法返回值的类型应比父类方法返回值的类型的更小或者相等
            2、子类声明抛出的异常类应比父类方法抛出的异常类更小或相等
一大就是指子类的方法访问权限比父类的方法访问权限更大或者相等
因此从以上原则看 你的写得代码简写是方法重写

  1. class fu//父类
  2. {
  3.         public  static void show()//------1
  4.         {
  5.                 System.out.println("我是父类的方法");
  6.         }
  7. }
  8. class zi extends fu//子类
  9. {
  10.         public static void show()//-------2
  11.         {
  12.                 System.out.println("我是子类的方法");
  13.         }
  14. }
  15. public class Demo
  16. {
  17.          public static void main(String[]agrs)
  18.         {
  19.          fu f=new fu();
  20.                  f.show();//父类对象调用父类自己的方法
  21.                  zi z=new zi();
  22.                  z.show();//子类调用的是自己的方法
  23.                  //结果显示
  24.                        //我是父类的方法
  25.                            //我是子类的方法
  26.         }
  27. }
  28. //首先验证方法的访问权限 加static的方法的访问权限是比不加static的方法的访问权限大
  29. //因为static成员属于类 而不加static的成员属于对象   
  30. //我们可以尝试把2中方法的static省略下,编译的时候就会出现zi中的show无法覆盖fu中的show
  31. //的提示语 因为子类的方法的权限小于父类方法的权限 其他的原则你自己可以验证
复制代码

回复 使用道具 举报
追逐 高级黑马 2014-3-26 08:10:32
8#
对于静态方法,只能是静态方法覆盖静态方法,你那种情况是覆盖。但是因为是Fu类引用f调用,所以调用的是父类的show()。因为静态的变量或者函数是随着类的加载而加载进内存中的。
在静态中对象调用时。
编译时看右边。运行时看左边。所以调用的肯定是父类的方法
在非静态的方法调用时。无论是编译时还是运行时都是看右边
就像你写的。因为是静态的。所以对象调用的就是父类的静态方法
如果是非静态的,那么调用的就是子类的函数



静态:static
用法:是一个修饰符,用于修饰成员(成员变量和成员函数)
当成员被静态修饰后。就多了一个调用方式,除了可以被对象调用外,
还可以直接被类名调用,类名。静态成员

static特点:
1,随着类的加载而加载
        也就是说:静态会随着类的消失而消失,说明它的生命周期最长。
2,优先于的对象存在
        明确一点:静态是先存在,对象是后存在的。
3,被所有对象所共享
4,可以直接被类名所调用。

实例变量和类变量的区别:
1,存放位置。
        类变量(静态的成员变量)随着类的加载而存在于方法区中。
        实例变量(非静态成员变量)随着对象的建立而存在于堆内存中。
2生命周期:
        类变量的生命周期最长,随着类的消失而消失。
        实例变量生命周期随着对象的消失而消失

静态的注意事项:
1,静态方法只能访问静态成员
        非静态方法既可以访问静态也可以访问非静态
2,静态方法中不可以定义this、super关键字。
        因为静态优先于对象存在,所以静态方法中不可以出现this。
3,主函数是静态的

静态有利有弊
利处:对对象的共享进行单独空间的存储,节省空间。没有必要每一个对象中        都存储一份。
        可以直接被类名调用。
弊端:生命周期过长。
        访问出现局限性(静态虽好。但是只能访问静态)



                什么时候使用静态?
要从两方面下手;
因为静态修饰的内容有成员变量和函数。
什么时候定义静态变量(类变量)呢?
当对象中出现共享数据时,该数据被静态所修饰。
对象中的特有数据要定义成非静态存在于堆内存中。


什么时候定义静态函数呢?

当功能内部没有访问到非静态数据(对象的特有数据)。
那么该功能可以定义成静态的。
回复 使用道具 举报 1 0
追逐 发表于 2014-3-26 08:10
对于静态方法,只能是静态方法覆盖静态方法,你那种情况是覆盖。但是因为是Fu类引用f调用,所以调用的是父 ...

总结的真好,顶一个!!
回复 使用道具 举报
北极雪871208 发表于 2014-3-26 08:24
总结的真好,顶一个!!

呵呵。能对你有所帮助就好
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马