`
manwuyuantao
  • 浏览: 7766 次
  • 性别: Icon_minigender_1
  • 来自: 北京
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

Java编程语言-面向对象

 
阅读更多

 

Java程序中,万事万物皆是对象,即使是Java程序本身,也是一个对象。那么我们之前学习的面向过程与面向对象又有那些不同之处呢,或者说,面向对象又有那些优点呢?下面我们就分析一下它们之间的关系。

面向对象相对于面向过程较显著的优势莫过于可扩展性以及可维护性。在我们的软件开发过程中,开发人员与客户需要不断的沟通,而客户的需求也在不断的变化,在这个时代,软件变化的速度之快大过了我们的想象。如果采用面向过程的方法来进行软件的开发,当用户需求发生变化时,比如奥求修改现有软件功能的实现方式,或者追加新的功能的时候,就需要把整个代码,从上到下的进行修改,有时候甚至整个软件系统的设计被完全推翻。小的软件无所谓,但是大型的项目的话,需要付出的就不是那么一点时间了,而是要重新写一个软件,可想而知,面向过程的麻烦之处。

相比之下,面向对象所提供的可扩展性保证了当软件必须增加新的功能的时候,能够在现有的软件系统结构基础上,方便的添加新的系统组件,而不需要大动干戈的修改整个软件系统的现有结构。可维护性则是保证了当用户需求发生变化的时候,只需要修改局部的代码就可以了,而不会牵一发而动全身。

除了可扩展性和可维护性外,面向对象还具有可重用性,这样就减少了软件中的代码重复,在可重用性方面在下面我讲详细讲解,这里就不多说了。

相对于团队来说,使用面向对象思想编程,可以很容易的把项目具体工作分离,分工合作,同时开发,从而降低了开发成本,提高了开发效率。

在面向对象程序中,有许多公共的数据放在接口里面或者其他的地方。这样同一个团队中开发就比较方便了,当然这也是一个代码的重用。

当然,面向过程也不是一无是处,面向过程也有它的优点。比如在同一个问题,面向对象的执行速度不如面向过程程序。在某些对速度要求极高的特殊场合,用面向过程就比较好,我们常说的,时间就是金钱,那么我们的软件执行速度决定了我们能挣多少钱,每一秒钟都是钱,再把这些时间加在一起,那么我们所损失的金钱就很客观了。

说了这么多,下面进入我们的主题吧。在这一阶段的Java oop中我们主要学习了oop的三大特征、异常处理以及API

在我们学习面向的过程中,三大特征的运用是很多的,其中封装就用的更多了,几乎每个项目中都必须用到封装。异常呢,异常是无法避免的,当然我们用的也是比较多的,因为我们要考虑程序的安全性,以及运行效果等多方面。API专业的说就是应用程序接口,如果想做好的项目,这个API是必不可少的。下面我就详细讲解各个板块的内容。

1 .面向对象的三大特征:

上面我们讲过了面向对象的优点,可维护性,可扩展性,可重用性。但是这些都体现在Java面向对象的什么地方呢?那就是面向对象的三大特征了:封装,继承和多态。

1.1封装

 

封装定义:为实现各式各样的数据传送,将被传送的数据结构映射进另一种数据结构的处理方式。

按照我的理解封装就是把不需要用户了解的东西打包起来,从而达到一个相对安全的数据安全性。在现在的软件行业中,存在很大的竞争性,如果你的软件没那么大的安全级别,那你的软件只能被淘汰。

封装的目的就是增强安全性和简化编程,为什么说简化编程呢,其实,这里面用到的是一个代码的重用。那么封装是如何实现的呢?其实封装就是把原来公共属性给私有化了。把属性私有化后只能在类内部使用,而在类中我们又定义了其属性的封装方法,这样既避免了代码的可视性,又增加了数据的坚固性。当然封装不只是作用在属性上,在类中我们依然可以,我们只需定义接口,用到时候只需实现接口就可以了。

1.2继承

 

继承是指一个对象直接使用另一对象的属性和方法。在定义的基础上我们可以这么理解,所谓继承就是子承父业,也就是说,当儿子的在父亲去世后可以继承父亲的财产。

继承在面向对象中呢,就是说,一个子类只能直接继承一个父类,一个父类可以拥有多个子类。也就是说一个人只能有一个父亲,但是一个父亲却可以有多个儿子。还有一点就是子类和父类的关系必须是同一类,否则无法继承。这句话怎么理解呢,就是说,儿子和父亲的关系前提条件必须都是人,这样说可能不好听,但是确实是这样一个事实。比如说,花是植物,你不能把它归到动物里边。

继承最大的作用就是代码的重用,子类可以使用父类中publicprotected修饰的方法和属性。Java是不支持多继承的,单继承使Java的继承关系很简单,便于管理程序,接口刚好弥补了继承的缺点。如果没有继承的话,那么我们写代码只能用最原始的方法,复制粘贴,这无疑是增加了代码的冗余,更加的不便于管理。

继承所表达的就是一种对象类之间的相交关系,它使得某类对象可以继承另外一类对象的数据成员和成员方法。若类B继承类A,则属于B的对象便具有类A的全部或部分性质(数据属性)和功能(操作),我们称被继承的类A为基类、父类或超类,而称继承类BA的派生类或子类。

继承是面向对象编程技术的一块基石,因为它允许分等级层次的类,运用继承,你能够创建一个通用类,它定义了一系列相关项目的一般特性。该类可以被具体的类继承,每个具体类都增加一些自己特有的东西。

 

1.2多态

多态按字面的意思就是多种形态。在面向对象语言中,接口的多种不同实现方式即为多态。但是多态是基于继承实现的,其实通俗的讲,多态就是一个方法,多种实现的方式。多态和重载有些许的相似之处,重载是方法名必须相同,但是参数不一样包括参数顺序的不同。而多态则是重写父类的方法,参数也是用的对象,参数的个数不允许改变。

多态对我们的编程有什么好处呢?总的来说可以归纳为5点:

1)可替换性,多态对已存在的代码具有可替换性。我们只需要改变其中的对象就可以替换掉不用的对象,相对于开发来说,更加的方便。

2)可扩充性,多态对代码具有可扩充性,增加新的子类不影响已存在类的多态性、继承性,以及其他特征的运行和操作。实际上新加子类更容易获得多态功能。

3)接口性,多态是超类通过方法签名,向子类提供了一个共同的接口,由子类来完善或者覆盖它而实现的。

4)灵活性,它在应用中体现了灵活多样的操作,提高了使用效率。

5)多态贱货对应用软件的代码编写和修改过程,尤其在处理大量对象的运算和操作时,这个特点尤为突出和重要。

 

面向对象的三大特征是相辅相成的,封装继承可以单独使用,唯独多态必须在继承的基础上才能使用。三大特征的使用都是为了增加代码的安全性、重用性以及可维护性。

在讲完了面向对象的三大特征之后,有必要了解一下抽象类和接口。

抽象类

抽象类是不完整的,并且它只能用作基类。抽象类不能直接被实例化,并且对抽象类使用new运算符是编译时错误。虽然一些变量和值在编译时的类型可以抽象的,但是这样的变量和值必须或者为null,或者含有对非抽象类的实例的引用。抽象类里面允许含有非抽象成员。但是抽象类不能被密封。如果抽象类被密封了,那么抽象类也就失去了它的唯一的作用,因为抽象类不能被实例化,所以它的存在只能是被继承。这又存在了一个继承的关系,抽象类里面有抽象方法,在继承的时候必须实现其父类的抽象方法,否则编译是不通过的。当父类已有实际功能的方法时,既是非抽象方法。该方法在子类中可以不必实现,直接引用的方法,子类也可以重写该父类的方法。

抽象类中可以有抽象方法,也可有非抽象方法,但是有抽象方法的类必须是抽象类。抽象类只关心它的子类是否具备某种功能,并不关心其功能的具体实现,具体的行为由子类具体实现,也就是说,在定义抽象方法时,不用实现其具体实施。

接口

接口的出现为继承为Java弥补了很大的缺陷,因为继承是单继承,而有时候则需要多继承,接口的出现为软件编程减少了很大的困难。在接口里面可以定义常量,也可以定义方法,但是这些方法都必须是抽象的方法,接口里面不允许有具体的实现。

接口是一种规范,它的作用也是为了继承,没有继承就没有它的存在。一个类可以实现多个接口,但是必须把接口里面的方法都实现。接口中的方法,常量都必须是public的,因为它是用来继承的,如果不是public的话,这个接口就没有了存在的意义了。

 

抽象和接口的不同之处

 

抽象类与接口紧密相关。然接口又比抽象类更抽象:

1)类可以实现无限个接口,但仅能从一个抽象(或任何其他类型)类继承,从抽象类派生的类仍可实现接口,从而得出接口是用来解决多重继承问题的。

2)抽象类当中可以存在非抽象的方法,可接口不能且它里面的方法只是一个声明必须用public来修饰没有具体实现的方法。

3)抽象类中的成员变量可以被不同的修饰符来修饰,可接口中的成员变量默认的都是静态常量(static final)。

4)这一点也是最重要的一点本质的一点"抽象类是对象的抽象,然而接口是一种行为规范"

5)使用抽象类是为了代码的复用,而使用接口的动机是为了实现多态性。

6)抽象类和它的子类之间应该是一般和特殊的关系,而接口仅仅是它的子类应该实现的一组规则。

 

在讲完了面向对象的三大特征以及抽象类、接口之后,我们又学习了异常,异常在整个面向对象的开发当中起着非凡的地位,如果没有异常,那么这个程序将出现一个无法预料的后果。有人会问,什么是异常呢?也许有的人认为代码出错了就是异常,其实不是的,一般在代码中出现一个错误,就是那种提示的错误,那就不是异常,而是编译错误。编译的错误很好解决,但是异常呢,就不是那么好解决了。因为异常是无法预料的,所有的异常只能避免,而不能完全消除。

异常

异常处理是程序设计中一个非常重要的方面,也是程序设计的一大难点。异常是程序中的一些错误,但并不是所有的错误都是异常,并且错误有时候是可以避免的。比如说,你的代码少了一个分号,那么编译就会报错了,这些是可以避免的。有些异常需要做处理,有些则不必要。在编程过程中首先应当尽可能的去避免错误和异常发生,对于不可避免、不可预测的情况则在考虑异常发生时如何处理。Java中的异常用对象来表示。Java对异常的处理是按异常分类处理的,不同的异常有不同的分类,每种异常都对应一个类型。每个异常都对应一个异常对象。

异常类从哪里来?有两个来源,一是Java语言本身定义的一些基本异常类型,而不管你是否愿意捕获和处理,它总是要被抛出的。比如除数为0的异常。二是程序员自己抛出的异常,这个异常是程序员自己定义的,也可以是Java语言中定义的,用throw关键字抛出异常,这种异常常用来向调用者汇报异常的一些信息。

异常是针对方法来说的,抛出、声明抛出、捕获、和处理异常都是方法中进行的。

Java中异常处理通过5个关键字trycatchthrowfinally进行管理。基本过程是用try语句块包住要监视的语句,如果在try语句块内出现异常,则异常会被抛出。你也可以通过throws关键字在方法上声明该方法要抛出异常。然后在方法内部通过throw抛出异常对象。catch语句可以有多个,用来匹配多个异常,匹配上多个中的一个后,执行catch语句块时候仅仅执行匹配上的异常。catch的类型是Java语言中定义的或者程序员自己定义的,表示代码抛出异常的类型,异常的变量名表示抛出异常的对象的引用,如果catch捕获并匹配上了该异常,那么就可以直接用这个异常变量名,此时该异常变量名指向所匹配的异常,并且在catch代码块中可以直接引用。Java处理异常的目的是提高程序的健壮性,你可以在catchfinally代码块中给程序一个修正机会,使得程序不因异常而终止或者流程发生以外的改变。同时,通过获取Java异常信息,也为程序的开发维护提供了方便,一般通过异常信息就很快就能找到出现异常的问题所在。

Java异常处理是Java语言的一大特点,也是个难点,掌握异常处理可以让写的代码更健壮和易于维护。

Throwable类是 Java语言中所有错误或异常的超类。只有当对象是此类(或其子类之一)的实例时,才能通过 Java 虚拟机或者 Java throw语句抛出。类似地,只有此类或其子类之一才可以是 catch子句中的参数类型。

两个子类的实例,Error Exception,通常用于指示发生了异常情况。通常,这些实例是在异常情况的上下文中新近创建的,因此包含了相关的信息(比如堆栈跟踪数据)。  Exception 类及其子类是 Throwable的一种形式,它指出了合理的应用程序想要捕获的条件,表示程序本身可以处理的异常。

Error Throwable的子类,表示仅靠程序本身无法恢复的严重错误,用于指示合理的应用程序不应该试图捕获的严重问题。

  在执行该方法期间,无需在方法中通过throws声明可能抛出但没有捕获的 Error 的任何子类,因为Java编译器不去检查它,也就是说,当程序中可能出现这类异常时,即使没有用try...catch语句捕获它,也没有用throws字句声明抛出它,还是会编译通过。

RuntimeException是那些可能在 Java虚拟机正常运行期间抛出的异常的超类。Java编译器不去检查它,也就是说,当程序中可能出现这类异常时,即使没有用try...catch语句捕获它,也没有用throws字句声明抛出它,还是会编译通过,这种异常可以通过改进代码实现来避免。

调用 Thread类中带有零参数的 stop方法时,受害线程将抛出一个 ThreadDeath实例。

  仅当应用程序在被异步终止后必须清除时才应该捕获这个类的实例。如果 ThreadDeath被一个方法捕获,那么将它重新抛出非常重要,因为这样才能让该线程真正终止。

  如果没有捕获 ThreadDeath,则顶级错误处理程序不会输出消息。

虽然 ThreadDeath类是正常出现的,但它只能是 Error 的子类而不是 Exception的子类,因为许多应用程序捕获所有出现的 Exception,然后又将其放弃。

如果每个方法都是简单的抛出,那么在方法调用方法的多层嵌套调用中,Java虚拟机会从出现异常的方法代码块中往回找,知道找到处理该异常的代码块为止。然后将异常交给相应的catch语句处理。Finally语句是在任何情况下都必须执行的代码,这样可以保证一些在任何情况下都必须执行代码的可靠性。比如,在数据库查询异常的时候,应该释放jdbc连接。Finally语句先于return语句执行,而不论其先后位置,也不管是否try块出现异常,finally块都必须执行。Finally块唯一不执行的情况下是方法执行了system.exit()方法。System.exit()的作用是终止当前正在运行的Java虚拟机。Finally语句块中不能通过给变量赋新值来改变return的返回值,也建议不要在finally块中使用return语句,没有意义还容易导致错误。

Exception类分为两种:运行时异常和受检查时异常。

1)运行时异常。runtimeException类及其子类都被称为运行时异常,这种异常的特点是Java编译器不去检查它,也就是说,当程序中可能出现这类异常时,即使没有用trycatch语句捕获它,也没有用throws字句声明抛出它,它还是会编译通过。

2)受检查时异常。运行时异常表示无法让程序恢复运行的异常,导致这种异常的原因通常是由于执行了错误的操作。一旦出现错误,建议让程序终止。受检查异常表示程序可以处理的异常。如果抛出异常的方法本身不处理或者不能处理它,那么方法的调用者就必须去处理该异常,否则调用会出错,连编译也无法通过。当然,这两种异常都是可以通过程序来捕获并处理的。

Java异常处理的原则和技巧

  1、避免过大的try块,不要把不会出现异常的代码放到try块里面,尽量保持一个try块对应一个或多个异常。

  2、细化异常的类型,不要不管什么类型的异常都写成Excetpion

  3catch块尽量保持一个块捕获一类异常,不要忽略捕获的异常,捕获到后要么处理,要么转译,要么重新抛出新类型的异常。

  4、不要把自己能处理的异常抛给别人。

  5、不要用try...catch参与控制程序流程,异常控制的根本目的是处理程序的非正常情况。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics