Java程序设计中面向对象的相关概念
内容来源:Bruce Ecke 的 《On Java8》(事实上的《Java编程思想》第五版)
一、对象的描述
Grady Booch对对象的简介描述:一个对象有自己的状态、行为和标识。即对象有自己的内部数据(提供状态)、方法(产生行为),并彼此区分(通过标识区分,每个对象在内存中都有唯一地址)。
二、对象的五大特征
1.万物皆对象。
2.程序是一组对象,通过消息传递来告知彼此该做什么。
3.每个对象都有自己的存储空间,可容纳其他对象。
4.每个对象都有一种类型。
5.同一类所有对象都能接收相同的消息。
三、类型与接口
(1)Java数据类型
Java 语言的数据类型分为:基本数据类型和引用数据类型。
A.基本数据类型
基本数据类型包括三类共八种,分别是
字符类型:char
布尔类型:boolean
数值类型:byte(字节型)、short(短整型)、int(整型)、long(长整型)、float(单精度浮点型)和 double (双精度浮点型)
B.引用数据类型
引用数据类型建立在基本数据类型的基础上,包括 : [](数组)、class(类)和interface(接口)。
程序中使用关键字interface来定义接口,关键字class来引入新的类型。
C.Java中的Type
Type是Java 编程语言中所有类型的公共高级接口,是一个空接口。对基本数据类型、引用数据类型向上的抽象。
public interface Type {
default String getTypeName() { return toString(); } }
Type接口下共有4种实现,每一种”代表着Java中的一种类型
Type体系中类型的包括:原始类型(Class)、参数化类型(ParameterizedType)、数组类型(GenericArrayType)、类型变量(TypeVariable)、基本类型。
原始类型(Class),包含类、枚举、数组、注解等;Class是Type的一个实现类,属于原始类型,是Java反射的基础,对Java类的抽象。在程序运行期间,每一个类都对应一个Class对象,这个对象包含了类的修饰符、方法,属性、构造等信息。
参数化类型(ParameterizedType),就是我们平常所用到的泛型List、Map;
数组类型(GenericArrayType),并不是数组String[] 、byte[],而是带有泛型的数组,即T[] ;
类型变量(TypeVariable),泛型的类型变量,指的是List<T>、Map<K,V>中的T,K,V等值,实际的Java类型是TypeVariableImpl
基本类型,就是前面所述的三类八种基本数据类型。
(2)类、接口与对象
三者的关系:类描述对象的属性和方法。接口则包含类要实现的方法。
A.类(class)
Java中的类以class关键字声明,它是一种抽象的数据类型,是对所具有相同特征实体的抽象。
类是一个模板,描述一类对象的行为和状态,是具备某些共同特征的实体的集合。
B.接口(interface)
Java中的接口以interface来声明,是一个抽象类型,是抽象方法的集合。
Java接口是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能)。
C.对象
对象是类的一个具体的个体,它是实际存在的,对象是类的实例。
四、面向对象三大特性
1.封装
概念:将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问。
软件设计的原则是高内聚,每个对象的功能单一且高效。
访问修饰符与访问权限:
类中元素的访问权限:
(1)public(公开): 无论是谁,无论在哪,都可以访问和使用该元素。
(2)protected(受保护):类似于private,区别是子类可以访问protected成员,不可以访问private成员。protected也提供包访问权限。
(3)default(默认):包访问权限,可以被同一包(库组件)中其他类的成员访问。包访问权限把相关类聚集到一个包下,以便他们能轻易互相访问。
(4)private(私有):除了类本身和类内部的方法,外界无法直接访问该元素。
复用:组合与聚合关系
组合(Composition):经常用来表示拥有关系(has-a),整件拥有部件的生命周期。例如汽车拥有引擎。UML中用实心菱形箭头表示。
2.继承
继承是类与类的一种关系,是一种“is-a”的关系。
如果继承一个类而不做任何变化,没有什么意义。有两种方法可以让派生类与基类不同:一种是在派生类中添加新方法(基类无法访问新添加的方法,这种关系称为is-like-a);另一种是改变现有基类方法的行为,即覆盖基类的方法(可以用一个派生类对象完全替代基类对象,这种纯粹替代关系是is-a)。
方法覆盖就是方法重写。改变现有基类的行为,即在派生类中重新定义这个方法,被称为覆盖(overriding)。覆盖(重写)的方法返回值类型、方法名、参数类型及个数都与父类继承的方法相同。
3.多态
多态是同一个行为具有多个不同表现形式或形态的能力。多态就是同一个接口(或抽象类),使用不同的实例而执行不同操作。
多态消除类型之间的解耦,解耦做什么和怎么做。
多态把很多派生自同一个基类的类型当做同一类型处理,使一段代码可以无差别地运行在所有不同类型上。
多态体现在父类引用变量可以指向子类对象。使用多态后的父类引用变量调用方法时,会调用子类重写后的方法。
五、类型之间的六种的关系
来源:博客园 千里之行,始于足下 https://www.cnblogs.com/ylq1990/p/8473041.html
1.泛化(Java中用来表示继承)
一种一般与特殊、一般与具体之间的关系。UML图中用实线空心三角形箭头表示。
2.实现
一种类与接口的关系,表示类是接口所有特征和行为的实现。UML中用虚线空心三角形箭头表示。
3.依赖(方法参数需要传入另一个类的对象)
一种使用的关系,即一个类的实现需要另一个类的协助。方法参数需要传入另一个类的对象,就表示依赖这个类。
UML用虚线箭头表示,指向被依赖的类。
4.关联(一个类的全局变量引用了另一个类)
这种关系比依赖更强、不存在依赖关系的偶然性、关系也不是临时性的,一般是长期性的。一个类的全局变量引用了另一个类,就表示关联了这个类。
5.聚合(has-a,整体与个体可以具有各自的生命周期)
聚合关联关系的一种特例,是强的关联关系。聚合是整体和个体之间的关系,即has-a的关系,整体与个体可以具有各自的生命周期,部分可以属于多个整体对象,也可以为多个整体对象共享。程序中聚合和关联关系是一致的,只能从语义级别来区分。
6.组合(contains-a,部分与整体的生命周期一致)
组合也是关联关系的一种特例。组合是一种整体与部分的关系,即contains-a的关系,比聚合更强。部分与整体的生命周期一致,整体的生命周期结束也就意味着部分的生命周期结束,组合关系不能共享。程序中组合和关联关系是一致的,只能从语义级别来区分。
UML用尾部为实心菱形的实线箭头表示,箭头由部分指向整体。
六、面向对象设计六大原则
1.单一职责原则SRP(Single Responsibility Principle)
一个类是对一组相关性高的函数、数据的封装。完全不一样的功能不应该放在一个类中。也适用于方法,功能单一,颗粒度要细。
(封装性)
2.开放封闭原则OCP(Open - Close Principle )
对修改封闭、对扩展开放。
(继承的原则)
3.里氏转换原则LSP (the Liskov Substitution Principle)
父类能出现的地方子类也可以出现。
(多态性)
4.依赖倒置原则DIP(the Dependency Inversion Principle )
高层模块和底层模块都依赖于抽象类或接口,而不依赖细节。依赖注入模式是该原则的一个实现。
(面向抽象或接口编程)
5.接口分离原则ISP(the Interface Segregation Principle )
客户端不依赖它不需要的接口。接口的设计尽可能粒度小,组合使用。
6.迪米特法则LoD(Law of Demeter)
最少知识原则,只与直接的朋友通信,门面模式(Facade)和中介模式(Mediator),都是迪米特法则应用的例子。谨慎使用Serializable,尽量降低一个类的访问权,尽量降低成员的访问权限。
(只公开必要的访问和操作)