面向对象编程中,某一个实例方法使用实例变量和调用其它实例方法的情况是常见的。当存在继承关系时,这种情况就变得复杂起来。以下就对继承关系中,父类的某实例方法使用实例变量和其它实例方法的情况进行探究。因为我也是初学者,有理解不到位的地方,还请路过的朋友多多指教。

(1)父类实例方法使用实例变量

public或protected修饰的实例变量。

因为在继承关系中,public和protected修饰的实例变量对于子类的效果是相同的,所以在此合并讨论。

public class Test {

public static void main(String[] args) {

System.out.println(new Parent().getName());

System.out.println(new Child().getName());

}

}

class Parent {

public String name = "base";

public String getName() {

return name;

}

}

class Child extends Parent {

public String name = "child";

}

输出结果:

base

base

由此可见,父类的方法如果使用了父类的实例变量,即使在子类中重新定义了一个和该变量名称相同的实例变量,父类的方法在通过子类调用的时候,依然使用的是父类的变量。

了解这一点后,我们可以做一个有趣的实验。下面这段代码会输出什么内容?

public class Test {

public static void main(String[] args) {

Child c = new Child();

c.name = "Child";

System.out.println(c.name);         //(1)这里输出的是子类的name

System.out.println(c.getName());    //(2)这里输出的时父类的name

}

}

class Parent {

public String name = "base";

public String getName() {

return name;

}

}

class Child extends Parent {

}

(1)处的代码输出的name,是通过子类引用找到的name,而(2)出代码调用的是继承自父类的getName()方法,根据之前测试的结果,该方法访问的肯定是父类的name。这里问题的关键在于,子类引用找到的name和父类的name是不是同一个name呢?运行的结果显示:是同一个!

输出结果

Child

Child

有这里可以看出,子类继承父类后,子类自身并未多出一个name来,其使用的name仍然是父类的name。也就是说,在内存结构中,子类继承自父类的实例变量,仍然是父类的实例变量,只是对于子类而言是可见的并且表现为子类自身实例变量。

从上述例子还可以看到,子类在声明一个同名成员变量后,子类使用的便是自身的成员变量了。其实此时父类的同名成员变量对子类仍然可见,并且子类可以通过super.变量名来使用该父类的成员变量。

private修饰的成员变量。

其实这时已经不用进一步讨论了,根据上边的结论,父类方法不会访问子类的public/protected员变量,那么肯定不会也不会访问到private修饰的成员变量。

综上所述,子类继承自父类的实例方法可以访问的实例变量是父类的实例变量,对于子类自身的实例变量是不能访问的!如果在继承的时候,子类定义了一个和继承自父类的实例变量名称相同的实例变量,则会导致子类不能直接访问父类,进而导致子类方法和父类方法对同名实例变量的操作不一致。所以,不建议子类定义和继承自父类实例变量名称相同的实例变量!

(2)父类实例方法调用实例方法

同样地,分public/protected和private两种情况进行讨论。

public/protected修饰的实例方法。

测试的方法很简单,只需要在对上面的例子稍微改动一下即可。

public class Test {

public static void main(String[] args) {

new Parent().print();

new Child().print();

}

}

class Parent {

private String name = "base";

public String getName() {

return name;

}

public void print() {

System.out.println(getName());

}

}

class Child extends Parent {

private String name = "child";

public String getName() {

return name;

}

}

输出结果:

base

child

很明显,子类的getName()覆写了父类的getName(),最终导致两个getName()访问的变量不一致。这里值得注意的是,父类实例方法调用另一个(子类可见的)实例方法,并且后者被子类重写时,是存在多态的。而且可进一步验证,即使print()方法的修饰符改为private,多态依然存在。

private修饰的实例方法

当方法有private修饰时,多态就不存在了。代码如下

public class Test {

public static void main(String[] args) {

new Parent().print();

new Child().print();

}

}

class Parent {

private String name = "base";

private String getName() {

return name;

}

public void print() {

System.out.println(getName());

}

}

class Child extends Parent {

private String name = "child";

private String getName() {

return name;

}

}

输出结果

base

base

这也是可以理解的,因为此时不存在方法的重写,所以也不存在多态。

总结一下:

父类方法访问实例变量只能是父类的实例变量,子类继承父类时。从内存结构上考虑,可以认为子类实例所占据的内存结构中内部有一份完整的父类实例内存结构。父类实例中public/protected修饰的实例变量对于子类实例而言是可见的,并且可以如同访问自身实例变量一样去访问,当然前提是子类自身实例变量中没有父类可见实例变量重名的。另一方面,父类实例中private修饰的实例变量对于子类而言不可见‍‍。‍‍‍

而当父类方法调用实例方法时,是可能存在多态的。具体说来,如果父类实例方法调用的实例方法被子类重写,当通过子类引用调用前者时,前者所调用的实例方法将采用被子类重写后的那个。然而,如果子类方法和父类方法并无重写关系(private修饰),那么这种多态效应将不存在,通过子类调用前者时,前者依然使用父类的方法。

