1. 面向对象的核心元素
类定义了对象的结构和行为,对象是类的实例;属性存储了对象的状态信息;方法定义了对象可以的操作。
1.1. 类(Class)
类(Class)是现实世界中某些具有共同属性和方法的对象的抽象,是创建对象的蓝图或模版。类可以包含数据成员(属性)和成员函数(方法),这些成员定义了对象的状态和行为。
1.2. 对象(Object)
对象(Object)是根据类创建的实例。每个对象都拥有类中定义有属性和方法。对象是类的实体,代表了现实世界中的个体。
1.3. 属性(Attribute)
属性(Attribute)是类中的变量,用于存储对象的状态信息。属性可以是私有的或公有的,它们定义了对象的特征,是对象静态的唯一性。
1.4. 方法(Method)
方法(Method)是类中的函数,定义了对象的行为。方法可以访问和修改对象的状态(属性),并且可以被对象调用以执行某些操作,是对象动态的唯一性。
2. 面向对象编程的交互概念
这里不局限于面向对象编程(OOP),部分还涉及面向服务的架构(SOA)。
2.1. 状态(State)
状态(State)是对象的属性值的集合,定义了对象在某个时刻的具体情况。状态可以影响对象的行为和方法的执行结果。
2.2. 行为(Behavior)
行为(Behavior)是对象所执行的动作或反应。在OOP中,通过对象的方法来实现。对象的行为是其对外部请求或内部状态的响应。
2.3. 实现(Implementation)
实现(Implementation)是指对象的的具体行为逻辑,即对象行为如何改变对象的状态等。
2.4. 消息(Message)
消息(Message)是对象间通信的一种机制。在OOP中,消息可以是方法调用,而在SOA中,消息可以是服务间的交互请求或响应。消息传递是分布式系统中组件间通信的常用方式。
2.5. 服务(Service)
服务(Service)是对象对外提供的一组功能或行为。在SOA中,服务是指通过媒介访问业务功能单元。
3. 面向对象的基本概念
3.1. 抽象(Abstract)
抽象(Abstract)是为了简化复杂问题的过程,通过识别和关注对象的关键特征来忽略哪些不重要的细节。抽象类不能被实例化的类,它通常包含抽象方法(没有实现的方法)。抽象类作用于其他类的基类,强制要求子类提供抽象的具体实现。
3.2. 封装(Encapsluation)
封装(Encapsluation)是将对象的状态(属性)和行为(方法)结合在一起的过程,同时限制对这些状态的直接访问。封装时使用访问修饰符(如private、public、protected)来隐藏对象的内部实现细节,只提供必要的接口给外部访问。
3.3. 继承(Inheritance)
继承(Inheritance)是一种代码复用的方式。它允许一个类(子类或者派生类)继承另一个类(父类或基类)的属性和方法。子类可以扩展或修改父类的行为,也可以添加新的属性和方法。
3.4. 多态(Polymorphis)
多态(Polymorphis)允许一个接口被不同对象以不同方式实现。多态可以通过方法重载(同一个类中多个同名方法,参数不同)和方法重写(子类重写父类的方法)实现。多态性会使得代码更加灵活,可以编写出更加通用的代码,而不必关心具体的类实现。
4. 面向对象编程的接口和抽象类
接口作为系统与外界交互的窗口,定义了系统承诺提供的服务。接口一旦定义,不宜随意修改,以避免对系统和调用者造成影响。
抽象类作为实现类和接口的中间层,提供规范性和部分实现功能。
4.1. 接口和抽象类概念
接口(Interface)是系统对外提供服务的抽象,由类访问的方法组成。
特征:
- 成员变量默认是public、static、final,且必须显示初始化。
- 方法默认都是public、abstract。
- 没有构造方法,不能被实例化。
- 可以继承多个其他接口。
- 类实现接口时,必须实现该接口的所有抽象方法,否则应定义为抽象类。
- 接口不允许直接创建接口的实例,但是允许定义具体实现接口类的引用变量(向上转型)。
抽象类(Abstract Class)是部分实现的类,不能被直接实例化。
特征:
- 可以包含抽象方法和具体方法。
- 可以有实例变量和静态变量,不限于public、static、final。
- 一个类只能继承一个抽象类。
4.2. 抽象类与接口的区别
- 定义方式:抽象类使用abstract class,接口使用interface。
- 继承限制:类继承单一抽象类,实现多个接口。
- 成员变量:接口的成员变量只能是public、static、final。
4.3. 抽象类与接口的联系
- 抽象类和接口都位于继承树的上层,都代表着系统的抽象层。
- 抽象类和接口都不能被实例化,但是可以当作引用类型定义。
- 抽象类和接口都能包含抽象方法,不必提供具体实现。
5. 面向对象编程的类实现和继承
类实现涉及类的具体行为和属性。
继承允许新类(子类)继承现有类(父类)的属性和方法,而方法涉及到重载或覆盖。
5.1. 方法重载与方法覆盖
方法重载(@OverLoad):
- 允许同一个类中有多个同名方法,只要它们的参数类型、个数、顺序至少有一项不同。
- 返回类型和访问修饰符可以不同,但这不构成重载。
方法覆盖(@Override):
- 子类覆盖父类中具有相同名称、返回类型和参数列表的方法。
- 返回类型必须与被覆盖的方法一致。
- 用于改变继承自父类的方法的行为。
5.2. 方法重载与方法覆盖的区别
- 参数签名:重载要求不同,覆盖要求完全一致。
- 返回类型:重载不限制,覆盖要求与被覆盖的方法一致。
- 使用范围:重载在同一类中,覆盖在子类和父类之间
- 次数限制:一个方法可以被多次重载,但在子类中只能被覆盖一次
5.3. 方法重载与方法覆盖的联系
- 两者都要求方法名相同。
5.4. super和this关键字
- this:引用当前对象的实例,用于访问当前类的成员变量或构造方法。
- super:引用父类的对象,用于访问父类的构造方法或成员。
两者都用于解决作用域冲突,使被屏蔽的方法或变量在当前上下文中可用。
6. 面向对象编程的类继承原则与实践
继承是提高代码的可重用性和系统的可扩展性的有效手段;
- 继承层次应控制在2-3层以内,避免过深的继承树,减少理解和维护的难度。
- 继承树顶层应为抽象层,如接口,以提高系统间的松耦合。
- 抽象层作为继承树的最上层,对外提供统一的接口。抽象层有助于系统间的解耦和服务的统一。
- 继承可能破坏封装性,子类可能不恰当地使用或修改父类的内部状态和行为。应谨慎使用继承,避免破坏封装性。
- 合理利用继承和多态性,同时考虑组合和接口/抽象类替代方案,可以增强代码的封装性、灵活性和可扩展性。
- 继承应该基于"是一个"(is-a)的关系,而不是"有一个"(has-a)的关系。避免过度使用继承,特别是在多层继承结构中。
评论区