复活JAVA1

本章主要目的介绍对象的概念,在程序设计当中,设计一个好的对象,是好程序的架构第一步。

我想到一个问题,就是UML,让我头疼的家伙,好多书籍上都用这个来画,我是真看不懂。恶补吧

以下是仔细研读这些话,从而领会到的精神。 (英文应该领悟的更透彻,中文又属于译者的领悟了)

所有编程语言的最终目的都是提供一种“抽象”方法

比如 汇编是对机器语言的抽象,C是对汇编的抽象,C++是对C的抽象,C#是对C++的抽象。

JAVA是一门OOP语言,即面向对象程序设计语言。那么要理解什么是纯粹的对象概念。请仔细跟我研读,以下5句话。

(1) 所有东西都是对象。可将对象想象成一种新型变量;它保存着数据,但可要求它对自身进行操作。理论上讲,可从要解决的问题身上提出所有概念性的组件,然后在程序中将其表达为一个对象。

对象保存数据,本身可操作。比如就是 “女人” 这个对象。描述形容一个女人你可能诸如使用《小薇》歌词里面的,“有一个美丽的小女孩,她的名字叫做小薇,她有双温柔的眼睛”,那么 名字、眼睛 都是 “女人” 这个对象的数据,也就是属性、成员变量(用于保存数据)。如何理解可以自身进行操作呢,有一个很鲜活的例子,军训有的女生来“大姨妈”了,教官就让她们可以不训练。大姨妈这个动作是每个月出现一次,周而复始是它的规律。是教官教会,亦或是告诉该女生要来大姨妈么,肯定不是的。是女生特有的一种行为(方法) 这个方法比较特殊,只能自己调用,对外仅仅提供告知他人的功能。“我处于大姨妈时期,请保护我” ,OK,明白了。(2) 程序是一大堆对象的组合;通过消息传递,各对象知道自己该做些什么。为了向对象发出请求,需向那个对象“发送一条消息”。更具体地讲,可将消息想象为一个调用请求,它调用的是从属于目标对象的一个子例程或函数。

程序是对象的集合,通过消息来通知对象该做哪些事情。比如“社会” 这个程序,由好多个对象“人”组成。人与人之间也是通过消息来沟通交流,告知对方你要做什么,做完之后有个反馈等等。那有朋友说了,你没解释清楚,人与人之前消息的驱动是如何发起的,源头是哪里。 举个例子,你老板通知你讲写一个某某企业OA。你“对象”开始执行编程方法,然后返回值(OA程序)给老板,老板给客户。 那源头应该是该企业向老板发起了“你给我做OA,我给你钱。”这个消息请求。才有了接下来我编程方法的执行。那你又问了,那谁驱动企业的,为啥做OA。 这个就比较复杂了,但是你要注意到,这维系企业,老板,我。 三者是通过“钱”这个对象的。所以钱就好比联系的枢纽,但它肯定不是消息。额,说的有点乱了。可以通过人类发展史来理解理解。从原始社会的平等。到奴隶社会的压迫。到封建社会的禁锢。到资本社会的人权。到共产主义的平等。是不是绕了一大圈满足了人性的所需之后又平等了。所以我很不理解《三字经》上说的,“人之初,性本善”。(3) 每个对象都有自己的存储空间,可容纳其他对象。或者说,通过封装现有对象,可制作出新型对象。所以,尽管对象的概念非常简单,但在程序中却可达到任意高的复杂程度。

这个其实很好理解。一个 H2o是个肉眼无法看到的分子,千千万万可以组成一滴水,水又可以根据状态分为气态,液态,固态。不同形态再由其千千万万个组成,又会被赋予不同的名字,川江海。复杂度越来越高,另外里面可能住着很多种类的生物等等。

(4) 每个对象都有一种类型。根据语法,每个对象都是某个“类”的一个“实例”。其中,“类”(Class)是“类型”(Type)的同义词。一个类最重要的特征就是“能将什么消息发给它?”。

对象属于实际的,类相当于概念,是对对象的抽象。比如说,男人,女人,小孩,这些对象,都属于“人”这一类型。每个类型,都会有突出的特点,否则不应该单独划分,也就是总是有一个维度来区分。比如男和女。老和少。

