随笔53 java存在继承关系的类之间的调用

 1 /**
 2  * Created by zmt on 2016/12/22.
 3  */
 4 public class Test {
 5     public static void main(String [] args){
 6         System.out.println(new B().getValue());
 7     }
 8     static class A{
 9         protected int value;
10         public A(int v) {
11             setValue(v);
12         }
13         public void setValue(int value){
14             this.value = value;
15         }
16         public int getValue(){
17             try{
18                 value++;
19                 return value;
20             } catch(Exception e){
21                 System.out.println(e.toString());
22             } finally {
23                 this.setValue(value);
24                 System.out.println(value);
25             }
26             return value;
27         }
28     }
29     static class B extends A{
30         public B() {
31             super(5);
32             setValue(getValue() - 3);
33         }
34         public void setValue(int value){
35             super.setValue(2 * value);
36         }
37     }
38 }

调试看下执行过程。

首先是main方法,new了一个B对象,然后就是调用该对象的getValue()方法,这个没什么好说的。

接下来就要执行B类的构造方法了,这个也没啥说的

然后执行B的构造方法,super(5);也就是调用B的父类A的构造方法,应该是到A构造的setValue()方法,同时A的成员变量value的值被赋为5,通过调试可以清楚的看到。

接下来就是执行setValue()方法了,但是此时A类和B类都有一个setValue()方法,到底执行哪一个呢,我一开始认为是A类的setValue()方法,但是结果并不是这样的,看下调试过程。

执行的是B的setValue()方法,,,因为现在正在执行B类的构造方法,所以默认先会调用B类中的方法,如果B类中没有,才会调用其父类A中的方法。我们继续看,,,接下来到super.setValue(2 * value),即执行A类的setValue()方法,这时,A类的成员变量value应该就变成了10


继续往下看,这时B类的构造方法中的super(5)就执行完了,然后就到了setValue(getValue() - 3)方法

接着执行getValue()方法,首先在B类中找,但B类没有getValue()方法,所以就执行A类中的getValue()方法,A类中肯定是有的,要不然编译就不会通过

然后就开始执行try、catch、finally这一块,给A的成员变量value自增,从之前的10变为11,然后直接返回value,没有捕获异常,继续到finally里面的this.setValue(value)

然后这个this指的到底是A类还是B类呢,答案是B类,因为现在是在执行B的构造方法,所以this指的应该是B类,即调用B类的setValue(int value)方法

然后又super.setValue(2 * value);执行父类A的setValue(int value),把2 * 11作为参数传递,A类的setValue(int value)把传进来的value值赋给了A的成员变量value,变成了22。

然后this.setValue(value)就执行完了,最后输出value,22

到这儿getValue()方法就执行完了,但是有一点需要注意,此时的value为22,但是getValue()的返回值确是11,因为在try{ }中已经return了,所以这个方法的返回值级已经保存下来了,是11,即使finally{ }里面又对value的值做出了改变,但是getValue()的返回值是不会变的。接着继续执行B类构造方法中的setValue(getValue() - 3);getValue()是11,所以B的setValue(int value)方法的参数就为8,接着又到了super.setValue(2 * value)

调用A类的setValue(int value)方法,同时将参数赋值给A类的成员变量value,此时value变为16

到这儿B类的构造方法就全部执行完了,也就是new B(),然后又调用了该对象 的getValue()方法,B类没有,但是父类A有,所以,

继续try{ }、catch{ }、finally{ },A类的成员变量value为16,然后value++,再返回,这时getValue()的返回值已经确定了,就是17,即使在finally中对value做出改变,其返回值不会变。然后到finally{ },又是this.setValue(value),前面已经说过了,这个this指的是B类的this,所以调用B类的setValue(int value)

接着又是super.setValue(2 * value),调用A类的setValue(),并把2 * 17作为参数传递过去。

把参数赋给A的成员变量value,这时this.setValue(value)就执行完了,此时的value为34。最后输出value。

需要注意的是,此时的getValue()方法的返回值是17,这个前面已经提到了,到这儿,整个new B().getValue()就执行完了,最后又输出了getValue的返回值,也就是17。所以整个过程执行完后的输出结果是22、34、17。。。。。。


这道题虽然绕了很多弯,但是我们做完后发现整体过程其实并不是很复杂,就是自类继承父类,调用方法时先是调用子类中的方法,如果没有就调用父类中的方法,还有一点就是try{ }、catch{ }、finally{ }返回值的问题,一旦try{ }中返回了某一个值,如果finally有返回值,finally中的返回值会覆盖try的返回值,如果finally没有返回值,就是try中的返回值。掌握了这些,这道题就显得很简单了。

时间: 2024-11-06 12:47:39

随笔53 java存在继承关系的类之间的调用的相关文章

在CMD窗口中使用javac和java命令进行编译和执行带有包名的具有继承关系的类

一.背景 最近在使用记事本编写带有包名并且有继承关系的java代码并运行时发现出现了很多错误,经过努力一一被解决,今天我们来看一下会遇见哪些问题,并给出解决办法. 二.测试过程 1.父类代码 1 package com.hafiz.zhang; 2 3 public class Fu 4 { 5 private Integer i ; 6 7 public void sayHello(String name) { 8 System.out.println("Hello " + name

Java:继承关系中的构造函数(转)

1.构造函数不会被继承到子类. 2.子类的构造函数中的第一行(除注释外)必须是父类对象(super)的构造函数. 如果没有显示指定,则有两种情况: 1)如果父类有默认构造器(不带参数的构造器才是默认构造器),则会隐式地调用它(super()),此时不会出错: 2)如果父类没有默认构造器,则会出错. class Game { Game() { System.out.println("Game default constructor"); } Game(int i) { System.ou

继承(指类之间共享属性和操作的机制)

继承(指类之间共享属性和操作的机制) 虚基类继承时要添加关键字virtual,以避免二义性. { 自己理解: 公有:基类的公有和保护成员作为派生类的公有和保护成员,在派生类类体内可以对基类进行公有和保护操作,基类私有不可访问.在main()函数内,派生类对象可以访问基类成员.虽然基类的私有成员不被派生类访问,但派生类还是包含了基类的私有数据成员. 保护:基类的公有和保护成员作为派生类的保护成员,在派生类类体内可以对基类进行保护操作,基类私有不可访问.在main()函数内,派生类对象不可访问基类任

JAVA问题总结之15-多个类之间的调用

JAVA问题总结之15-多个类之间的调用: 代码: package java3; public class test1 { public static void main(String[] args){ Pretimive t = new Pretimive(); for (int i=0;i<t.b.length;i++){ System.out.println(t.b[i]); } System.out.print("\n"); t.b[0]=true; t.b[2]=tru

java中继承关系学习小结

继承:把多个类中相同的内容提取出来,定义到一个类中,其他类只需要继承该类,就可以使用该类公开的属性和公开的方法. 继承的好处:提高代码的复用性.提高代码的可维护性.让类与类之间产生关系,是多态存在的一个前提. 继承的弊端:提高了类与类之间的耦合性. 开发的原则:低耦合,高内聚 耦合:类与类之间的关系 内聚:自己单独完成某件事情的能力. 在Java中只允许单继承.一个类如果没有显示的继承其他类,则该类的默认父类为Object类.Object类是所有类的父类. Java支持多层继承. 父类的公开方法

java中的面向对象和类之间的关系

1.面向对象 a.分析问题中需要用到哪些类以及对象 b.分析以上类中或对象中应该具有哪些属性及方法 c.分析类之间的关系 (合适的方法应该出现在合适的类中) 2.举例:模板-实物 a.白板笔 b.员工(年龄.姓名.性别.工作岗位) (显示姓名,年龄,修改姓名,修改年龄,变更工作岗位) (区分对象:一般通过方法是无法区分对象的,通过属性可以区分对象) 3.类与对象 a.类是具有共同特征的一类事物的一个抽象 b.对象是这个类具体的某一个实例 4.类(对象)之间的4种关系 a.依赖关系(Depende

C++/Java中继承关系引发的调用关系详解

C++: 这里引用到了 http://blog.csdn.net/haoel/article/details/1948051/ 中的内容,还请提前阅读陈大神的这篇博客后在阅读本篇. 覆盖,实现多态的基础,通过虚函数表来实现,下面这个例子便是覆盖 Override 1 #include<iostream> 2 3 using namespace std; 4 5 class Base{ 6 public: 7 Base(){ 8 cout << "Base::Base&qu

类与类之间调用Computer-CPU-Mouse--看懂它看懂类之间的调用

举个例子 大家会使用类并且会声明并且实现类的setter 和 getter方法 那让我们来更深入的学习,类中包含另一个类的实现方法吧. 题目: Computer类(电脑类) 该类用于描述一个具体的电脑类,可以对该类进行一些基本的操作 属性: 1. 电脑品牌 2. 鼠标 3. CPU 方法: 1.成员变量的set.get方法 2.电脑信息的详细描述 包括电脑品牌 鼠标信息,CPU信息等等 鼠标类: 鼠标品牌 类别 价格 CPU类: CPU型号 缓存 价格 解题思路:(有很多种,但大单位为程序员交流

类与类之间的调用

1:如果在同一个类中的两个方法都是非静态方法,可以直接调用. 2:若果在同一个类中一个是非静态方法,一个是静态方法.从非静态方法中调用静态方法可以,从静态方法中调用非静态方法不可 3:如果在同一个类中两个都是静态方法,也可以直接调用. 4:在Main方法中,如果想要调用(同一个类或不同类)中的方法,必须要创建类的对象才能调用此方法