动手动脑,11.9

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了动手动脑,11.9相关的知识,希望对你有一定的参考价值。

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

构造函数的功能主要用于在类的对象创建时定义初始化的状态。构造一个对象,先调用其构造方法,来初始化其成员函数和成员变量。

子类拥有父的成员变量和成员方法,如果不调用,则从父类继承而来的成员变量和成员方法得不到正确的初始化。

不能反过来调用也是这个原因,因为父类根本不知道子类有什么变量,子类也得不到初始化的父类变量.所以程序不能运行。

2.不可变的“类”有何用?

可以方便和安全地用于多线程环境中,访问它们可以不用加锁,因而能提供较高的性能。

 

 

知识点:(子类与父类方法间的关系  扩充(Extends):子类定义的方法父类没有同名

覆盖/重写(Override):子类父类定义了完全一样的方法

重载(Overloads):子类有父类的同名方法,但两者的参数类型或参数数目不一样)

3.

public class ExplorationJDKSource {

 

/**

 * @param args

 */

public static void main(String[] args) {

System.out.println(new A());

}

 

}

 

class A{}

 

 

public void println(Object x),这一方法内部调用了String类的valueOf方法。

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

public String toString() {

return getClass().getName() +"@" +

Integer.toHexString(hashCode());

}

 

 

  1. 我们来看一段代码:
  2. 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());

}注意最后一句,一个字串和一个对象“相加”,得到以下结果:

 

}

 

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

4.在子类中,若要调用父类中被覆盖的方法,可以使用super关键字:

class Father

{

      public void display()

        {

                System.out.println("Father");

        }

        }

class Son extends Father

{

        public void display()

        {

                super.display();

                System.out.println("Son");

        }

        }

public class Teost {

public static void main(String []args)

{

        Son c=new Son();

        c.display();

        }

         

}

 

 

  1. 怎样判断对象是否可以转换?

例:public class TestInstanceof

{

public static void main(String[] args)

{

//声明hello时使用Object类,则hello的编译类型是ObjectObject是所有类的父类

//hello变量的实际类型是String

Object hello = "Hello";

//StringObject类的子类,所以返回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));

}

}

 

 

6.现在有三个类:

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;

d=m 编译错误,基类转换成子类需要强制转换,d=c,错误,两个对象不能互换。

7.请看以下“变态”的类,下述代码的特点是:

子类和父类定义了一模一样的字段和方法

 

 

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

}

}

程序运行结果是什么?

Parent.printValue(),myValue=100

Child.printValue(),myValue=200

Child.printValue(),myValue=200

Child.printValue(),myValue=200

Child.printValue(),myValue=201

你如何解释会得到这样的输出?

当子类与父类拥有一样的方法,并且让一个父类变量引用一个子类对象时,到底调用哪个方法,由对象自己的“真实”类型所决定,这就是说:对象是子类型的,它就调用子类型的方法,是父类型的,它就调用父类型的方法。

这个特性实际上就是面向对象“多态”特性的具体表现。

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

如果子类被当作父类使用,则通过子类访问的字段是父类的。

以上是关于动手动脑,11.9的主要内容,如果未能解决你的问题,请参考以下文章

动手动脑 (第二次)

动手动脑-4

动手动脑,无法自拔

方法的动手动脑

第三次实验及动手动脑

第八周动手动脑