动手动脑(课堂作业05)

1,思考

class Grandparent
{

    public Grandparent()
     {

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

}

    public Grandparent(String string)
    {

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

 }

}

class Parent2 extends Grandparent
{

    public Parent2()
     {

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

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

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

      }
    public Parent2(String a)
    {

        System.out.println("PPP"+a);
    }

}

class Child2 extends Parent2
{

    public Child2()
     {

        //super("GGG");
        System.out.println("Child Created");

      }

}

public class TestInherits
{

    public static void main(String args[])
     {

            Child2 c = new Child2();

  }

}

运行结果为:

显然运行子类的构造函数会先执行父类的构造函数。若将//super("Hello.Grandparent.");前//去掉之后运行就结果就会变成:

有了super()语句会执行其调用的构造函数,若将其放在第二行,则会报错

(构造函数调用必须是构造函数中的第一个语句)这是显示的错误。

总结:通过 super 调用父类构造方法,必须是子类构造方法中的第一个语句。若父类中同时存在有参构造函数和无参构造函数,若子类构造函数什么也没写则默认调用无参构造函数,若加上super(),则根据super()来确定,若父类只有有参构造函数,则必须在写子类构造函数时加上super();

2,思考

构造函数(constructor)是一种特殊的方法 。主要用来在创建对象时初始化对象, 即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中 。特别的一个类可以有多个构造函数 ,可根据其参数个数的不同或参数类型的不同来区分它们 即构造函数的重载。构造函数的功能主要用于在类的对象创建时定义初始化的状态。构造一个对象,先调用其构造方法,来初始化其成员函数和成员变量。子类拥有父的成员变量和成员方法,如果不调用,则从父类继承而来的成员变量和成员方法得不到正确的初始化。不能反过来调用也是这个原因,因为父类根本不知道子类有神魔变量而且这样一来子类也得不到初始化的父类变量,导致程序运行出错!

3,解密

public class ExplorationJDKSource {

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

}

class A{}

通过javap反编译得:

可以看到println()那条语句到底调用了Ljava/lang/Object使用Eclipse打开JDK源码,查看真正被执行的代码是

4,探索:观看以下代码,,注意最后一句,一个字串和一个对象“相加”

得到的结果为:

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

5,请自行编写代码测试以下特性(动手动脑): 在子类中,若要调用父类中被覆盖的方法,可以使用super关键字。

代码如下:

class ddd
{
    int num;
    ddd()
    {
        this.num=1;
    }
    void shuchu()
    {
        System.out.println("父类"+num);
    }
}
class aaa extends ddd
{
    aaa()
    {
        this.num=2;
    }
    void shuchu()
    {
        super.shuchu();
        System.out.println("子类"+num);
    }
}
public class demo {
    public static void main(String[]args)
    {
        aaa wa=new aaa();
        wa.shuchu();
    }

}

运行结果为:

若将super.shuchu()注释掉,结果为:

6,怎样判断对象是否可以转换?

可以使用instanceof运算符判断一个对象是否可以转换为指定的类型: Object obj="Hello"; if(obj instanceof String) System.out.println("obj对象可以被转换为字符串");

public class TestInstanceof
{
    public static void main(String[] args)
    {
        //声明hello时使用Object类,则hello的编译类型是Object,Object是所有类的父类
        //但hello变量的实际类型是String
        Object hello = "Hello";
        //String是Object类的子类,所以返回true。
        System.out.println("字符串是否是Object类的实例:" + (hello instanceof Object));
        //返回true。
        System.out.println("字符串是否是String类的实例:" + (hello instanceof String));
        //返回false。
        System.out.println("字符串是否是Math类的实例:" + (hello instanceof Math));
        //String实现了Comparable接口,所以返回true。
        System.out.println("字符串是否是Comparable接口的实例:" + (hello instanceof Comparable));
        String a = "Hello";
        //String类既不是Math类,也不是Math类的父类,所以下面代码编译无法通过
        //System.out.println("字符串是否是Math类的实例:" + (a instanceof Math));
    }
}

结果为:

7,小测试:

现在有三个类: 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;

我认为第一句不出错,可以用子类给父类赋值,因为子类里有父类里所有的变量;第二句会出错,不能用父类变量来给子类赋值,父类里面不一定包含不全子类里所有的变量;第三句不会出错若要用子类给父类赋值必须强转;第四句出错,这两个变量间没有直接关系;第五句对同第三句。

class Mammal{}
class Dog extends Mammal {}
class Cat extends Mammal{}

public class TestCast
{
    public static void main(String args[])
    {
        Mammal m;
        Dog d=new Dog();
        Cat c=new Cat();
        m=d;
        //d=m;
        d=(Dog)m;
        //d=c;
        //c=(Cat)m;

    }
}

结果:

第二句错误显示为:类型不匹配:不能从 Mammal 转换为 Dog

第三句错误显示为:类型不匹配:不能从 Cat 转换为 Dog

8,动动手:

public class ParentChildTest {
    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();

    }
}

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);
    }
}

结果:

解释:

先定义了一个父类对象以及子类变量,输出就显示出来第一二句,然后用children对象给parent对象赋值,parent对象的myValue变为200;parent函数printvalue也被覆盖,于是就有了第三句,value++是先输出再加一,于是输出第四句,然后强转输出,这是value已经是201,先输出在加一有了第五句。

思考:但我又加了一行代码如下:

运行结果如下:

发现父类对象的数据值加了1

之后再改如下:

结果为:

我在网上查了查发现过程为:

第一个100:是parent调用PrintValue方法输出parent类中myValue值为100;

第二个200:是child调用PrintValue方法输出child类中myValue值为200;

第三个200:是parent = child,将子类对象的赋值给父类,但此时parent只能调用子类的方法,调用子类PrintValue时,输出的当然是子类的myValue值200。

