我们知道,在JAVA中,子类可以继承父类,如果子类声明的方法与父类有重名的情况怎么办,大伙儿都知道要是重写,但是实际上这又分为两种情况,就是方法和变量在继承时的覆盖和隐藏问题,这些概念性的东西看似无聊,但是在面试或者是SCJP认证题中围绕这些是会经常碰到的,所以这里来讨论下

首先我们来看几个概念

类变量:又叫静态变量,这种变量属于类,通过类名就可以访问类变量。

实例变量:属于类的实例,即对象,通过对象可以访问实例变量,但是不能通过类名访问实例变量。

静态方法:通过类名访问。

实例方法:对象访问,不能通过类名访问。

隐藏 :child隐藏了parent的变量和方法,那么,child不能访问parent被隐藏的变量或者方法,但是,将B转换成A中,可以访问A被隐藏的变量或者方法

覆盖 :child覆盖了parent的变量或者方法,那么,child不能访问parent被覆盖的变量或者方法,将child转换成parent后同样不能访问parent被覆盖的变量或者方法

首先看一下JAVA中方法和变量在继承时的覆盖和隐藏规则

1.父类的实例变量和静态变量能被子类的同名变量隐藏

2.父类的静态方法被子类的同名静态方法隐藏

3.父类的实例方法被子类的同名实例变量覆盖

      作为通用的规则:覆盖实例方法时,新方法的访问控制不能比原来的方法更严格,但可以更松。

      1.在超类中被声明为公有的实例方法,在子类中也必须是公有的;

      2.在超类中被声明为保护的实例方法,在子类中可以是保护的或公有的,但不能私有的。

      3.在超类中默认的实例方法,在子类中其访问控制可以更严格。

      4.在超类中被声明为私有的实例方法根本不能继承,也不能被覆盖。

子类覆盖父类的实例方法,必须有同样的(参数列表、参数名、参数返回类型),否则编译不能通过。
      子类覆盖父类的实例方法,在jdk1.5后,参数返回类可以是父类方法返回类的子类

子类的静态方法不能隐藏同名的父类实例方法
       java与C++一样,继承的方法具有多态性

还有几点需要注意的是

1、不能用子类的静态方法隐藏 父类中同样标示(也就是返回值 名字 参数都一样)的实例方法

2、不能用子类的实例方法覆盖 父类中同样标示的静态方法

3、变量只会被隐藏 不会被覆盖 ,无论他是实例变量还是静态变量,而且,子类的静态变量可以隐藏 父类的实例变量,子类的实例变量可以隐藏 父类的静态变量

4、最终方法(带关键字final的方法)不能被覆盖。

O(∩_∩)O哈哈~ 是不是有点儿绕口,没关系 我们看一个实例

创建两个父子类关系的类

  1. //父类
  2. class Parent
  3. {
  4. public static String kind="javastudy.extendsstudy.parent";
  5. public static int age=50;
  6. public String name="Parent";
  7. //静态方法,返回包名
  8. public static String getKind()
  9. {
  10. System.out.println("parent的getKind()方法被调用了");
  11. return kind;
  12. }
  13. //静态方法,返回年龄
  14. public static int getAge()
  15. {
  16. System.out.println("Parent的getAge()方法被调用了");
  17. return age;
  18. }
  19. //实例方法,返回姓名
  20. public String getName()
  21. {
  22. System.out.println("Parent的getName()方法被调用了");
  23. return this.name;
  24. }
  25. }
  26. //子类
  27. class Child extends Parent
  28. {
  29. public static String kind="javastudy.extendsstudy.child";
  30. public int age=25;
  31. public String name="child";
  32. //隐藏父类静态方法
  33. public static String getKind()
  34. {
  35. System.out.println("child的getkind()方法被调用了");
  36. return kind;
  37. }
  38. //获取父类包名
  39. public static String getParentKind()
  40. {
  41. return Parent.kind;
  42. }
  43. //覆盖父类实例方法
  44. public String getName()
  45. {
  46. System.out.println("child的getName()被调用了");
  47. return this.name;
  48. }
  49. //获取父类名称
  50. public String getParentName()
  51. {
  52. return super.name;
  53. }
  54. /*
  55. *错误,实例方法不能覆盖父类的静态方法
  56. public int getAge()
  57. {
  58. return this.age;
  59. }
  60. */
  61. }

