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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 付信榕 中级黑马   /  2012-6-10 09:49  /  3429 人查看  /  14 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 付信榕 于 2012-6-13 10:30 编辑

视频资料的原笔记:
覆盖:
1,子类覆盖父类,必须保证子类权限大于等于父类权限,才可以覆盖,否则编译失败。
2,静态只能覆盖静态。//关键是这句话的理解

public class TestOverride{
public static void main(String[] args){
  Super s=new Sub();//多态
  System.out.println(s.a);
  s.ma();
  s.mb();
}
}
class Super{
int a=10;
public void ma(){
  System.out.println("Super Ma");
}
public static void mb(){
  System.out.println("Super Static Mb");
}
}
class Sub extends Super{
int a=20;
public void ma(){
  System.out.println("Sub Ma");
}
public  static void mb(){
  System.out.println("Sub Static Mb");
}
}
输出结果
10
Sub Ma
Super Static Mb//父类静态方法,子类的静态方法并没有被调用。
问题是:子类的public  static void mb()方法到底算不算、有没有覆盖了父类的public static void mb()方法???
不算的话,什么情况有静态方法覆盖静态方法呢?

评分

参与人数 1技术分 +1 收起 理由
黄奕豪 + 1 赞一个!

查看全部评分

14 个回复

倒序浏览
在多态中:还是老毕总结的那句话:编译看左边,运行看右边。这是指一般的成员方法
但是针对成员变量静态成员函数时, 无论编译还是运行 都参考左边,(也就是父类的。)  这个知识点经常在面试中出现。
个人认为:在这里的父类的静态方法,在多态过程中比子类new对象前就已经放入方法区了。 如果想调用子类的静态构造方法,直接  类名.函数名也就OK了

评分

参与人数 1技术分 +1 收起 理由
黄奕豪 + 1 赞一个!

查看全部评分

回复 使用道具 举报
原因是静态方法是在编译的时候把静态方法和类的引用类型进行匹配,而不是在运行的时候 和类引用进行匹配。因此我们得出结论:当我们在子类中创建的静态方法,它并不会覆盖父类中相同名字的静态方法。


回复 使用道具 举报
子类的方法当然算啦~只不过没有覆盖父类的public static void mb()静态方法。
原因是:
静态方法是在编译的时候把静态方法和类的引用类型进行匹配,而不是在运行的时候和类引用进行匹配。因此我们得出结论:
当我们在子类中创建的静态方法,它并不会覆盖父类中相同名字的静态方法。

要注意:

1. 试图用子类的静态方法隐藏父类中同样标识的实例方法是不合法的,编译器将会报
错;
2. 试图用子类的实例方法覆盖父类中同样标识的静态方法也是不合法的,编译器同样
会报错;
3. 静态方法和最终方法(带关键字final 的方法)不能被覆盖;
所以啦~你可以把它等同于final理解!也就是什么情况下都不能被覆盖!

点评

回答很好,赞一个!  发表于 2012-6-10 10:47

评分

参与人数 1技术分 +1 收起 理由
黄奕豪 + 1 赞一个!

查看全部评分

回复 使用道具 举报
实例方法能覆盖,静态方法被隐藏了
回复 使用道具 举报
override可以翻译为覆盖,从字面就可以知道,它是覆盖了一个方法并且对其重写,以求达到不同的作用。对我们来说最熟悉的覆盖就是对接口方法的实现,在接口中一般只是对方法进行了声明,而我们在实现时,就需要实现接口声明的所有方法。除了这个典型的用法以外,我们在继承中也可能会在子类覆盖父类中的方法。在覆盖要注意以下的几点:
1、覆盖的方法的标志必须要和被覆盖的方法的标志完全匹配,才能达到覆盖的效果;
2、覆盖的方法的返回值必须和被覆盖的方法的返回一致;
3、覆盖的方法所抛出的异常必须和被覆盖方法的所抛出的异常一致,或者是其子类;
4、被覆盖的方法不能为private,否则在其子类中只是新定义了一个方法,并没有对其进行覆盖。
overload对我们来说可能比较熟悉,可以翻译为重载,它是指我们可以定义一些名称相同的方法,通过定义不同的输入参数来区分这些方法,然后再调用时,VM就会根据不同的参数样式,来选择合适的方法执行。在使用重载要注意以下的几点:
1、在使用重载时只能通过不同的参数样式。例如,不同的参数类型,不同的参数个数,不同的参数顺序(当然,同一方法内的几个参数类型必须不一样,例如可以是fun(int,float),但是不能为fun(int,int));
2、不能通过访问权限、返回类型、抛出的异常进行重载;
3、方法的异常类型和数目不会对重载造成影响;
4、对于继承来说,如果某一方法在父类中是访问权限是priavte,那么就不能在子类对其进行重载,如果定义的话,也只是定义了一个新方法,而不会达到重载的效果。
下面是对override和overload的测试程序,其中注释中的内容都是会产生编译错误的代码,我们将注释去掉,看看在编译时会产生什么效果。
回复 使用道具 举报
静态的方法不能被重写吧 override 只不过是名字相同 各用各的 用类名.静态方法名 直接调用就可以啦
回复 使用道具 举报
覆盖了,只是在多态中,不管是静态成员变量还是成员函数运行和编译都是参考左边(也就是引用型变量所属的类)
回复 使用道具 举报
朝哥 中级黑马 2012-6-10 10:54:17
9#
lz,记住这一句话,成员变量的调用是从父类到子类,成员方法的调用从子类到父类。
不管你加没加static,只要遵循你笔记的两点就行。
静态只能重写静态的意思是,你的方法是静态的,你父类与你有一样的方法,此时满足老师说的下面条件就行