第四个200:虽然parent = child,但parent不能调用子类的变量,所以parent.myValue++;只是将父类对象中的变量myValue值+1但不能改变子类的myValue值,但调用的是子类PrintValue方法时,输出的是子类的myValue值200。

第五个201:(Child)parent,强制转化parent为child对象,此时parent完全成为child对象,所以输出值为201。

原因:

(1):当子类和父类拥有同名方法时,并且让一个父类变量引用一个子类对象时,调用哪个方法由自己的真实类型来决定。

(2):如果子类与父类有相同的字段,则子类中的字段会代替或隐藏父类的字段,子类方法中访问的是子类中的字段(而不是父类中的字段)。

时间: 2024-10-14 06:20:53

动手动脑(课堂作业05)的相关文章

动手动脑课堂作业7---------

动手动脑1 CatchWho.java运行结果: CatchWho2.java运行结果: EmbedeFinally.java运行结果: finally语句块一定会执行吗? SystemExitAndFinally.java运行结果: 只有与 finally 相对应的 try 语句块得到执行的情况下,finally 语句块才会执行.如果在try语句块之前返回(return)或者抛出异常,try对应的finally语句块就不会执行. 动手动脑2 如何跟踪异常的传播路径? 当程序中出现异常时,JVM

动手动脑与作业

一.古罗马皇帝凯撒在打仗时曾经使用过以下方法加密军事情报:请编写一个程序,使用上述算法加密或解密用户输入的英文字串. 1.设计思想 输入数据后,输入数字n,若n>5,则为加密过程,数据按ASCII码转化为int型,转化得来的数字加数字做为加密后的数据,再将这些数据转化为字符,这就是加密.若n<5,则为解密过程,数据按ASCII码转化为int型,转化得来的数字减数字做为解密后的数据,再将这些数据转化为字符,这就是解密. 2.程序流程图 3.源代码 //信1403-1班 张妞妞   加解密 imp

动手动脑(课堂作业05)第二句错误显示为:类型不匹配:不能从 Mammal 转换为 Dog 第三句错误显示为:类型不匹配:不能从 Cat 转换为 Dog

---恢复内容开始--- 为什么子类的构造方法在运行之前,必须调用父类的构造方法?能不能反过来?为什么不能反过来? 构造函数(constructor)是一种特殊的方法 .主要用来在创建对象时初始化对象, 即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中 .特别的一个类可以有多个构造函数 ,可根据其参数个数的不同或参数类型的不同来区分它们 即构造函数的重载.构造函数的功能主要用于在类的对象创建时定义初始化的状态.构造一个对象,先调用其构造方法,来初始化其成员函数和成员变量.子类

动手动脑课堂练习

一.原码.反码和补码 (出处:http://www.cnblogs.com/zhangziqiu/ ) 1.机器数和真值 在学习原码, 反码和补码之前, 需要先了解机器数和真值的概念. (1).机器数 一个数在计算机中的二进制表示形式,  叫做这个数的机器数.机器数是带符号的,在计算机用一个数的最高位存放符号, 正数为0, 负数为1.比如,十进制中的数 +3 ,计算机字长为8位,转换成二进制就是00000011.如果是 -3 ,就是 10000011 .那么,这里的 00000011 和 100

课堂作业05 《6种质量属性战术》

实现xxxx系统质量属性战术 1.可用性战术:错误检测战术 对XXXX系统的所有信息的输入及数据处理进行异常的处理.尤其对信息进行填报时,编写异常类来捕获异常. 2.易用性战术:设计战术 (1)在进行归口部门填写时,可以使用搜索词进行提示,方便进行填写. 在填写需求征集表格时,对于用户已注册填写过的基本信息,可以折叠,看起来更加简洁明了. (2)将用户接口与应用的其余部分分离开来:为方便用户接口的修改.将用户操作界面与实现分开实现. 3.可修改性战术:局部化修改 设计登陆的泛化模块,不同身份登陆

Java课堂作业05

1.随机生成10个数,填充一个数组,然后用消息框显示数组内容,接着计算数组元素的和,将结果也显示在消息框中. 设计思路:定义一个长度为10的数组---->数组初始化---->利用随机数给数组元素分别赋值--->转换成字符串求和--->输出结果 程序流程图: 程序源代码: 结果截图: 编程注意及总结: 编写该程序定义数组时一定要初始化,随机数产生也借助for循环.

动手动脑java作业

1.程序截图 第一个false:判断s和t里的值,不同则输出false 第二个false:当且仅当这个类表示一个基本类型此方法返回true 第三个true:判断s和u里的值,相同则输出true 最后则是列出Size的所有值. 其中的问题: //s和t引用同一个对象?不是 //是原始数据类型吗?不是 2.计算机的原码.补码和反码: 1.原码:原码表示法是机器数的一种简单的表示法.其符号位用 0表示正号,用1表示负号,数值一般用二进制形式表示. 2.补码:机器数的补码可由原码得到.如果机器数是正数,

动手动脑+课后作业

一.编写一个方法,使用以上算法生成指定数目(比如1000个)的随机整数. 二.代码MethodOverLoad有什么特殊之处? 使用了同一种方法但是是不同类型. 这是"方法重载",构成重载的条件:1.方法名相同(square) 2.参数类型不同(int,double),参数个数不同或参数类型的顺序不同. 三. (1) (2) (3) (4) (5)

Java动手动脑课后作业1-求创建对象个数

截图 //通过静态字段和构造函数知道所创建对象个数 //刘启明,October 17,2015 package Demo; class ObjectNumbers{ static int number=0; public ObjectNumbers()  { System.out.println("已经创建了"+(++number)+"个对象!!"); } } public class Search { public static void main(String[