1、面向对象编程的四大特性及其含义
1.1、封装
- 封装把一个对象的属性私有化,同时提供一些可以被外界访问的属性的方法。
1.2、继承
- 使用已存在的类的定义作为基础建立新类,新类的定义可以增加新的数据或新的功能,也可以用父类的功能,但不能选择性地继承父类。通过使用继承我们能够非常方便地复用以前的代码。
- 子类拥有父类非 private 的属性和方法。
- 子类可以拥有自己属性和方法,即子类可以对父类进行扩展。
- 子类可以用自己的方式实现父类的方法。
1.3、多态
- 多态是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定,即一个引用变量倒底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定。
- 在Java中有两种形式可以实现多态:继承(多个子类对同一方法的重写)和接口(实现接口并覆盖接口中同一方法)。
1.4、抽象
- 对现实世界的事物进行概括,抽象为在计算机虚拟世界中有意义的实体。
1.5、为什么是单继承而不能多继承呢?
- 如果在一个子类继承的多个父类中拥有相同名字的实例变量,子类在引用该变量时将产生歧义,无法判断应该使用哪个父类的变量。
- 如果在一个子类继承的多个父类中拥有相同方法,子类中有没有覆盖该方法,那么调用该方法时将产生歧义,无法判断应该调用哪个父类的方法。
1.6、为什么是多实现呢?
- 多个接口中有重复的方法也没关系,因为实现类中必须重写接口中的方法,所以调用时还是调用的实现类中重写的方法。
2、接口和抽象类的区别
2.1、接口和抽象类的区别是什么
- 接口的方法默认是 public,所有方法在接口中不能有实现(Java 8 开始接口方法可以有默认实现),抽象类可以有非抽象的方法
- 接口中的实例变量默认是 final 类型的,而抽象类中则不一定
- 一个类可以实现多个接口,但最多只能实现一个抽象类
- 一个类实现接口的话要实现接口的所有方法,而抽象类不一定
- 接口不能用 new 实例化,但可以声明,但是必须引用一个实现该接口的对象,从设计层面来说,抽象是对类的抽象,是一种模板设计,接口是行为的抽象,是一种行为的规范。
2.2、接口的作用是什么
- 重要性:abstract class 和interface 是支持抽象类定义的两种机制。正是由于这两种机制的存在,才赋予了Java强大的面向对象能力。
- 简单、规范性。
- 维护、拓展性。
- 安全、严密性:接口是实现软件松耦合的重要手段,它描叙了系统对外的所有服务,而不涉及任何具体的实现细节。这样就比较安全、严密一些。
2.3、抽象类的意义是什么
- 把一些具有相同属性和方法的组件进行抽象,这样更有利于代码和程序的维护。
- 当有一个具有相似的组件产生时,只需要实现该抽象类就可以获得该抽象类的那些属性和方法。
2.4、如何选择抽象类和接口?
- 使用接口:
- 需要让不相关的类都实现一个方法,例如不相关的类都可以实现 Compareable 接口中的 compareTo() 方法;
- 需要使用多重继承。
- 使用抽象类:
- 需要在几个相关的类中共享代码。
- 需要能控制继承来的成员的访问权限,而不是都为 public。
- 需要继承非静态和非常量字段。
3、内部类
3.1、什么是内部类
- 内部类就是定义在另外一个类里面的类。它隐藏在外部类中,封装性更强,不允许除外部类外的其他类访问它。但它可直接访问外部类的成员。
3.2、内部类有哪些
- 成员内部类:
- 成员内部类是外围类的一个成员,是依附于外围类的,所以,只有先创建了外围类对象才能够创建内部类对象。也正是由于这个原因,成员内部类也不能含有 static 的变量和方法;
- 静态内部类:
- 静态内部类,就是修饰为static的内部类,该内部类对象不依赖于外部类对象,就是说我们可以直接创建内部类对象,但其只可以直接访问外部类的所有静态成员和静态方法;
- 局部内部类:
- 局部内部类和成员内部类一样被编译,只是它的作用域发生了改变,它只能在该方法和属性中被使用,出了该方法和属性就会失效。
- 匿名内部类:
- 定义匿名内部类的前提是,内部类必须要继承一个类或者实现接口,格式为 new 父类或者接口(){定义子类的内容(如函数等)}。也就是说,匿名内部类最终提供给我们的是一个匿名子类的对象。
3.3、静态内部类和非静态内部类的区别有
- 静态内部类是指被声明为static的内部类,可不依赖外部类实例化,而非静态内部类需要通过生成外部类来间接生成。
- 静态内部类只能访问外部类的静态成员变量和静态方法,而非静态内部类由于持有对外部类的引用,可以访问外部类的所用成员。
3.4、内部类作用的作用主要是什么?
- 内部类作用主要实现功能的隐藏、减少内存开销,提高程序的运行速度。
3.5、为什么内部类调用的局部变量必须是final修饰的?
- 由于方法中的局部变量的生命周期很短,一旦方法结束变量就要被销毁,为了保证在内部类中能找到外部局部变量。如果定义为final,java会将这个变量复制一份作为成员变量内置于内部类中,通过final关键字可得到一个外部变量的引用。通过final关键字也不会在内部类去做修改该变量的值,保护了数据的一致性。
- 在java 1.8中,可以不用final修饰,java 1.8其实会自动给它加上final。
3.6、局部变量对垃圾回收机制有什么样的影响?
- 局部变量表中的变量是很重要的垃圾回收根节点,被局部变量表中变量直接或者间接引用的对象都不会被回收。