一:运行 TestInherits.java 示例,观察输出,总结。

TestInherits.java

class Grandparent
{

  public Grandparent()
  {

    System.out.println("GrandParent Created.");

  }

public Grandparent(String string)
  {

    System.out.println("GrandParent Created.String:" + string);
  }

}

class Parent extends Grandparent
{

public Parent()

  {

   //super("Hello.Grandparent.");

   System.out.println("Parent Created");
  // super("Hello.Grandparent.");

  }

}

 

class Child extends Parent
{

public Child()
  {
   System.out.println("Child Created");

  }

}

 

public class TestInherits
{

  public static void main(String args[])
  {

    Child c = new Child();
  }

}

总结:

通过 super 调用基类构造方法,必须是子类构造方法中的第一个语句。否则会报错。运行结果如下:

为什么子类的构造方法在运行之前,必须调用父类的构造方法?能不能反过来?为什么不能反过来?

答:

构造一个对象,先调用其构造方法,来初始化其成员函数和成员变量。
子类拥有父类所有的变量及方法,父类没有子类的部分变量和方法。
如果不调用,则从父类继承而来的成员变量和成员方法得不到正确的初始化。
不能反过来调用也是这个原因,因为父类根本不知道子类有神魔变量而且这样一来子类也得不到初始化的父类变量,导致程序运行出错!

 二、直接输出一个不可变的类的对象,会有什么结果?

程序源码示例:

class A{}

public class ExplorationJDKSource {

  public static void main(String[] args) {
    System.out.println(new A());
  }

}

运行结果:类型名+@+随机数

原因:

main方法实际上调用的是祖类函数: public void println(Object x),这一方法内部调用了String类的valueOf方法。

valueOf方法内部又调用Object.toString方法:

hashCode()方法是本地方法,由JVM设计者实现: public native int hashCode();

所以通过层层调用结果就显示出了      类名+@+哈希值。

三、我们来看Fruit.java 代码,总结原因。

Fruit.java

public class Fruit
{
  public String toString()
  {
    return "Fruit toString.";
  }

  public static void main(String args[])
  {
    Fruit f=new Fruit();
    System.out.println("f="+f);
    // System.out.println("f="+f.toString());
  }
}

运行结果

总结:

Fruit类覆盖了Object类的toString方法。

在“+”运算中,当任何一个对象与一个String对象,连接时,会隐式地调用其toString()方法,默认情况下,此方法返回“类名 @ + hashCode”。为了返回有意义的信息,子类可以重写toString()方法。

四、

现在有三个类:

class Mammal{}

class Dog extends Mammal {}

class Cat extends Mammal{}

针对每个类定义三个变量并进行初始化

Mammal m=null ;

Dog d=new Dog();

Cat c=new Cat();

下列语句哪一个将引起编译错误?为什么?哪一个会引起运行时错误?为什么?

m=d;

d=m;

d=(Dog)m;

d=c;

c=(Cat)m;

答:程序运行结果

第二行与第四行出错。

将父类赋值给子类时需要强制转化,子类赋值给父类时不用强制转化。父类的两个子类相互赋值时也必须强制转化。

五、请看下面的“变态”类。程序运行结果是什么?你如何解释会得到这样的输出? 计算机是不会出错的,之所以得 到这样的运行结果也是有原因的, 那么从这些运行结果中,你能总 结出Java的哪些语法特性?

程序源码:

class Parent{
  public int myValue=100;
  public void printValue() {
    System.out.println("Parent.printValue(),myValue="+myValue);
  }
}
class Child extends Parent{
  public int myValue=200;
  public void printValue() {
  System.out.println("Child.printValue(),myValue="+myValue);
  }
}
public class Fruit
{
  public static void main(String[] args) {
    Parent parent=new Parent();
    parent.printValue();
    Child child=new Child();
    child.printValue();

    parent=child;
    parent.printValue();

    parent.myValue++;
    parent.printValue();
  
    ((Child)parent).myValue++;
    parent.printValue();

  }
}

运行结果:

总结:

当子类与父类拥有一样的方法,并且让一个父类变量引用一个子类对象时,到底调用哪个方法,由对象自己的“真实”类型所决定,这就是说:对象是子类型的,它就调用子类型的方法,是父类型的,它就调用父类型的方法。 这个特性实际上就是面向对象“多态”特性的具体表现。

如果子类与父类有相同的字段,则子类中的字段会代替或隐藏父类的字段,子类方法中访问的是子类中的字段(而不是父类中的字段)。如果子类方法确实想访问父类中被隐藏的同名字段,可以用super关键字来访问它。 如果子类被当作父类使用,则通过子类访问的字段是父类的!

