java继承成员访问特点_Java 继承后访问成员的特点

Java 继承后访问成员的特点

继承后的特点 -- 成员变量

对象访问成员变量时, 会先在子类中查找有没有定义对应的变量, 若子类中存在就会就近使用子类中的变量, 若子类中没有定义就会沿着继承关系往上找有没有定义相应的变量, 若父类中也没有则编译不通过. 代码示例:classFu{

// Fu 类中的成员变量.

intnum=5;

intnum2=7;

}

classZiextendsFu{

// Zi 类中的成员变量

intnum=6;

publicvoidshow(){

// 访问父类中的 num2

System.out.println("num2="+num2);

// 访问子类中的 num

System.out.println("num="+num);

}

}

publicclassExtendsDemo0{

publicstaticvoidmain(String[]args){

// 创建子类对象

Ziz=newZi();

// 调用子类中的 show 方法

z.show();

}

}

演示结果:

num2=7

num=6

子父类中出现了同名的成员变量时, 在子类中访问父类中非私有成员变量, 需要使用 super 关键字, 用法类似于 this .

使用格式:

super. 父类成员变量名

代码如下:classZiextendsFu{

// Zi 类中的成员变量

intnum=6;

publicvoidshow(){

// 访问父类中的 num

System.out.println("Fu num2="+num2);

// 访问父类中的 num

System.out.println("Fu num="+super.num);

}

}

演示结果:Funum=7

Zinum=5

Fu 类中的私有成员变量, 子类是不能直接访问的. 编码时, 遵循封装的原则, 使用 private 修饰成员变量, 可以在父类中提供公共的 getXxx 方法和 setXxx 方法来访问.

super 和 this

父类空间优先于子类对象产生

在每次创建子类对象时, 先初始化父类空间, 再创建其子类对象本身. 目的在于子类对象中包含了其对应的父类空间, 便可以包含其父类的成员. 代码体现在子类的构造方法调用时, 一定先调用父类的构造方法. 理解图解如下:

ab7653affab982b574eb7acc55df2e04.gif

super 和 this 的含义

super : 代表父类的存储空间标识 (可以理解为父类的引用).

this : 代表当前对象的引用 (谁调用就代表谁).

super 和 this 的用法

this. 成员变量 -- 本类的

super. 成员变量 -- 父类的

this. 成员方法名 () -- 本类的

super. 成员方法名 () -- 父类的

代码示例:classAnimal{

publicvoideat(){

System.out.println("animal : eat");

}

}

classCatextendsAnimal{

publicvoideat(){

System.out.println("cat : eat");

}

publicvoideatTest(){

this.eat();// this 调用本类的方法

super.eat();// super 调用父类的方法

}

}

publicclassExtendsDemo08{

publicstaticvoidmain(String[]args){

Animala=newAnimal();

a.eat();

Catc=newCat();

c.eatTest();

}

}

输出结果为:animal:eat

cat:eat

animal:eat

注意:

通过 super 引用属性, 方法, 构造器时, 都要求该成员是可见的, 即该成员的修饰符不能是 private 的, 跨包的话还不能是缺省的.

super 的追溯不仅限于直接父类

如果某个属性或方法前面使用 "this.", 那么先从本类中查找, 如果未找到, 会沿着继承关系往上找

如果某个属性或方法前面使用 "super.", 那么先从直接父类中查找, 如果未找到, 会沿着继承关系往上找

如果某个属性或方法前面既没有 "this.", 也没有 "super.", 遵循就近原则, 先从本类中查找, 如果未找到, 会沿着继承关系往上找

继承后的特点 -- 成员方法

成员方法不重名时

如果子, 父类中的方法不重名, 这时的调用是没有影响的. 对象调用方法时, 会先在子类中查找有没有定义对应的方法, 若子类中存在就执行子类中定义的方法, 若子类中没有定义就会沿着继承关系往上找有没有定义相应的方法, 若父类中也没有则编译不通过. 代码示例:classFu{

publicvoidshow(){

System.out.println("Fu 类中的 show 方法执行");

}

}

classZiextendsFu{

publicvoidshow2(){

System.out.println("Zi 类中的 show2 方法执行");

}

}

publicclassExtendsDemo04{

publicstaticvoidmain(String[]args){

Ziz=newZi();

// 子类中没有定义 show 方法, 但是可以找从父类继承的 show 方法去执行

z.show();

z.show2();

}

}

成员方法重名 -- 重写 (Override)

