java编程思想

来源:互联网 发布:巨人网络社会招聘 编辑:程序博客网 时间:2024/06/08 15:30

程序设计其实是对复杂性的管理:待解决问题的复杂性,以及用来解决该问题的工具的复杂性。java的设计目标就是为程序员减少复杂性。减少开发健壮代码所需的时间以及困难。

1、抽象过程

所有编程语言都提供抽象机制。可以认为,人们所能够解决问题的复杂性直接取决于抽象的类型和质量。所谓的“类型”是指“所抽象的是什么?”。

2、一切都是对象

每种语言都有自己的操纵内存中元素的方式。有时候程序员必须注意将要处理的数据是什么类型。是直接操纵元素,还是用某种基于特殊语法的间接表示来操纵对象。所有这一切在java里都得到了简化。一切都被视为对象,因此可采用单一固定的语法。尽管一切都看作对象,但操纵的标识符实际上是对象的一个“引用”(reference)。可以将这一情形想象成用遥控器(引用)来操纵电视机(对象)。

3、创建、存储对象

程序运行时,对象是怎样进行放置安排的呢?特别是内存是怎样分配的呢?有5个不同的地方可以存储数据:

1)寄存器:这是最快的存储区,因为它位于不同其他存储区的地方——处理器内部。但是寄存器的数量极其有限,所以寄存器根据需求进行分配。你不能直接控制,也不能在程序中感觉到寄存器存在的任何迹象(c和c++允许你向编译器建议寄存器的分配方式)。

2)堆栈:位于通用ram(随机访问存储器)中,通过堆栈指针可以从处理器那里获得直接支持。堆栈指针向下移动,则分配新的内存;若向上移动,则释放那些内存。这是一种快速有效的分配存储方法,仅次于寄存器。创建程序时,java系统必须知道存储在堆栈内所有项的确切生命周期,以便上下移动堆栈指针。这一约束限制了程序的灵活性,所以虽然某些java数据存储于堆栈中——特别是对象引用,但是java对象并不存储于其中。

3)堆:一种通用的内存池(也位于ram区),用于存放所有的java对象。堆不同于堆栈的好处是:编译器不需要知道存储的数据在堆里存活多长时间。因此,在堆里分配存储有很大的灵活性。当需要一个对象时,只需用new写一行简单的代码,当执行这行代码时,会自动在堆里进行存储分配。当然,为这种灵活性必须要付出相应的代价:用堆进行存储分配和清理可能比用堆栈进行存储分配需要更多的时间。

4)常量存储:常量值通常直接存放于程序代码内部,这样做是安全的,因为它们永远不会被改变。有时,在嵌入式系统中,常量本身会和其他部分隔离开,所以在这种情况下,可以选择将其存放在rom(只读存储器)中。

5)非ram存储:如果数据完全存活于程序之外,那么它可以不受程序的任何控制,在程序没有运行时也可以存在。其中两个基本的例子是流对象和持久化对象。在流对象中,对象转化成字节流,通常被发送给另一台机器。在“持久化对象”中,对象被存放于磁盘上,因此,即使程序终止,它们仍可以保持自己的状态。这种存储方式的技巧在于:把对象转化成可以存放在其他媒介上的事物,在需要是,可恢复成常规的,基于ram的对象。java提供了对轻量级持久化的支持,而诸如JDBC和hibernate这样的机制提供了更加复杂的对在数据库中存储和读取对象信息的支持。

在java中,基本类型可以不用new创建变量,而是创建一个并非是引用的“自动”变量。这个变量直接存储“值”,并置于堆栈中,因此更加高效。

4、static关键字

通常来说,当创建类时,就是在描述那个类的对象的外观与行为。除非用new创建那个类的对象,否则,实际上并未获得任何对象。执行new来创建对象时,数据存储空间才被分配,其方法才供外界调用。

有两种情形用上述方法是无法解决的。一种情形是,只想为某特定域分配单一存储空间,而不去考虑究竟要创建多少对象,甚至根本就不创建任何对象。另一种情形是,希望某个方法不会与包含它的任何对象关联在一起。也就是说,即使没有创建对象,也能够使用这个方法。

通过static关键字可以满足这两方面的需要。当声明一个事物是static时,也就意味着这个域或方法不会与包含它的那个类的任何对象实例关联在一起。所以,即使从未创建某个类的任何对象,也可以调用其static方法或访问static域。

5、初始化

类成员变量可以不用初始化,编译器会给它们赋于默认值,boolean默认值为false,引用默认值为null,char、byte、short、int、long的默认值为0,float、deuble的默认值为0.0。方法内使用变量前一定要先初始化。

在类的内部,变量定义的先后顺序决定了初始化的顺序。即使变量定义散布于方法定义之间。它们仍旧会在任何方法(包括构造器)被调用之前得到初始化。

