动手动脑四

一、运行 TestInherits.java 示例,观察输出,注意总结父类与子类之间构造方法的调用关系修改Parent构造方法的代码,显式调用GrandParent的另一个构造函数,注意这句调用代码是否是第一句,影响重大!

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

}

运行结果:

 

 

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

构造函数是一种特殊的方法 。主要用来在创建对象时初始化对象, 即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中 。特别的一个类可以有多个构造函数 ,可根据其参数个数的不同或参数类型的不同来区分它们 即构造函数的重载。构造函数的功能主要用于在类的对象创建时定义初始化的状态。
所以说构造函数的作用,简单来说就是初始化,初始化一个新建的对象。而父类不拥有子类成员,故子类和父类不可以反过来调用。

三、参看ExplorationJDKSource.java示例,此示例中定义了一个类A,它没有任何成员:

class A { }
示例直接输出这个类所创建的对象
public static void main(String[] args) {
System.out.println(new A());
}

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());
}
hashCode方法是本地方法,由JVM设计者实现:
public native int hashCode();

四、 来看一段代码(示例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());
}
}

 

 

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

五、在子类中,若要调用父类中被覆盖的方法,可以使用super关键字。

class Parent {
    public Parent() {
        System.out.println("父类 1");
    }
    public void show() {
        System.out.println("子类 2");
    }
}
class Child extends Parent {
    int y;
    public Child() {
        System.out.println("父类 1");
    }
    public void show() {
        super.show();
        System.out.println("父类 3");
    }
}

public class text {
    public static void main(String args[]) {
        Child c = new Child();
        c.show();
    }
}

六、

1. 左边的程序运行结果是什么?
2. 你如何解释会得到这样的输出?
3. 计算机是不会出错的,之所以得到这样的运行结果也是有原因的,那么从这些运行结果中,你能总结出Java的哪些语法特性?

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

输出结果:

 

 

当子类与父类拥有一样的方法时,并且让一个父类变量引用一个子类对象时,看自己的类型,对象时子类型则调用子类型方法,若对象是父类型则调用父类型方法。

如果子类与父类有相同的字段,则子类中的字段回代替或隐藏父类的字段,子类方法中访问的是子类中的字段,如果子类方法想访问父类中隐藏的同名字段,可以用super来访问

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

七、为什么要用多态?它有什么好处?

使用多态最大的好处是:
当你要修改程序并扩充系统时,你需要修改的地方较少,对其它部分代码的影响较小!千万不要小看这两个“较”字!程序规模越大,其优势就越突出。

posted @ 2020-10-19 20:45  yasai  阅读(52)  评论(0编辑  收藏  举报