(5) 同一类所有对象都能接收相同的消息。这实际是别有含义的一种说法,大家不久便能理解。由于类型为“圆”(Circle)的一个对象也属于类型为“形状”(Shape)的一个对象,所以一个圆完全能接收形状消息。这意味着可让程序代码统一指挥“形状”,令其自动控制所有符合“形状”描述的对象,其中自然包括“圆”。这一特性称为对象的“可替换性”,是OOP最重要的概念之一。

比如男人,女人,小孩。都可以接收,你吃饭吧,这种消息。虽然吃的不一样,但是吃饭。是人具有的方法,确切说是每个人都具有的方法。

上面的圆属于形状的具体对象,形状Shape属于类。

如何在“问题空间”(问题实际存在的地方)的元素与“方案空间”(对实际问题进行建模的地方,如计算机)的元素之间建立理想的“一对一”对应或映射关系。 ?

建模个人认为是最关键最难的部分,因为建模画UML时,就看你的功底和经验。这种是长期累积的结果,必然的。

接下来往下继续看…

继承

这个概念出现了,非常非常重要概念。通过extends来实现继承关系,继承的主要应用场景是:“当我们有一种非常复杂的数据类型时,我们要实现与之略有不同的功能,我们最好的办法就是不完全“克隆”即继承。” 另外有一点,当超类发生变化时,子类亦或发生相同的变化。这样的好处是,当程序某个函数统一处理某业务,该业务总体发生变化,只要在父类里改变即可。例如友盟的事件统计,在Activity的onResume() onPause() 实现方法即可,其他Activity若是继承它,则无需再次写该方法。

继承的最大好处在于,子类复制了基础类的接口。也就是说,向基础类对象发送的消息,同样可以发送给子类,因为他们的类型相同。但同时引起一个问题,“发送给该类一个消息,必须有方法去执行” 有时候,父类的抽象方法太多,导致子类复杂程序增加,所以父类每个抽象方法都要尽量合理。因为抽象方法是必须要子类实现的。若是一般方法子类可以实现,也可以不实现。当有消息发送时,按是否实现了该方法而让程序做判断处理。还有一点,子类可以增加新的函数来区别于父类。

关于这个有一个编程技巧。

比如父类有一个方法

public void draw(Shape s){System.out.println("draw : "+s.getClass().getName());}

这个方法是画自身,传给什么对象就绘制什么。比如这么使用

public static void main(String[] args) {Shape s = new Shape();s.draw(new Circle());s.draw(new Square());s.draw(new Triangle());}

输出结果是

draw : Circledraw : Squaredraw : Triangle

骚年,想象下是不是Android的某些你不太明白的地方就是这么设计的。

此时,一个Circl的句柄发给了接收Shape句柄的函数。凡是Shape类型的,都会自动的执行里面的方法而不报错。我们管这个叫做“Upcasting” 向上转型。基础类位于顶部,衍生类位于下部。子类向父类类型转换。是没有错误的,不会出现类型错误!

注意,这个方法并没有说做,if你是Circle 你这么做,if你是个Square你那么做,这样每次新增一个形状比如梯形,都要修改父类的Draw()显然很不合理,它就是说,你是Shape,那么就Draw,并且自己控制所有细节把。 这时候Draw方法会写的很通用。

对象的创建和生命周期

1.数据存放在哪? 2.存活多久?

解决的办法各异

1) C++ 认为程序的执行效率是最重要第一个问题。所以它允许程序员做出选择,存储以及存在的时间是编写程序规定的,以获得最快的运行速度。一般可以把对象放到堆栈或静态存储区域。这种方法提供了执行效率但是同时失去了灵活性,必须要事先知道对象的数量、存在时间、类型。

2)内存池 亦或叫 堆 。 在里面动态的创建对象,除非程序运行,否则不知道数量和存活多久,类型等等。由于存储空间是运行时动态的进行的。所以内存堆里创建对象的时间就很长,又因为是动态计算的所以时间必然很久。但是更大的灵活性是常规编程至关重要的问题,所以JAVA出现并且有了垃圾回收器。你要允许垃圾回收器带来的额外开销。

C++ 更加灵活,允许我们决定是在写程序时创建对象,还是运行期间创建。但垃圾回收期带来的额外开销并不符合C++语言的设计宗旨。所以未能包括到C ++中,但是有C++可以使用一些公司开发的垃圾回收产品。

我们可以失望,但不能盲目。

复活JAVA1

相关文章:

你感兴趣的文章:

标签云: