• [ Java学习 ] 一道Java好题的详细题解 001


      之所以贴出这道题,是因为觉得真的好,真的值得整理总结,因为它覆盖了Java的许多语法知识点,可以说,只要有一点没有透彻弄懂,这题就很难做到全对

      有这样的血泪教训,是因为,我在还没完全彻彻底底明白所有语法点之前,我凭着感觉做时,做了3次,都和答案不一样。于是决定好好把知识点理一理,帮助自己日后复习,也希望给初学者一些帮助~

    -------------------------------其他相关文章------------------------------

     [Java学习 ] 类的其他文章汇总(都是超链接,可直接点击):

    [ Java学习 ] 实验 银行业务模拟

    [ Java学习 ] 破除思维定势之 C++ 和 Java 的差异 001

    [ Java学习 ] 破除思维定势之 C++ 和 Java 的差异 002

    [ Java学习 ] 破除思维定势之 C++ 和 Java 的差异 003

    [ Java学习 ] 包语句 package等语句的汇总整理

    [ Java学习 ] Java变量以及内存分配(非常重要)

    [ Java学习 ] 其他知识总结(重要)

    [ Java学习 ] “goto语句“ 和 “continue + 标号” 的不同待遇

    [ Java学习 ] toString方法 和 equals方法

    [ Java学习 ] 查阅资料整理 001

    [ Java学习 ] 查阅资料整理 002

    -------------------------------言归正传,进入本文的内容-------------------------------

    先上题目,题目是一段Java代码,要求我们写出它的输出

    (先别急着在eclipse上跑程序,先自己把答案写答案出来

    因为…如果你对知识点不是特别烂熟于心,你自己第一次做的答案,很可能会错很多,就像我一样)


    //题目是一段Java代码,要求我们写出它的输出结果
    class A
    {
    	int a = 10;
    	static int b = 20;
    	A()
    	{
    		
    	}
    	void f1()
    	{
    		System.out.println("A.a=" + a++);
    	}
    	static void f2()
    	{
    		System.out.println("A.b=" + b++);
    	}
    }
    
    
    public class test extends A
    {
    	int a = 100;
    	static int b = 200;
    	void f1()
    	{
    		System.out.println("test.a=" + a++);
    	}
    	static void f2()
    	{
    		System.out.println("test.b=" + b++);
    	}
    	public static void main(String args[])
    	{
    		A t= new test();
    		t.f1();
    		t.f2();
    		System.out.println("a=" + t.a);
    		System.out.println("b=" + t.b);
    		test s = new test();
    		System.out.println("a=" + s.a);
    		System.out.println("b=" + s.b);
    	}
    }



    //我们先把最后三句代码屏蔽掉,先只看上转型变量的部分,待会再来单独分析最后三句的输出
    //我的这个程序可以在eclipse上跑一下,因为我加了很多注释,来说明每步的结果,为什么会是那样
    package test;
    
    class A
    {
    	int a = 10;
    	static int b = 20;
    	A()
    	{
    		System.out.println("a=" + a + ", b=" + b);
    		System.out.println("加上这句,可以很清楚地看出,初始化了A类以后,才调用A的构造函数");
    		System.out.println("略微提一下,初始化的意思是,调用 int a = 10; 和 static int b = 20; 这两句代码");
    	}
    	void f1()
    	{
    		System.out.println("A.a=" + a++);
    	}
    	static void f2()
    	{
    		System.out.println("A.b=" + b++);
    		System.out.println("上句代码的输出,体现的知识点是:");
    		System.out.println("如果子类重写了父类静态方法,那么子类对象的上转型对象,不能调用子类的静态方法,只能调用父类的静态方法。");
    	}
    	void printABNow()
    	{
    		System.out.println("a=" + a + ", b=" + b);
    	}
    }
    
    
    public class test extends A
    {
    	int a = 100;
    	static int b = 200;
    	test()
    	{
    		System.out.println("a=" + a + ", b=" + b);
    		System.out.println("加上这句,可以很清楚地看出,初始化了test类以后,才调用test的构造函数");
    		System.out.println("并且我们还发现,a和b的值都和之前不一样了");
    		
    		System.out.println();
    		System.out.println("这时你可能会猜测说,是不是a和b的值被覆盖了,但其实没有覆盖,只是父类中的a和b,被子类中的a和b隐藏了而已。");
    		System.out.println("并且,父类中的a和b,仍然还可以通过,调用从父类继承的方法,操作隐藏的成员变量,我们可以来做个测试");
    		printABNow();
    		System.out.println("这个测试告诉我们,其实 100 和 200,分别只是test类的a和b,而 A类中的a和b,还是仍然保留着,并且能通过A调用A类的函数来观察");
    		System.out.println();
    		
    	}
    	void f1()
    	{
    		System.out.println("test.a=" + a++);
    		System.out.println("上句代码的输出,体现的知识点是:");
    		System.out.println("如果子类重写了父类的某个实例方法后,当对象的上转型调用这个实例方法时,一定是调用了子类重写的实例方法。");
    	}
    	static void f2()
    	{
    		System.out.println("test.b=" + b++);
    	}
    	public static void main(String args[])
    	{
    		A t= new test();
    		t.f1();
    		t.f2();
    		System.out.println("a=" + t.a);
    		System.out.println("b=" + t.b);
    		System.out.println("上两句不是调用方法,而是输出类中的值,它体现的知识点是:");
    		System.out.println("可以通过上转型变量访问父类中被子类隐藏的成员变量。");
    		System.out.println("这是因为上转型变量通过父类模板去寻找相应的成员变量,找到的正是父类中被子类隐藏的成员变量。");
    		System.out.println("不过需要注意一下的是,之前调用函数时,是有后++自增符号的,所以值发生了小变化");
    //		test s = new test();
    //		System.out.println("a=" + s.a);
    //		System.out.println("b=" + s.b);
    	}
    }
    
    //在eclipse上跑完得到的结果是:
    a=10, b=20
    加上这句,可以很清楚地看出,初始化了A类以后,才调用A的构造函数
    略微提一下,初始化的意思是,调用 int a = 10; 和 static int b = 20; 这两句代码
    a=100, b=200
    加上这句,可以很清楚地看出,初始化了test类以后,才调用test的构造函数
    并且我们还发现,a和b的值都和之前不一样了
    
    这时你可能会猜测说,是不是a和b的值被覆盖了,但其实没有覆盖,只是父类中的a和b,被子类中的a和b隐藏了而已。
    并且,父类中的a和b,仍然还可以通过,调用从父类继承的方法,操作隐藏的成员变量,我们可以来做个测试
    a=10, b=20
    这个测试告诉我们,其实 100 和 200,分别只是test类的a和b,而 A类中的a和b,还是仍然保留着,并且能通过A调用A类的函数来观察
    
    test.a=100
    上句代码的输出,体现的知识点是:
    如果子类重写了父类的某个实例方法后,当对象的上转型调用这个实例方法时,一定是调用了子类重写的实例方法。
    A.b=20
    上句代码的输出,体现的知识点是:
    如果子类重写了父类静态方法,那么子类对象的上转型对象,不能调用子类的静态方法,只能调用父类的静态方法。
    a=10
    b=21
    上两句不是调用方法,而是输出类中的值,它体现的知识点是:
    可以通过上转型变量访问父类中被子类隐藏的成员变量。
    这是因为上转型变量通过父类模板去寻找相应的成员变量,找到的正是父类中被子类隐藏的成员变量。
    不过需要注意一下的是,之前调用函数时,是有后++自增符号的,所以值发生了小变化


    //再来分析刚刚屏蔽掉的最后3句代码
    package test;
    class A
    {
    	int a = 10;
    	static int b = 20;
    	A()
    	{
    		
    	}
    	void f1()
    	{
    		System.out.println("A.a=" + a++);
    	}
    	static void f2()
    	{
    		System.out.println("A.b=" + b++);
    	}
    }
    
    
    public class test extends A
    {
    	int a = 100;
    	static int b = 200;
    	void f1()
    	{
    		System.out.println("test.a=" + a++);
    	}
    	static void f2()
    	{
    		System.out.println("test.b=" + b++);
    	}
    	public static void main(String args[])
    	{
    //		A t= new test();
    //		t.f1();
    //		t.f2();
    //		System.out.println("a=" + t.a);
    //		System.out.println("b=" + t.b);
    		test s = new test();
    		System.out.println("a=" + s.a);
    		System.out.println("b=" + s.b);
    		System.out.println("上面两句代码的输出,体现的知识点是:");
    		System.out.println("在Java中,子类也可以隐藏由父类继承来的成员变量,只要子类中声明的成员变量和父类的成员变量同名,就可以将其隐藏。 ");
    	}
    }

    //在eclipse上跑完得到的结果是:
    a=100
    b=200
    上面两句代码的输出,体现的知识点是:
    在Java中,子类也可以隐藏由父类继承来的成员变量,只要子类中声明的成员变量和父类的成员变量同名,就可以将其隐藏。 


    最后,再把我查阅过的资料一并附上:(都是超链接,可直接点击):

    Java子类继承(二):隐藏成员变量和方法重写的理解

    Java子类继承(二):隐藏成员变量和方法重写的理解

    最后的最后,我想附带说一下的就是,这题主要是难在上转型变量的部分,因为语法规则比较多,稍不注意就很可能弄错,至于普通的继承,其实和C++大同小异。

    所以,我个人的感觉是,学习Java的继承时,有必要把上转型变量的语法透彻清楚地弄得明明白白,因为…

    上转型变量真的是稍不注意就能踩肯多坑的知识点啊

    ^(* ̄(oo) ̄)^










  • 相关阅读:
    spring 解析bean
    Spring Cloud
    Spring
    JDK动态代理源码实现深入分析
    一个很坑的问题,button 的onclick方法失效了
    web总结
    字符串编码
    海量数据的解决方案--笔记
    链接保存
    读《JVM虚拟机》- 集中简单的垃圾收集算法
  • 原文地址:https://www.cnblogs.com/mofushaohua/p/7789360.html
Copyright © 2020-2023  润新知