然后测试下

  1. class Test
  2. {
  3. public static void main(String[] args)
  4. {
  5. Child child=new Child();
  6. System.out.printf("子类名称:%s,年龄:%d,包名:%s%n",child.name,child.age,child.kind);
  7. //输出:子类名称:child,年龄:25,包:javastudy.extendsstudy.child
  8. //把child转换成parent对象
  9. Parent parent=child;
  10. System.out.printf("转换后的名称:%s,年龄:%d,包名:%s%n",parent.name,parent.age,parent.kind);
  11. //输出:转换后的名称:Parent,年龄:50,包:javastudy.extendsstudy.parent
  12. System.out.printf("子类访问父类被隐藏的实例变量name:%s%n",child.getParentName());
  13. //输出:子类访问父类被隐藏的实例变量name:Parent
  14. System.out.printf("子类访问父类被隐藏的静态变量kind:%s",child.getParentKind());
  15. //输出:子类访问父类被隐藏的静态变量kind:javastudy.extendsstudy.parent
  16. child.getName();
  17. //输出:child的getName()被调用了
  18. //**************注意看这个方法,返回的还是子类的getName
  19. parent.getName();
  20. //输出:child的getName()被调用了
  21. child.getKind();
  22. //输出:child的getkind()方法被调用了
  23. parent.getKind();
  24. //输出:parent的getKind()方法被调用了
  25. }
  26. }

好了,看了结果后总结下吧

1.同名的实例方法被覆盖 ,同名的静态方法被隐藏 ,child类的getName实例方法覆盖 了parent的getName实例方法,chind的getKind方法隐藏 了parent类的getKind方法

2.隐藏 和覆盖 的区别在于,子类对象转换成父类对象后,能够访问父类被隐藏 的变量和方法,而不能访问父类被覆盖 的方法

3.如果需要访问父类被隐藏 的实例变量,加上super就好了,比如访问父类的name,写上super.name就好了

4.子类若要访问父类种被隐藏的类变量,则需要父类的名字加“.”来访问。比如:parent.name

本文不是教会大家重写父类变量的,而是重点说明方法和变量的隐藏和覆盖,这些个小知识点虽然在做项目的时候不怎么会用到,但是一定要记住,不然的话很多错误会感到莫名其妙,还有就是SCJP的题库里这类题大大存在,所以本人觉得这些细小的知识还是记住为好。

最新文章

  1. “div+css”下拉菜单
  2. 表连接,如何先筛选再 join
  3. putty+xming远程登录Ubuntu16.04图形界面
  4. 用openGL实现用黑白相间的棋盘图案填充多边形
  5. ServiceStack.OrmLite 调用存储过程
  6. Python/Ruby/Go/Node 之四国大战
  7. Linux 进程编程
  8. uboot总结:uboot配置和启动过程3(config.mk分析)
  9. bit和sbit的区别
  10. 基于visual Studio2013解决面试题之0701寻找丑数
  11. 实现android里面WebView显示内容
  12. 微信小程序 + nodeJs(loopback) 实现支付
  13. TortoiseSVN客户端的使用说明
  14. 剑指offer 06:旋转数组的最小数字
  15. Judy Beta Postmortem
  16. [PA2014]Muzeum
  17. 定时任务 Wpf.Quartz.Demo.5 (升级版)
  18. ethereum/EIPs-1077 Executable Signed Messages
  19. Linux VMware tools安装步骤
  20. rar压缩类

热门文章

  1. sudo环境变量问题;程序库函数寻找
  2. Java回顾之网络通信
  3. hdu2149巴什博弈输出
  4. HDU 5816 状压DP&排列组合
  5. MyBatise代码自动生成时候Oralce的number类型BigDecimal问题
  6. Hibernate主键生成器
  7. 转载 ORACLE中实现表变量的方法
  8. icon fonts入门
  9. L202
  10. L172 K-kilogram