面向对象三大基石:封装,继承,多态。面试会问到。Overriding 覆盖 只存在于父子类之间,一定。什么时候才是覆盖呢?class Father{ public void run(){ }}class Son extends Father{ public void run(int a){ }}注意:这是方法的重载,不是覆盖!只是这个重载发生在父子类之间。覆盖是,子类参数列表与返回值都与父类相同,并且子类在覆盖父类方法时,不能给出更严格的访问控制,并且子类方法例外的类型是等于父子方法抛出的异常类型,或者是其子类型。The exceptions thrown by an overriding method must be equal to or a subset of the exceptions thrown by the overridden method.注意构造方法根本不能继承,所以不存在覆盖的问题。访问控制private 本类内部可见default 同类同包protected 同包+不同包子类要构造一个对象,先构造父类对象,再构造子类对象构造一个对象的执行过程。1.递归的构造父类对象-----------〉也就是说父类本身也要走这样的步骤。2.顺序调用成员属性赋初值语句3.调用本类构造方法后来课程领悟,类加载与构造对象是两回事,类加载过程,1.static静态成员加载,2运行static一次,静态代码块,3如果有静态内部类,赋值,对静态内部类的赋值是指编译产生的Employee$SomeInner.class文件的读取。如果类有静态变量或者静态块,而且用到时(static初始化只有在必要的时候才会进行),那么就会在第一步之前执行一遍,先静态变量,然后静态块,以后再怎么new都不会执行,回到创建父类开始。======〉引用Think In Java在这里有必要总结一下对象的创建过程。请考虑一个名为Dog的类:(1) 类型为Dog的一个对象首次创建时,或者Dog类的static方法/static字段首次访问时,Java解释器必须找到Dog.class(在事先设好的类路径里搜索)。(2) 找到Dog.class后(它会创建一个Class对象,这将在后面学到),它的所有static初始化模块都会运行。因此,static初始化仅发生一次——在Class对象首次载入的时候。(3) 创建一个new Dog()时,Dog对象的构建进程首先会在内存堆(Heap)里为一个Dog对象分配足够多的存储空间。(4) 这种存储空间会清为零,将Dog中的所有基本类型设为它们的默认值(零用于数字,以及boolean和char的等价设定)。(5) 进行字段定义时发生的所有初始化都会执行。(6) 执行构建器。正如第6章将要讲到的那样,这实际可能要求进行相当多的操作,特别是在涉及继承的时候。=====================多态-1.编译时多态 方法重载 2.运行时多态 一个对象可能会具有多个类型对象是客观的。人类对对象的认识是主观的当人看到一个不能识别的,有生命的,区别人的东西时,会类来认识该事物。也就是Animal a = new Dog();子类对象可以使用父类对象来引用。Animal被称为编译时类型,而a真正的对象类型是运行时类型。3个原则:1.对象不变(运行时类型不变)(客观的肯定不会改变)2.只能调用编译时类型的方法,方法调用时,检查编译时类型内部是否定义了该方法。 也就是说,在你以一个一个动物来看待一只狗时,你是不会知道它有散步的方法的。3.RTTI,运行时,动态类型判定(看运行时类型),子类覆盖了(Overriding)父类方法,那么调用运行时类型对象的方法。a instanceof 类名(编译时类型)a为对象变量判断a是否被声明为后面类的对象。用在强制类型转换之前。如果转换错了,java.lang.ClassCastException 运行时例外记住,方法只有覆盖时,调用寻找运行时类型。而Overloading ->编译时多态->看编译时类型。属性,重载阿,都要看编译时类型。
为什么子类覆盖父类方法时,访问控制符只能更宽泛。因为如果父类方法为public,子类方法为private,那么多态时,察看父类方法可以调用(可调用编译时类型所定义的方法),而动态类型判断时,调用子类方法,发现为private,完蛋了。