关于类的基本面试题
一、类初始化过程
-
一个类要创建实例需先加载后初始化该类
main方法所在的类需先加载和初始化。
-
一个子类要初始化先初始化父类
-
一个类初始化就是执行
()方法 ()方法由静态类变量显示赋值代码和静态代码块组成; 类变量显示赋值代码和静态代码块代码从上到下顺序执行;
()方法只执行一次。
二、实例初始化过程
-
实例初始化就是执行
()方法 ()方法可能重载有多个,存在几个构造器就有几个 ()方法; ()方法由非静态实例变量显示赋值代码和非静态代码块、对应构造器代码组成; 非静态实例变量显示赋值代码和非静态代码块从上到下顺序执行,对应构造器代码最后执行;
每次创建实例对象,调佣对应构造器,执行的就是对应的
()方法; ()方法的首行是super()或super(实参列表),即对应父类的 ()方法。
三、方法重写Override
-
那些方法不可被重写
final方法;
静态方法;
private等子类中不可见方法。
-
对象的多态性
子类如果重写父类的方法,通过子类对象调佣的一定是子类重写过得代码;
非静态方法默认的调用对象是this;
this对象在构造器或者说
()方法中就是正在创建的对象。
四、方法重写(Override)和重载(Overload)的区别
-
方法重写的要求(两同两小一大)!
在存在继承关系的子类中且父类的私有方法不能被重写;
两同:方法名和参数列表相同(参数顺序、个数、类型);
两小:子类返回值类型小于等于父类返回值类型;子类抛出的异常小于等于父类抛出的异常;
一大:子类方法修饰符权限要大于等于父类方法修饰符权限。
-
方法重载的要求!
同一个类中;
方法名相同,参数列表不同(参数顺序、个数、类型)。
-
重写与重载的意义
重写:在不修改源码的前提下,进行功能的修改与扩展。
重载:为了方便其他类对本类方法的调用,体现的是程序的灵活性。
五、代码示例
父类代码示例:
/*父类初始化:
* 1.j=method();
* 2.父类静态代码块
*
* 父类实例化方法<init>():
* 1.super()
* 2.i=test(); 这里的i=test()执行的是子类重写的test()方法
* 3.父类的非静态代码块
* 4.父类的无参构造
*
*非静态方法前面存在一个默认的this,this在构造器(或<init>())中表示的是正在创建的对象,
*因为这里是在创建子类对象,所以test()执行的是子类重写的代码(体现了面向对象的多态)
* */
public class Father {
private int i = test();
private static int j = method();
static {
System.out.print("(1)");
}
Father(){
System.out.print("(2)");
}
{
System.out.print("(3)");
}
public int test() {
System.out.print("(4)");
return 1;
}
public static int method() {
System.out.print("(5)");
return 1;
}
}
子类代码示例:
/*子类初始化:
* 1.先初始化父类:(5)(1)
* 2.初始化子类:(10)(6)
*
* 子类实例化方法<init>():
* 1.super() (9)(3)(2)
* 2.i=test(); (9)
* 3.子类的非静态代码块 (8)
* 4.子类的无参构造 (7)
*
* 因为创建了两个Son对象,所以实例化方法<init>()执行两次
* */
public class Son extends Father{
public static void main(String[] args) {
Son son1 = new Son();
System.out.print("//////////");
Son son2 = new Son();
}
private int i = test();
private static int j = method();
static {
System.out.print("(6)");
}
Son(){
//super();//写或不写都存在,在子类构造器中一定会调用父类构造器
System.out.print("(7)");
}
{
System.out.print("(8)");
}
public int test() {
System.out.print("(9)");
return 1;
}
public static int method() {
System.out.print("(10)");
return 1;
}
}
代码运行结果:
"C:\Program Files\Java\jdk1.8.0_171\bin\java.exe" "-javaagent:E:\JAVA\idea\IntelliJ IDEA
(5)(1)(10)(6)(9)(3)(2)(9)(8)(7)//////////(9)(3)(2)(9)(8)(7)
Process finished with exit code 0
补充:
一、成员变量、局部变量和静态变量的区别
| 成员变量 | 局部变量 | 静态变量 | |
|---|---|---|---|
| 定义位置 | 类里方法外 | 方法中或方法的形参 | 类里方法外 |
| 初始化值 | 有默认初始化值 | 无,先定义,赋值后使用 | 有默认初始化值 |
| 调用方式 | 对象调用 | 对象调用 | 类调用 |
| 存储位置 | 堆中 | 栈中 | 方法区 |
| 生命周期 | 与对象共存亡 | 与方法共存亡 | 与类共存亡 |
二、控制访问修饰符
修饰符是用来修饰类、成员变量和方法的,它通常放在语句的最前面。
| 修饰符 | 同类 | 同包 | 子类 | 不同包 |
|---|---|---|---|---|
| public | √ | √ | √ | √ |
| protected | √ | √ | √ | × |
| default | √ | √ | × | × |
| private | √ | × | × | × |

浙公网安备 33010602011771号