无论创建多少个对象,静态数据都占用一份存储区域。static关键字不能应用于局部变量,因此它只能作用于域。如果一个域是静态的基本类型,且也没有对它进行初始化,那么它就会获得基本类型的标准初值;如果它是一个对象引用,那么它的默认初始化值就是null。

静态初始化只有在必要时刻才会进行,被初始化之后,静态对象不会再次被初始化。

初始化的顺序是先静态对象而后是“非静态”对象。

6、数组初始化

编译器不允许指定数组的大小。为了给数组创建相应的存储空间,必须写初始化表达式。对于数组,初始化动作可以出现在代码的任何地方,但也可以使用一种特殊的初始化表达式,它必须在创建数组的地方出现。这种特殊的初始化是由一对花括号括起来的值组成的。

数组的创建是在运行时刻进行的。此外,数组元素中的基本类型数值会自动初始化成空值(对于数字和字符,就是0;对于布尔类型,是false)。

7、多态

在面向对象的程序设计语言中,多态是继数据抽象(封装)和继承之后的第三种基本类型。“封装”通过合并特征和行为来创建新的数据类型。“实现隐藏”则通过细节“私有化”把接口和实现分离开来。而多态的作用是消除类型之间的耦合关系。多态是一项让程序员“将改变的事物与未变的事物分离开来”的重要技术。

8、方法调用绑定

将一个方法调用同一个方法主体关联起来称作绑定。若在程序执行前进行绑定,叫做前期绑定。在运行时根据对象的类型进行绑定。后期绑定也叫做动态绑定或运行时绑定。java中除了static方法和final方法(private方法属于final方法)之外,其他所有的方法都是后期绑定。这意味着通常情况下,我们不必判定是否应该进行后期绑定——它会自动发生。

9、构造器调用顺序

1)调用基类构造器。这个步骤会不断地反复递归下去,首先是构造器这种层次结构的根,然后是下一层导出类,等等,直到最底层的导出类。在其他任何事物发生之前,将分配给对象的存储空间初始化成二进制的零。

2)按声明顺序调用成员的初始化方法。

3)调用导出类构造器的主体。

10、OOP三大基本特性

1)封装,也就是把客观事物封装成抽象的类,并且可以把自己的属性和方法只让可信的类操作,对不可信的进行信息隐藏。

2)继承,是指这样的一种能力,它可以使用现有类的所有功能,并在无需重新编写原来类的情况下对这些功能进行扩展。

3)多态,是指一个类实例的相同方法在不同的情形有不同的表现形式。具体来说就是不同的实现类对公共接口有不同的实现方式,但这些操作可以通过相同的方式(公共接口)进行调用。

11、OOD七大原则

1)开-闭原则

Open-Close Principle(OCP)。开,指的是对扩展开放,即要支持方便的扩展;闭,指的是对修改关闭,即要严格限制对已有内容的修改。开-闭原则是最抽象也是最重要的OOD原则。简单工厂模式、工厂方法模式、抽象工厂模式中都提到如何通过良好的设计遵循开-闭原则。

2)里氏替换原则

Liskov Substitution Principle(LSP)。该原则规定子类必须能够替换其父类,否则不应当设计为其子类。换句话说,父类出现的地方,都应该能由其子类代替。所以子类只能去扩展基类,而不是隐藏或者覆盖基类。

3)依赖倒置原则

Dependence Inversion Principle(DIP)。指设计和实现要依赖于抽象而非具体。一方面抽象化更符合人的思维习惯;另一方面,根据里氏替换原则,可以很容易将原则的抽象替换为扩展后的具体,这样可以很好的支持开-闭原则。

4)接口隔离原则

Interface Segration Principle(ISP)。将大的接口打散成多个小的独立的接口。由于Java类支持实现多个接口,可以很容易的让类具有多种接口的特征,同时每个类可以选择性地只实现目标接口。

5)单一职责原则

Single Responsibility Principle(SRP)。指不要存在多于一个导致类变更的原因,是高内聚低耦合的一个体现。

6)迪米特法则/最少知道原则

Law of Demeter or Lest Knowledge Principle(LoD or LKP)。指一个对象要尽可能少的去了解其他对象,从而实现松耦合。如果一个类的职责过多,由于多个职责耦合在一起,任何一个职责的变更都可能引起其他职责的问题,严重影响了代码的可维护性和可重用性。

7、合成/聚合复用原则

Composite/Aggregate Reuse Principle(CARP/CRP)。如果新对象的某些功能在别的已经创建好的对象里面已经实现,那么应当尽量使用别的对象提供的功能,使之成为新对象的一部分,而不要在重新创建。新对象可通过向这些对象的委派达到复用已有功能的效果

原创粉丝点击