面向对象基础
1.面向对象和面向过程的区别?
两者的主要区别在于解决问题的方式不同:
- 面向过程把解决问题的过程拆成一个个方法,通过一个个方法的执行解决问题。
- 面向对象会先抽象出对象,然后用对象执行方法的方式解决问题。
另外,面向对象开发的程序一般更易维护、易复用、易扩展。
2.对象的相等和引用相等的区别?
- 对象的相等一般比较的是内存中存放的内容是否相等。
- 引用相等一般比较的是他们指向的内存地址是否相等。
3.如果一个类没有声明构造方法,该程序能正确执行吗?
构造方法是一种特殊的方法,主要作用是完成对象的初始化工作。
如果一个类没有声明构造方法,也可以执行。因为一个类即使没有声明构造方法也会有默认的不带参数的构造方法。如果我们自己添加了类的构造方法(无论是否有参),Java就不会添加默认的无参数的构造方法了。
这也是为什么我们在创建对象的时候后面要加一个括号(因为要调用无参的构造方法)。如果我们重载了有参的构造方法,记得都要把无参的构造方法也写出来(无论是否用到),因为这可以帮助我们在创建对象的时候少踩坑。
4.构造方法有哪些特点?是否可被 override?
构造方法特点如下:
- 名字与类名相同。
- 没有返回值,但不能用 void 声明构造函数。
- 生成类的对象时自动执行,无需调用。
构造方法不能被 override(重写),但是可以overload(重载),所以你可以看到一个类中有多个构造函数的情况。
面向对象三大特征
5.封装
封装是把一个对象的信息(属性)隐藏在对象内部,不允许外部对象直接访问。但是也可以提供一些方法来让外界操作对象的属性。
6.继承
继承其实就是在父类的基础上定义新的子类,子类拥有父类的所有属性和方法,但是子类不能访问父类中的私有属性和方法。子类可以拥有自己的属性和方法,也可以重写父类的方法。
7.多态
多态其实就是一个对象有多种形态。比如有一个动物类,它有一个叫做makeSound()
的方法,现在有狗和猫两个类继承了动物类,并都重写了makeSound()
方法,那么狗调用这个函数就会发出“汪汪”的声音,猫就是“喵”的声音。多态其实就是同一个方法调用,根据对象的不同,会有不同的行为。
8.接口和抽象类有什么共同点和区别?
共同点:
- 都不能被实例化
- 都可以包含抽象方法
- 都有默认实现方式
区别:
- 接口主要用于对类的行为进行约束(为类服务),你实现了某个接口就具有了对应的行为
- 一个类只能继承一个类,但是可以实现多个接口
- 接口中的成员变量只能是
public static final
类型的,不能被修改且必须有初始值,而抽象类的成员变量默认default,可在子类中被重新定义,也可被重新赋值
9.深拷贝和浅拷贝区别了解吗?什么是引用拷贝?
浅拷贝: 在堆上创建一个新的对象(区别于引用拷贝的一点),拷贝对象和原对象共用同一个内部对象的地址。
深拷贝: 完全复制整个对象,包括这个对象所包含的内部对象。
引用拷贝: 引用拷贝就是两个不同的引用指向同一个对象。(浅拷贝基础上)
Object
10.== 和 equals() 的区别?
- 对于基本数据类型来说,== 比较的是值。
- 对于引用数据类型来说,== 比较的是对象的内存地址。
equals()
不能用于判断基本数据类型的变量,只能用来判断两个对象是否相等。equals()方法存在于Object类中,而Object类是所有类的直接或间接父类,因此所有的类都有equals()方法。
String
11.String、StringBuffer、StringBuilder 的区别?
是否可变:
- String不可变:String保存字符串的数组被
final
修饰而且为私有的(被final
关键字修饰的类不能被继承,修饰的方法不能被重写,修饰的变量不能修改),所以String类不能被继承,而且String类没有提供修改字符串的方法。 - StringBuffer和StringBuilder继承的父类中提供了修改字符串的方法,比如
append
方法
安全性:
- String不可变,线程安全
- StringBuffer加了同步锁,线程安全
- StringBuilder,非线程安全
性能:
- 由于String是不可变的,所以每次对 String类型进行改变的时候,都会生成一个新的String 对象,会消耗内存
- StringBuffer每次都会对StringBuffer对象本身进行操作,不会生成新的对象,所以在进行字符串操作时会更高效
- StringBuilder会比StringBuffer性能更好一点,但是它是非线程安全