Java课堂疑问解答与思考5的更多相关文章

  1. java课堂疑问解答与思考2

    问题一 编写一个方法,使用以上算法生成指定数目(比如1000个)的随机整数. 答:Xn+1=(7^5*Xn)mod(2^31-1) 程序源码: import java.util.Random; imp ...

  2. java课堂疑问解答与思考1

    问题一 Java类中只能有一个公有类吗?用Eclipse检测以下程序是否正确.是否在接口中同样适用. 答:一个源文件里必须稚嫩发有一个公有类,名称必须与文件名一致.以上程序经过编译没有提示错误.jav ...

  3. Java课堂疑问解答与思考4

    一. 请运行以下示例代码StringPool.java,查看其输出结果.如何解释这样的输出结果?从中你能总结出什么? 答:定义的三个字符串如果相等,系统自动创建一个,并调用这个,对于由new创建的字符 ...

  4. Java课堂疑问解答与思考3

    一. 两对整数明明完全一样,为何一个输出true,一个输出false? 答: 整数在小于127时都可以用常量池,因此第一次比较的的地址是取自同一个地址的数字,而第二次比较的数是创建了两个不同地址的对象 ...

  5. 一个想法(续五):IT联盟创业计划:现阶段进度公示、疑问解答及进行中的计划

    前言: 首先今天是元宵节,先祝大伙元宵节快,单纯的快乐! 然后看看开展中的计划: IT联盟创业计划众筹发起:一个想法(续三):一份IT技术联盟创业计划书,开启众筹创业征程 IT联盟创业计划众筹进度:一 ...

  6. java面试题—精选30道Java笔试题解答(二)

    摘要: java面试题-精选30道Java笔试题解答(二) 19. 下面程序能正常运行吗() public class NULL { public static void haha(){ System ...

  7. 阿里JAVA开发手册零度的思考理解(二)

    转载请注明原创出处,谢谢! 说在前面 人生的大道上默默地走,就必须要有一盏灯亮着为你引导方向!而这盏灯抑或只是一句话,一句鼓励,一个赞美,一次承认,一次认可,一次相识一次交流-- 上篇文章:阿里JAV ...

  8. Java课堂笔记(零):内容索引

    回想自己学习和使用Java的时间也是很长了.本科期间课堂上浅尝辄止地学习了点皮毛,后来也是搁置不用,未曾深入研究.研究生期间因为项目和实习的原因,基本算是重新拾起Java这门语言,并且接触到了Spri ...

  9. 20155237 第十一周java课堂程序

    20155237 第十一周java课堂程序 内容一:后缀表达式 abcde/-f+ 内容二:实现Linux下dc的功能,计算后缀表达式的值 填充下列代码: import java.util.Scann ...

随机推荐

  1. jquery 判断是否为空

    jquery 判断是否为空 if(my_val == null || my_val == undefined || my_val==""){ console.log("我 ...

  2. python变量与常量内容:

    ''' python变量与常量内容: ''' # 变量:定义世间万物变化的状态 ''' height 180 weight 140 age 18 tree_name yuyang ''' # prin ...

  3. mysql参数sql_log_bin配置

    mysql参数sql_log_bin配置 如果想在主库上执行一些操作,但不复制到slave库上,可以通过修改参数sql_log_bin来实现.比如说,这里模拟主从同步复制异常. 还有一种场景,就是导入 ...

  4. JAVA笔记25-IO流(3)-处理流举例

    处理流类型: 1.缓冲流 例1: import java.io.*; public class TestBufferStream{ public static void main(String arg ...

  5. Linux基础教程 linux下查询history操作时间的方法

    要在linux操作系统中查看history记录的操作时间,可以按如下步骤实现: 学习linux 1,修改/etc/profile文件,在末尾添加:exporthisttimeformat=”%f %t ...

  6. python 线程模块

    Python通过两个标准库thread和threading提供对线程的支持.thread提供了低级别的.原始的线程以及一个简单的锁. threading 模块提供的其他方法: threading.cu ...

  7. 记ubuntu sudo无法使用,su密码不对的解决办法

    前言 因为我有强制关机的习惯, 然后就杯具了.. ubuntu版本是 16.04 sudo没法使用, su密码不对, 顿时我就慌了 解决方案 1.1.开机点击ESC,进去GUN GRUB界面 1.2. ...

  8. 也谈HTTP协议

    HTTP(HyperText Transfer Protocol,超文转移协议,超文本传输协议的译法并不严谨.) 一.网络基础 TCP/IP 1.1 TCP/IP 协议族 TCP/IP 协议族是互联网 ...

  9. [CSP-S模拟测试]:取石子(博弈论+DP)

    题目描述 有三堆石子,它们的石子个数分别为$x,y,z$.$A$和$B$正在博弈,由$A$先手,双方轮流操作.每次操作是指,选择若干堆($1-3$堆)石子,从中各取出相同数量的石子(不能$1$个都不取 ...

  10. leetcode-easy-array-66 .plus one

    mycode 主要在计算商和余数的时候一定要用还没更新的商和余数哦 class Solution(object): def plusOne(self, digits): ""&qu ...