java 实例方法直接调用超类的实例方法_Java继承关系中,父类方法使用实例变量和调用实例方法的探究...相关推荐

  1. 浅析继承关系中的方法调用

    我们首先来看一段代码: 1 class Program 2 { 3 static void Main(string[] args) 4 { 5 Father father=new Son(); 6 f ...

  2. Java继承关系中,父类不可以强制转换成子类

    总结: 父类不可以强转为子类 父类中只存放共性抽象类方法,子类可以存放特性方法,所以子类 首先构建好两个类 构建继承类方法-点击查看 在Main中强制将父类转换为子类 Student a = (Stu ...

  3. java继承关系中,父类private修饰的内容真的不能被继承吗?NO

    前情引入 关于java的继承,初学的时候,一直认为父类中private修饰的东西时无法被子类继承.后来随着学习的深入,见得多了一些,看到一些文章博客的另一种观点:其实父类中的东西,除了构造方法之外,其 ...

  4. Java中父类方法重写有哪些需要注意的?

    在继承关系中,子类会自动继承父类中公共的方法,但有时在子类中需要对继承的方法进行一些修改,即对父类的方法进行重写.需要注意的是,子类中重写的方法需要和父类被重写的方法具有相同的方法名.参数列表以及返回 ...

  5. java 中静态变量(类变量)与实例变量 静态方法与实例方法

    静态变量: 在类内部中,方法的外部声明的对象而且加上static; 实例变量: 在类内部中,声明不需要加static; 比如: 1 public class Demo{ 2 3 int i1=0; 4 ...

  6. Java的多态形式中,如何访问成员变量和调用成员方法

    父类的引用指向子类的对象: Fu obj = new Zi(); int num = obj.num; obj.show(); obj.methodZi(); 1.如果父类和子类都有成员变量 num, ...

  7. java 注解 方法 参数_java在注解中绑定方法参数的解决方案

    我们有这样子的需求,需要记录用户操作某个方法的信息并记录到日志里面,例如,用户在保存和更新任务的时候,我们需要记录下用户的ip,具体是保存还是更新,调用的是哪个方法,保存和更新的任务名称以及操作是否成 ...

  8. java 方法参数绑定_java在注解中绑定方法参数的解决方案

    我们有这样子的需求,需要记录用户操作某个方法的信息并记录到日志里面,例如,用户在保存和更新任务的时候,我们需要记录下用户的ip,具体是保存还是更新,调用的是哪个方法,保存和更新的任务名称以及操作是否成 ...

  9. plsa的java实现_java在注解中绑定方法参数的解决方案

    我们有这样子的需求,需要记录用户操作某个方法的信息并记录到日志里面,例如,用户在保存和更新任务的时候,我们需要记录下用户的ip,具体是保存还是更新,调用的是哪个方法,保存和更新的任务名称以及操作是否成 ...

最新文章

  1. [Usaco2009 Open]工作安排Job
  2. 我的世界java版怎么加整合包_我的世界1.9MOD简单整合下载 功能性懒人包
  3. android sqlite 怎么写入存储时间
  4. New Companies(关联查询+group by)
  5. 超详细!使用OpenCV深度学习模块在图像分类下的应用实践
  6. 修改windows远程登录端口
  7. module.exports和exports得区别
  8. “朝三暮四”与“BPO”
  9. PLC控制三相异步电动机正反转系列实训QY-DG800E
  10. 游戏开发中的物理之软体
  11. 统计学习方法总结、应用对比
  12. android获取版本信息、屏幕信息和设备编号
  13. 苹果8参数_苹果12pro max 128G新起点预售价9099元-苹果 iPhone 12 Pro Max_西安手机行情...
  14. 阿里云的这群疯子--深度好文成功绝非偶然
  15. 解决高分辨率下安装Linux花屏问题
  16. Python学习心得(一):词频统计,自顶向下设计
  17. 《python密码学编程》笔记
  18. H3C交换机、路由器常用配置命令大全
  19. 4. 选股(基金)神器 —— 证券基本分析
  20. navicat导出sql数据,保留datetime三位小数

热门文章

  1. SaveFileDialog的用法
  2. 主板上各种英文名称含义(待更新)
  3. “三白汤”让你又白又嫩(图)
  4. mysql通配符escape使用_详解MySQL like如何查询包含'%'的字段(ESCAPE用法)
  5. 基于MATLAB的药物扩散仿真系统设计与实现 文档+上机实验报告+项目源码+运行说明
  6. 杭州出台政策最高奖5000万支持软件产业,鼓励自主软件推广应用,培育开源生态等
  7. 『51CTO七周年庆典活动』社区总动员,一“七”同行
  8. 在kernel2.4.18下的s3c2410 AD驱动
  9. nginx 灰度发布
  10. 如何通过第三方工具维护计算机,无需第三方优化软件利用电脑自身维护功能优化系统...