第三次动手动脑

(一)

通过 super 调用基类构造方法,必须是子类构造方法中的第一个语句。在调用子类构造方法之前,必须先调用基类构造方法。

(二)

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

构造函数的主要作用是在定义对象时初始化对象,定义子类对象时会同时定义父类对象,然后调用父类构造方法将其初始化,再调用子类对象将其初始化,所以不能反过来。

(三)

package JavaApp;


public class ExplorationJDKSource {

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

}

class A{}

我们得到了一个奇特的运行结果: A@1c5f743

为什么??

在编译源代码时,当遇到没有父类的类时,编译器会将其指定一个默认的父类(一般为Object),而虚拟机在处理到这个类时,由于这个类已经有一个默认的父类了,main方法实际上调用的是:
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();所以出现上述结果。

(四)

package JavaApp;

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());
    }
}
一个字串和一个对象“相加”,得到以下结果:

f=Fruit toString.
f=Fruit toString.

为什么??

当一个字符串和一个对象连接时,对象会隐式的调用其toString方法。所以两个输出结果一样。

(五)

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

package JavaApp;

class one
{
      public void one()
      {
          System.out.println("这是父类!");
      }
}

class two extends one
{
       public void one()
      {
          System.out.println("这是子类!");
          System.out.println("使用super关键字:");
          super.one();
      }
}

public class fugai {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
           two a=new two();
           a.one();
    }
}

运行结果:

这是子类!
使用super关键字:
这是父类!

(1)覆盖方法的允许访问范围不能小于原方法。

(2)覆盖方法所抛出的异常不能比原方法更多。

(3)声明为final方法不允许覆盖。 例如,Object的getClass()方法不能覆盖。

(4)不能覆盖静态方法。

(六)

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

m=d;

d=m;

d=(Dog)m;

d=c;

c=(Cat)m;

package JavaApp;

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;

    }
}

子类对象可以赋给基类对象,基类对象赋给子类对象时必须强制转换,同一父类派生下来的子类之间不可以赋值。

所以可以成立的有m=d;        d=(Dog)m;     c=(Cat)m;

(七)
package JavaApp;

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

猜你喜欢

转载自www.cnblogs.com/liyuchao/p/9890502.html