关于类的基本面试题

一、类初始化过程

  1. 一个类要创建实例需先加载后初始化该类

    main方法所在的类需先加载和初始化。

  2. 一个子类要初始化先初始化父类

  3. 一个类初始化就是执行()方法

    ()方法由静态类变量显示赋值代码静态代码块组成;

    类变量显示赋值代码和静态代码块代码从上到下顺序执行;

    ()方法只执行一次。

二、实例初始化过程

  1. 实例初始化就是执行()方法

    ()方法可能重载有多个,存在几个构造器就有几个()方法;

    ()方法由非静态实例变量显示赋值代码非静态代码块对应构造器代码组成;

    非静态实例变量显示赋值代码和非静态代码块从上到下顺序执行,对应构造器代码最后执行;

    每次创建实例对象,调佣对应构造器,执行的就是对应的()方法;

    ()方法的首行是super()或super(实参列表),即对应父类的()方法。

三、方法重写Override

  1. 那些方法不可被重写

    final方法;

    静态方法;

    private等子类中不可见方法。

  2. 对象的多态性

    子类如果重写父类的方法,通过子类对象调佣的一定是子类重写过得代码;

    非静态方法默认的调用对象是this;

    this对象在构造器或者说()方法中就是正在创建的对象。

四、方法重写(Override)和重载(Overload)的区别

  1. 方法重写的要求(两同两小一大)!

    在存在继承关系的子类中且父类的私有方法不能被重写

    两同:方法名和参数列表相同(参数顺序、个数、类型);

    两小:子类返回值类型小于等于父类返回值类型;子类抛出的异常小于等于父类抛出的异常;

    一大:子类方法修饰符权限要大于等于父类方法修饰符权限。

  2. 方法重载的要求!

    同一个类中;

    方法名相同,参数列表不同(参数顺序、个数、类型)。

  3. 重写与重载的意义

    重写:在不修改源码的前提下,进行功能的修改与扩展。

    重载:为了方便其他类对本类方法的调用,体现的是程序的灵活性。

五、代码示例

父类代码示例:

/*父类初始化:
* 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 × × ×
posted @ 2022-05-26 11:11  の南归  阅读(37)  评论(0)    收藏  举报