前言
面向对象编程是一种程序设计思想,简称 OOP。它把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数。
OOP:Object Oriented Programming
面向对象的三大特征
- 封装:将对象的属性隐藏在对象内部,不允许外部直接访问,只提供一些可访问的方法操作某些属性。
- 继承:
- 子类拥有父类的属性和方法(包括私有)。但是子类无法访问私有属性和方法,仅仅是拥有。
- 子类可以对父类进行扩展。
- 子类可以用自己的方式实现父类的方法。
- 多态:多态具体表现为父类引用指向子类实例。
1 | /** |
多态的实现
本质上分为编译时多态(静态多态)和运行时多态(动态多态),重载就是动态多态的一个例子。
Java 实现多态需要满足 3 个条件:继承、重写和向上转型:
- 继承:多态中必须存在有继承关系的子类和父类。
- 重写:子类对父类中的某个方法进行重新定义,在调用这些方法时就会调用子类的方法。
- 向上转型:在多态中需要将子类对象赋给父类引用,这样该引用才既能可以调用父类的方法,又能调用子类的方法。
多态的特点:
- 多态不能调用“只在子类存在但是父类不存在”的方法。
- 对象类型和引用类型之间具有继承(类)/ 实现(接口)的关系。
- 引用类型变量发出的方法调用的到底是哪个类中的方法,必须在程序运行期间才能确定。
- 如果子类重写了父类的方法,真正执行的是子类覆盖的方法,否则执行的是父类的方法。
面向对象和面向过程的区别
面向过程:
- 优点:性能比面向对象高,因为类调用时需要实例化,开销比较大,比较消耗资源。
- 缺点:不容易维护、易复用、易扩展。
面向对象:
- 优点:易维护、易复用、易扩展。面向对象有封装、继承、多态性三个特性,所以可以降低系统的耦合性,使系统更加灵活和维护。
- 缺点:由于对象需要实例化,所以性能较面向过程很低。
Java 创建对象的方式
Java 中包含 4 种创建对象的方式:
- new 创建新对象;
- 反射机制;
- clone 机制;
- 序列化机制;
其中,前两者都需要显式调用构造方法,clone 机制需要注意浅拷贝和深拷贝的区别,序列化一般通过 Externalizable 或者 Serializable 来实现。
成员变量和局部变量的区别
- 语法形式:
- 成员变量属于类,局部变量属于代码块或方法。
- 成员变量可以被
public
、private
、static
等修饰符修饰,局部变量不可以。但是二者都可以被final
修饰。
- 存储方式:成员变量根据是否被
static
修饰判断是属于类还是实例。对象存在堆内存,局部变量存在栈内存。 - 生存时间:成员变量随着对象的创建而存在,局部变量随着方法的调用自动生成,随着调用结束而消亡。
- 默认值:成员变量会自动以类型的默认值赋值,而局部变量不会自动赋值。如果被
final
修饰,则都必须显式赋值。
对象引用和对象实体
- 对象实体:使用
new
关键字创建,存放在堆内存中。 - 对象引用:存放在栈内存中,指向对象实体。
一个对象引用可以指向 0 或 1 个对象;一个对象实体可以有 n 个引用指向它。
1 | // 一个对象实体可以有多个引用指向它 |
对象相等和引用相等
- 对象相等:比较内存中存放的内容是否相等。
- 引用相等:比较他们指向的内存地址是否相等。
不可变对象
不可变对象指对象一旦被创建,状态就不能再改变,任何修改都会创建一个新的对象,如 String、Integer及其它包装类。不可变对象最大优点是线程安全。可以创建一个包含可变对象的不可变对象,但是需要注意不能共享可变对象的引用,而是在数据变化时返回原对象的一个拷贝。
接口和抽象类的共同点和区别
共同点:
- 不能被实例化;
- 可以包含抽象方法;
- 可以有默认实现的方法,Java8 可以使用
default
关键字在接口中定义默认方法;
区别:
- 一个类只能继承一个类,但是可以实现多个接口;
- 接口强调约束类的行为,抽象类强调所属关系;
- 接口中的成员变量只能为
public
、static
、final
类型,不能被修改且必须有初始值。抽象类的成员变量默认default
,可以在子类中重新定义或重新赋值。