面向对象和面向过程的区别
- 面向过程性能更优一些,所以一般是使用在底层,例如,单片机、嵌入式开发
- 面向对象相对于面向过程效率较低,但是面向对象具有继承封装多态的特性使得面向对象的程序易维护,易扩展,易复用
多态是如何实现的
接口和抽象类的区别
设计层面
- 抽象是对类的抽象,是一种模板设计
- 接口是对行为的抽象,是一种行为规范
使用层面
- 类可以实现多个接口,但是只能继承一个抽象类
- 类可以不实现抽象类和接口中的抽象方法,但是这种情况下,类必须声明为抽象类
- 接口中声明的变量默认是被
final
修饰,而抽象类中可以包含非final的属性 - 接口中的方法默认是被
public
修饰,而抽象类的方法可以被private
,protected
或者public
修饰 - 接口中所有方法都是抽象方法,而抽象类中的方法可以同时包含抽象和非抽象的方法
对象创建+对象初始化过程
对象是如何创建的?
- 判断对应的类是否已经加载,需要先完成类加载
- 内存分配
- 初始化默认值
- 设置对象头(对象头中包含了CG年龄,GC年龄,是否充当锁等)
- 执行
init()
初始化方法
子实现类是如何初始化的?
-
类加载过程中
-
初始化父类中的静态成员变量和静态代码块
-
初始化子类中的静态成员变量和静态代码块
-
-
对象创建过程中
-
初始化父类的普通成员变量和代码块,再执行父类的构造方法
-
初始化子类的普通成员变量和代码块,再执行子类的构造方法
-
重载和重写的区别
-
重载:重载同名称的方法,但是需要参数的个数,类型,顺序至少有一个不同
-
重写
-
存在于父类和子类之间
-
方法名,参数,返回值都相等
-
被
final
修饰的方法不能被重写 -
问题:构造函数能否被重写?
不能,因为构造函数不会被继承
-
Object中常用方法
-
getClass()
获取对象对应的 Class 对象
-
finalize()
实例被垃圾回收器回收的时候触发的操作
-
hashCode()
-
equals()
问题:为什么需要 equals 和 hashcode 保持一致?
-
wait() / notfiy()
-
clone()
clone()
属于浅拷贝,且调用方法必须让类实现Clonable
接口-
问题:浅拷贝和深拷贝的区别?
浅拷贝对于对象属性并不会拷贝对象,而会拷贝引用指向原对象
深拷贝拷贝对象属性时会拷贝一份新的对象
-
问题:如何实现深拷贝?
使用序列化可以实现深拷贝
-
String类
常用的方法
length()
charAt()
toCharArray()
equals()
indexOf()
subString()
startsWith()
toLowerCase()/toUpperCase()
String
特点:被final
修饰,每次修改数值都会重新生成String
类
StringBuilder
特点:使用建造者模式创建出来的对象,可以进行字符串的修改
StringBuffer
特点:线程安全
基本数据类型
- 数值型:byte,short,int,long
- 浮点型:float double
- 布尔型:boolean
- 字符型:char
关键字
final
- final修饰的类无法被继承
- final修饰的方法无法被重写,可以重载(被static修饰的方法同样无法被重写,但是子类可以存在一个同样的方法)
- final修饰的属性被赋值后不可以修改(被final修饰的属性必须在被使用前赋值)
static
-
变量
-
静态变量当且仅当在类初次加载时会被初始化
-
静态变量属于类,被所有的对象所共享
-
静态成员变量可以通过类直接访问
-
-
方法
-
静态方法,可以直接通过类名去访问
-
静态方法中不可以使用this和super,不可以直接访问对象的实例变量和实例方法,可以直接访问类的静态变量和静态方法
-
-
代码块
类加载时执行一次(初始化阶段)
权限修饰符
-
private
-
default
同包的类可以访问
-
protect
子类可以访问
-
public
全部都可以访问
JDK1.8特性
- 函数式接口
Lamdba
表达式steam
流Data
日期类optional
来防止空指针异常