第八、九章 多态与接口
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)在包外是不可见的,所以就会报错误。

浙公网安备 33010602011771号