第八、九章 多态与接口

1、多态:接口元素(就是方法)的多种实现方式,表现在重载、覆盖。

2、只有普通的方法支持覆盖,被private和static修饰的方法,以及域都看不到覆盖效果。

3、接口中所有的方法都是public的,接口方法被定义时也必须是public的。

4、接口中的域都是static final的

5、接口的实质就是极度抽象的类,接口的实现实质就是继承关系,就是方法的覆盖,方法的覆盖不可以降低方法的可见性。

实例:连内部类都继承过去了

interface Fruit1 {
    //接口中的类自动为嵌套类,且是public
     class Apple {
        public void eat() {
            System.out.println("Apples are good!");
        }
    }
}

public class StaticInnerClass implements Fruit1{
    
    public static void main(String[] args) {
        StaticInnerClass.Apple a2 =new StaticInnerClass.Apple();
        a2.eat();
    }
}

 

6、构造器中调用方法法的多态问题

实例: 

class Super {
    Super() {
        print();
    }
    void print() {
        System.out.println("Super");
    }
}

public class OverrideProblem extends Super {

    void print() {
        System.out.println("OverrideProblem");
    }
    
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        new OverrideProblem();
    }

}

输出:

这个实例的输出相当诡异:应该输出Super啊,为什么是OverrideProblem

答案:在构造器中调用可以被子类覆盖的函数时,要相当慎重,它会调用子类中的方法,而不是本类的方法。

稍微改一下:

class Super {
    Super() {
        print();
    }
    static void print() {
        System.out.println("Super");
    }
}

public class OverrideProblem extends Super {

    static void print() {
        System.out.println("OverrideProblem");
    }
    
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        new OverrideProblem();
    }

}

我将print()方法改成静态方法就正常了:

因为被final、private、static修饰的方法是没有覆盖效果的,如若覆盖,两个方法讲是相互独立的同名方法,没有覆盖效果。

7.看一个诡异的代码分析一波问题

大家都知道15行的代码调用的是ProtectedProblem2.print(int i)这个函数,可是为什么第15行代码会报错呢。这样做在同一个包中确实没有问题,但是java的多态是动态绑定的,也就是说,只有在运行期才能够知道调用的是A.print(int i)还是ProtectedProblem2.print(int i);在编译期,编译器是不知道的,编译器不知道类型信息以为是调用A.print(int i),而A.print(int i)在包外是不可见的,所以就会报错误。

posted @ 2019-08-20 15:54  卑微芒果  Views(134)  Comments(0)    收藏  举报