您的位置:首页 > 编程语言 > Java开发

Java中隐藏与覆盖(重写)的区别

2019-03-26 16:55 746 查看

隐藏与覆盖的前提条件是存在继承,当一个类继承了另一个类时就有可能会出现隐藏和覆盖的情况。

类有属性和方法,其中又分为静态属性/方法和实例属性/方法。

隐藏:针对属性(静态和实例)和静态方法,当子类中存在和父类同名的属性或者静态方法时,父类的属性或静态方法被子类的属性或静态方法隐藏。

覆盖:针对实例方法,当子类中存在和父类相同的实例方法(方法名和参数类型相同,返回值和异常比父类小(返回子类类型)或者相同,访问修饰符比父类宽松或者相同),父类的实例方法就会被子类重写的实例方法覆盖。

一:属性隐藏

1.直接访问属性

假设存在父类A和子类B,B继承自A,A类中定义了一个属性i=1,B类中定义了一个属性i=2。此时B类中存在两个属性i,一个是从A类继承的i=1,另一个是自己定义的i=2。

创建一个B类引用变量去引用一个B类实例对象,并访问该对象的属性i:

[code]B b = new B();
system.out.print(b.i);

打印的i的值为2,因为此时引用变量b的声明类型是B类型,从A类继承的属性i=1被隐藏了。

创建一个A类引用变量去引用一个B类实例对象,并访问该对象的属性i:

[code]A a = new B();
system.out.print(a.i);

打印的值为1,因为此时引用变量a的声明类型是A类型,访问的属性i是从父类中继承的i=1。

总结:直接访问对象的属性时,该属性的值取决于对象的声明类型。

2.调用方法访问属性

假设父类A类中存在一个成员方法value(),该方法打印属性i的值。

(1)当子类没有重写该方法时,代码如下:

[code]A a = new B();
a.value();//输出值为1

B b = new B();
b.value();//输出值为1

代码中打印的值都为1,因为此时对象a和b调用的value()方法都是从父类A中继承的方法,所以打印的属性i是从A类中继承的属性i=1。

(2)当子类重写了该方法时,代码如下:

[code]A a = new B();
a.value();//输出值为2

B b = new B();
b.value();//输出值为2

代码中打印的值都为2,因为此时对象a和b调用的value()方法是子类B中重写的方法(重写的方法比继承的方法优先级高),该方法属于B类,所以打印的属性i是B类中定义的属性i=2。

总结:当通过调用方法来访问属性时,如果调用的是从父类继承的方法,访问的是从父类继承的属性;如果调用的是子类的方法,访问的是子类的属性。

二:静态方法隐藏

静态方法与直接访问属性一样,访问的静态方法由调用该静态方法的对象的声明类型决定。当调用静态方法的对象声明类型是父类时,该静态方法属于从父类继承的;当调用静态方法的对象声明类型时子类时,该静态方法属于在子类中新定义的。代码如下:

[code]A a = new B();
a.staticMethod();//调用的是从父类继承的静态方法。

B b = new B();
b.staticMethod();//调用的是子类中定义的静态方法。

三:实例方法覆盖

在子类中重写了父类的实例方法时,父类的实例方法就被覆盖了,子类的实例方法优先级比父类的实例方法高。 子类对象调用该实例方法时优先调用重写的实例方法。代码如下:

[code]A a = new B();
a.instanceMethod();//调用的是子类中重写的实例方法。

B b = new B();
b.instanceMethod();//调用的是子类中重写的实例方法。

注:如果要访问被隐藏的父类属性或方法时,可以通过super.变量名和super.方法名访问,super一个是指向父类对象的指针。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: