【面经总结】Java基础 - 面向对象

68 阅读4分钟

面向对象

什么是面向对象

www.bilibili.com/video/BV1wZ…

以对象为核心。

类是对象创建的模板,对象是类的实例。

面向对象三大特性是什么

  1. 封装:类的创建者将类具体实现隐藏,使用者只需要使用外部接口即可
  2. 继承:类有子类和父类,有从属关系。提高代码复用性。
  3. 多态:同一个方法可以被不同的对象以不同的方式执行。子类可以替代父类出现在任何需要父类的地方

怎么理解多态的特性

  1. 什么是多态:接口的多种不同的实现方式即为多态。多个对象调用同一个方法,得到不同的结果。
  2. 多态使用: 父类类名 对象 = new 子类类名();
  3. 向上转型(默认):子类型赋值给父类型。对象只能访问父类中的属性和方法,但会优先访问子类重写的方法。
  4. 向下转型:子类型赋值给父类型后,强转回子类型。
class Animal {
    public void eat() {
        System.out.println("Animal is eating");
    }
}

class Dog extends Animal {
    public void bark() {
        System.out.println("Dog is barking");
    }
}

public class Main {
    public static void main(String[] args) {
        // 向上转型
        Animal myAnimal = new Dog(); 
        myAnimal.eat();

        // 向下转型
        if (myAnimal instanceof Dog) {
            Dog myDog = (Dog) myAnimal;
            myDog.bark();
        }
    }
}

Java为什么只能单继承

www.bilibili.com/video/BV14o…

  1. 使用简单:多继承会导致“钻石问题”,子类有多个相同方法需要继承。
  2. 多继承在其他语言中也不经常使用
  3. Java可以通过实现多个接口实现“多继承”

抽象类和接口

接口和抽象类有什么区别

www.bilibili.com/video/BV14T…

相同点:

  1. 都可以定义抽象方法,让子类去实现
  2. 都不能实例化

不同点:

  1. 抽象类用继承extend,接口用实现implements
  2. 接口可以多实现,抽象类只能单继承
  3. 抽象类可以实现接口,接口只能继承接口
  4. 抽象类可以定义成员属性,接口只能定义静态常量
  5. 抽象类可以定义构造方法,控制子类实例化。接口没有构造方法。

接口的补充:

  1. Java8:default关键字实现接口默认方法,子类可以不重写。提高兼容性。
  2. Java9:private关键字可以封装私有方法,可以提高默认方法的函数内的代码复用性。

方法重写和重载

方法重载和重写有什么区别

  • 重载:类中定义了多个方法名相同,但参数不同的方法。
  • 重写:子类存在方法与父类的方法的名字相同、参数相同

方法重载是一个类的多态性表现,而方法重写是子类与父类的一种多态性表现。

多态性:相同的名称但有着不同的实现。

内部类

内部类汇总

  1. 成员内部类:在成员位置上定义类
    1. 可以访问外部类静态属性和非静态属性
    2. 外部类成员方法调用成员内部类的方法需要先创建对象
public class User {
    static String name;
    int age;

    class IdCard {
        String id;

        public void getIdCardData() {
            System.out.println(name);
            System.out.println(id);
            System.out.println(age);
        }
    }

    IdCard idCard = new IdCard();

    public void getUserData() {
        System.out.println(idCard.id);
    }
}
  1. 局部内部类:在类的方法中定义类
    1. 可以访问外部类静态属性和非静态属性
public class User {
    static String name;
    int age;

    public void say() {
        class IdCard {
            String birthday;

            public void getIdCardData() {
                System.out.println(name);
                System.out.println(age);
                System.out.println(birthday);
            }
        }

        IdCard idCard = new IdCard();
        idCard.getIdCardData();
    }
}
  1. 静态(成员)内部类:在成员位置上定义静态类
    1. 只能访问外部类静态属性,不能访问非静态属性
public class User {
    static String name;
    int age;

    static class IdCard {
        String id;

        public void getIdCardData() {
            System.out.println(name);
            System.out.println(id);
            // System.out.println(age);
        }
    }

    IdCard idCard = new IdCard();

    public void getUserData() {
        System.out.println(idCard.id);
    }
}
  1. 匿名内部类:只有类体没有类名的类,通常用于创建只需要使用一次的类的实例。
public abstract class Animal {
    String name;
    abstract void eat();
}

public class Main {
    public static void main(String[] args) {
        Animal animal = new Animal() {
            @Override
            void eat() {
                System.out.println("The animal is eating");
            }
        };
        animal.eat();
    }
}

为什么需要内部类?什么是匿名内部类?

内部类的主要作用是可以访问外部类的私有成员。

匿名内部类是只有类体没有类名的类,通常用于创建只需要使用一次的类的实例。可以简化代码书写,不需要单独定义一个实体类。

静态内部类和非静态内部类有什么区别?

外部属性:

  • 静态内部类只能访问外部类的静态属性
  • 非静态内部类可以访问外部类的静态属性和非静态属性

对外部类实例的依赖:

  • 静态内部类可以直接创建
  • 非静态内部类需要外部类实例才能创建

静态内部类的使用场景是什么?

用来实现单例模式

  • 优点:天然线程安全,实现延迟加载
  • 缺点:第一次加载又有延迟
public class Singleton {
    public static class Inner {
        public static final Singleton INSTANCE = new Singleton();
    }

    public static Singleton getInstance() {
        return Inner.INSTANCE;
    }

    private Singleton() {}
}