JAVA中方法和变量在继承中的覆盖和隐藏
关键字: java继承 方法覆盖 方法隐藏
?????? 我们知道,在JAVA中,子类可以继承父类,如果子类声明的方法与父类有重名的情况怎么办,大伙儿都知道要是重写,但是实际上这又分为两种 情况,就是方法和变量在继承时的覆盖和隐藏问题,这些概念性的东西看似无聊,但是在面试或者是SCJP认证题中围绕这些是会经常碰到的,所以这里来讨论下
?
首先我们来看几个概念
?????? 隐藏?:child隐藏了parent的变量和方法,那么,child不能访问parent被隐藏的变量或者方法,但是,讲B转换成A中,可以访问A被隐藏的变量或者方法
??????? 覆盖?:child覆盖了parent的变量或者方法,那么,child不能访问parent被覆盖的变量或者方法,将child转换成parent后同样不能访问parent被覆盖的变量或者方法
?
首先看一下JAVA中方法和变量在继承时的覆盖和隐藏规则
?????? 1.父类的实例变量和静态变量能被子类的同名变量隐藏
?????? 2.父类的静态方法被子类的同名静态方法隐藏
?????? 3.父类的实例方法被子类的同名实例变量覆盖
?
还有几点需要注意的是
?????? 1.不能用子类的静态方法隐藏?父类中同样标示(也就是返回值 名字 参数都一样)的实例方法
?????? 2.不能用子类的实例方法覆盖?父类中同样标示的静态方法
?????? 3.这点儿请注意,就是变量只会被隐藏?不会被覆盖?,无论他是实例变量还是静态变量,而且,子类的静态变量可以隐藏?父类的实例变量,子类的实例变量可以隐藏?父类的静态变量
?
Java代码??
- //父类??
- class?Parent??
- {??
- ????public?static?String?kind="javastudy.extendsstudy.parent";??
- ????public?static?int?age=50;??
- ????public?String?name="Parent";??
- ??
- ????//静态方法,返回包名??
- ????public?static?String?getKind()??
- ????{??
- ????????System.out.println("parent的getKind()方法被调用了");??
- ????????return?kind;??
- ????}??
- ????//静态方法,返回年龄??
- ????public?static?int?getAge()??
- ????{??
- ????????System.out.println("Parent的getAge()方法被调用了");??
- ????????return?age;??
- ????}??
- ??
- ????//实例方法,返回姓名??
- ????public?String?getName()??
- ????{??
- ????????System.out.println("Parent的getName()方法被调用了");??
- ????????return?this.name;??
- ????}??
- }??
- //子类??
- class?Child?extends?Parent??
- {??
- ????public?static?String?kind="javastudy.extendsstudy.child";??
- ????public?int?age=25;??
- ????public?String?name="child";??
- ??
- ????//隐藏父类静态方法??
- ????public?static?String?getKind()??
- ????{??
- ????????System.out.println("child的getkind()方法被调用了");??
- ????????return?kind;??
- ????}??
- ??????
- ????//获取父类包名??
- ????public?static?String?getParentKind()??
- ????{??
- ????????return?Parent.kind;??
- ????}??
- ??????
- ????//覆盖父类实例方法??
- ????public?String?getName()??
- ????{??
- ????????System.out.println("child的getName()被调用了");??
- ????????return?this.name;??
- ????}??
- ??????
- ????//获取父类名称??
- ????public?String?getParentName()??
- ????{??
- ????????return?super.name;??
- ????}??
- ????/*?
- ?????*错误,实例方法不能覆盖父类的静态方法?
- ????public?int?getAge()?
- ????{?
- ????????return?this.age;?
- ????}?
- ????*/??
- }??
- ??
- ??
- class?Test???
- {??
- ????public?static?void?main(String[]?args)???
- ????{??
- ????????Child?child=new?Child();??
- ????????System.out.printf("子类名称:%s,年龄:%d,包名:%s%n",child.name,child.age,child.kind);??
- ????????//输出:子类名称:child,年龄:25,包:javastudy.extendsstudy.child??
- ??
- ????????//把child转换成parent对象??
- ????????Parent?parent=child;??
- ??
- ????????System.out.printf("转换后的名称:%s,年龄:%d,包名:%s%n",parent.name,parent.age,parent.kind);??
- ????????//输出:转换后的名称:Parent,年龄:50,包:javastudy.extendsstudy.parent??
- ??
- ????????System.out.printf("子类访问父类被隐藏的实例变量name:%s%n",child.getParentName());??
- ????????//输出:子类访问父类被隐藏的实例变量name:Parent??
- ??????????
- ????????System.out.printf("子类访问父类被隐藏的静态变量kind:%s",child.getParentKind());??
- ????????//输出:子类访问父类被隐藏的静态变量kind:javastudy.extendsstudy.parent??
- ??
- ????????child.getName();??
- ????????//输出:child的getName()被调用了??
- ??
- ????????//**************注意看这个方法,返回的还是子类的getName??
- ????????parent.getName();??
- ????????//输出:child的getName()被调用了??
- ??
- ????????child.getKind();??
- ????????//输出:child的getkind()方法被调用了??
- ??
- ????????parent.getKind();??
- ????????//输出:parent的getKind()方法被调用了??
- ????}??
- }??
?好了,看了结果后总结下吧
?????? 1.同名的实例方法被覆盖?,同名的静态方法被隐藏?,child类的getName实例方法覆盖?了parent的getName实例方法,chind的getKind方法隐藏?了parent类的getKind方法
?????? 2.隐藏?和覆盖?的区别在于,子类对象转换成父类对象后,能够访问父类被隐藏?的变量和方法,而不能访问父类被覆盖?的方法
?????? 3.如果需要访问父类被隐藏?的实例变量,加上super就好了,比如访问父类的name,写上super.name就好了