重写:
**存在于子父类当中。
**方法的声明一致。(名称和参数)
**子类的访问权限不能低于父类的访问权限。

看到没有,没有强调static,说明是要(1)子父的方法都是static,(2)子类加static,而父类没加(3)都没加
满足这三点都是重写(覆盖了)了


回复 使用道具 举报
还有,你测试一下就知道,把父类的static去掉,编译器会报错:
错误: Sub中的mb()无法覆盖Super中的mb()

说明肯定存在子类static方法覆盖父类static方法了,上面有做过测试吗?

评分

参与人数 1技术分 +1 收起 理由
黄奕豪 + 1 赞一个!

查看全部评分

回复 使用道具 举报
朝哥 发表于 2012-6-10 10:54
lz,记住这一句话,成员变量的调用是从父类到子类,成员方法的调用从子类到父类。
不管你加没加static,只要 ...

修正一下,第二点是错的,只能满足(1)和(3)两点。要么都静态,要么都不静态
回复 使用道具 举报
很不错的问题,赞一个
回复 使用道具 举报
class Test6{
public static void main(String[] args){
Super s=new Sub();//多态
  System.out.println(s.a);
  s.ma();
  s.mb();
  
}
}
class Super{
int a=10;
public void ma(){
  System.out.println("Super Ma");
}
public static void mb(){
  System.out.println("Super Static Mb");
}

}
class Sub extends Super{
int a=20;
public void ma(){
  System.out.println("Sub Ma");
}
public  static void mb(){//确实已经覆盖了父类的方法
                                                //写成Sub s=new Sub();就可以调用子类中的覆盖的方法了
                             //Super s=new Sub();是多态
                                                 //多态的特点:父类的引用指向子类的对象
                                                 //静态函数以及成员变量具有其特殊性,因为它们都是在类加载的时候,就已经加载到内存里了.
                                                 /*Super s=new Sub();父类引用在使用方法或成员变量时,应该遵循下面步骤:
                                                                1,在父类中是不是存在该方法或者成员变量.
                                                                                2,如果存在,编译通过
                                                                                3,如果调用的是成员变量,只看父类中的成员变量.
                                                                                4,调用的方法是静态的,即使子类重写了该方法,jvm也会优先选择调用父类的
                                                                                5,一般函数子类如果有覆盖,就调用子类的
                                                                                */
  System.out.println("Sub Static Mb");
}

}
回复 使用道具 举报
就像老毕说的那样,想想内存,想想时间,因为静态比非静态更早出现,所以静态只能覆盖静态
回复 使用道具 举报
个人查阅些资料,比较认同静态方法没有被覆盖。
资料1、静态方法覆盖为什么不能用override标注
因为对静态方法的调用不存在任何动态的分派机制

子类虽然覆写了父类的静态方法,但是这并不会被判定为是重写(Override).

会提示错误.
The method XXXXX() of type XXXX must override or implement a supertype method

资料2、静态方法是在编译的时候把静态方法和类的引用类型进行匹配,而不是在运行的时候和类引用进行匹配。因此我们得出结论:当我们在子类中创建的静态方法,它并不会覆盖父类中相同名字的静态方法。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马