动手动脑4

1.继承条件下构造方法调用

(1)例子

package practice1;

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 Test
{

    public static void main(String args[])
     {

            Child c = new Child();
    
  }

}

运行现在的代码运行结果:

 当把第一句注释删掉后的运行结果:

 当把第二句注释删掉后运行时报错

(2)结论:

  • 如果一个类中没有定义构造器时,编译器会在编译时自动加上默认无参构造器

  • 每个类都直接或间接时object的子类,并且object只有一个无参构造方法

  • 编译器会在每个构造函数第一行隐式添加父类的默认无参构造函数,即super()

  • 在子类的构造方法中调用其父类的构造方法。如果父类无构造方法或者含有无参构造方法时,那么子类的构造方法中会自动调用super()

  • 如果父类有含参数的构造方法,那么在子类的构造方法中,必须用super()调用父类的某个构造方法,而且必须是在构造方法的第一个语句中进行调用

  • 子类构造时必须通过某些方式首先调用父类的构造方法,否则会报错


2.输出类的奥秘

1 class A{}
2 public class Test
3 {
4     public static void main(String[] args) {
5         System.out.println(new A());
6     }
7 }

 解释:

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


3.方法覆盖

要点:

  • 方法覆盖要求子类与父类的方法一模一样

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

  • 覆盖方法的允许访问范围不能小于原方法

  • 覆盖方法所抛出的异常不能比原方法更多

  • 声明为final方法不允许覆盖

  • 不能覆盖静态方法

 1 class Animal{
 2     public void display() {
 3         System.out.println("我是一只动物");
 4     }
 5 }
 6 class Dog extends Animal{
 7     public void display() {
 8         super.display();
 9         System.out.println("我是一只狗");
10     }
11 }
12 class Cat extends Animal{
13     public void display() {
14         System.out.println("我是一只猫");
15     }
16 }
17 public class Test
18 {
19     public static void main(String[] args) {
20         Animal a=new Animal();
21         a.display();
22         Dog d=new Dog();
23         d.display();
24         Cat c=new Cat();
25         c.display();
26     }
27 }


4.多态

 1 public class Test {
 2     public static void main(String[] args) {
 3         Parent parent=new Parent();
 4         parent.printValue();
 5         Child child=new Child();
 6         child.printValue();
 7         
 8         parent=child;
 9         parent.printValue();
10         
11         parent.myValue++;
12         parent.printValue();
13         
14         ((Child)parent).myValue++;
15         parent.printValue();
16         
17     }
18 }
19 
20 class Parent{
21     public int myValue=100;
22     public void printValue() {
23         System.out.println("Parent.printValue(),myValue="+myValue);
24     }
25 }
26 class Child extends Parent{
27     public int myValue=200;
28     public void printValue() {
29         System.out.println("Child.printValue(),myValue="+myValue);
30     }
31 }

将main()代码修改后:

 1 public class Test {
 2     public static void main(String[] args) {
 3         Parent parent=new Parent();
 4         parent.printValue();
 5         Child child=new Child();
 6         child.printValue();
 7         
 8         parent.myValue++;
 9         System.out.println(parent.myValue);
10         parent.printValue();
11         
12         parent=child;
13         parent.printValue();
14         
15         parent.myValue++;
16         System.out.println(parent.myValue);
17         parent.printValue();
18         
19         
20         ((Child)parent).myValue++;
21         parent.printValue();
22         
23     }
24 }

我们不难发现,在parent=child; 之前,父类parent调用的是父类的变量和父类的方法,而让父类对象变量引用子类对象后,parent调用的是父类的变量和子类的方法。

 结论:

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

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

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


5.接口实例

原文地址:https://www.cnblogs.com/znjy/p/13853650.html