如果子, 父类中出现重名的成员方法, 这时的访问是一种特殊情况, 叫做方法重写 (Override).

方法重写 : 子类继承了父类, 可以获得父类的成员变量和成员方法; 可是当父类的某个方法不适合于子类本身的特征时, 在子类中可以根据需要对从父类中继承来的方法进行改造, 也称为方法的重写, 覆写. 在程序执行时, 子类的方法将覆盖父类的方法.

代码如下:classFu{

publicvoidshow(){

System.out.println("Fu show");

}

}

classZiextendsFu{

// 子类重写了父类的 show 方法

publicvoidshow(){

System.out.println("Zi show");

}

}

publicclassExtendsDemo05{

publicstaticvoidmain(String[]args){

Ziz=newZi();

// 子类中有 show 方法, 只执行重写后的 show 方法

z.show();// Zi show

}

}

重写的应用

子类可以根据需要, 定义特定于自己的行为. 既沿袭了父类的功能名称, 又根据子类的需要重新实现父类方法, 从而进行扩展增强. 比如新的手机增加来电显示头像的功能, 代码如下:classPhone{

publicvoidsendMessage(){

System.out.println("发短信");

}

publicvoidcall(){

System.out.println("打电话");

}

publicvoidshowNum(){

System.out.println("来电显示号码");

}

}

// 智能手机类

classNewPhoneextendsPhone{

// 重写父类的来电显示号码功能, 并增加自己的显示姓名和图片功能

publicvoidshowNum(){

// 调用父类已经存在的功能使用 super

super.showNum();

// 增加自己特有显示姓名和图片功能

System.out.println("显示来电姓名");

System.out.println("显示头像");

}

}

publicclassExtendsDemo06{

publicstaticvoidmain(String[]args){

// 创建子类对象

NewPhonenp=newNewPhone();

// 调用父类继承而来的方法

np.call();

// 调用子类重写的方法

np.showNum();

}

}

重写时, 用到 super. 父类成员方法, 表示调用父类的成员方法.

方法重写注意事项

方法名: 必须完全一致

形参列表: 必须完全一致

返回值类型:

如果是基本数据类型和 void, 必须一致

如果是引用数据类型, 重写的方法的返回值类型 <= 被重写方法的返回值类型, Student

修饰符: 重写的方法的修饰符范围 >= 被重写方法的修饰符范围 (public> protected> 缺省 > private)

被重写方法不能被 private,static,final 修饰, 如果跨包的话, 修饰符缺省的也不能被重写, 因为缺省的跨包不可见

继承后的特点 -- 构造方法

首先我们要回忆两个事情, 构造方法的定义格式和作用:

构造方法的名字是与类名一致的. 所以子类是无法继承父类构造方法的.

构造方法的作用是初始化成员变量的. 所以子类的初始化过程中, 必须先执行父类的初始化动作.

子类不会继承父类的构造器, 但是一定会调用父类的构造器

默认情况下, 调用的是父类的无参构造, super() 写或不写都会调用父类的无参构造, 如果要写, 必须在子类构造器首行

如果父类没有无参构造, 必须在子类的构造器首行使用 super(实参列表) 显式调用父类的有参构造, 否则编译报错

super([形参列表]) 和 this([形参列表]) 都必须是在构造方法的第一行, 所以不能同时出现.

代码示例:classFather{

publicFather(){

System.out.println("父类的无参构造");

}

}

classSonextendsFather{

privateStringstr;

privateintnum;

publicSon(){

// 隐含调用了 super(); 子类的构造器中一定会调用父类的构造器, 默认调用父类的无参构造

System.out.println("子类的无参构造");

}

publicSon(Stringstr){

// 隐含调用了 super()

this.str=str;

System.out.println("子类的有参构造 1");

}

publicSon(Stringstr,intnum){

// 调用重载的构造器, 隐含调用了 super()

this(str);

this.num=num;

System.out.println("子类的有参构造 2");

}

}

publicclassConstructorTest{

publicstaticvoidmain(String[]args){

Sons1=newSon();

/*

父类的无参构造

子类的无参构造

*/

//Son s2 = new Son("java");

/*

父类的无参构造

子类的有参构造 1

*/

Sons3=newSon("java",10);

/*

父类的无参构造

子类的有参构造 1

子类的有参构造 2

*/

}

}

来源: http://www.bubuko.com/infodetail-3658642.html


版权声明:本文为weixin_29176179原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。