Java中抽象类与接口异同点

 

     最近翻看了Java基础书籍,发现很多以前深记的东西快失去印象了,所以就抽空记录一下。好了,闲话不多说,说多了是闲人。偶然浏览技术贴吧时,看到一群刚迈入我们这行业的程序员争论一个关于抽象类是否可以实例化的问题。我似乎对这个问题记忆不太深了,所以翻阅了下资料记录下。首先要从Java的语言性质说起,学过Java的人都知道这是一门面向对象的语言,那么Java是如何实现面向对象的呢?首先要说起他处理现实问题的机制。拿C、BASIC这些面向过程的语言来与Java对比,你会发现C、BASIC的执行效率好快啊,JAVA怎么会执行起来这么慢啊?除了C、basic语言本身就是命令语言外,不需要像Java底层还需要转译成机器语言。还有一层原因就是:这些面向过程的语言是面向计算机结构。简单点来说它们不是面向我们思考对象的抽象,而是面向计算机器存储结构的轻微抽象。那么我们就要花费大量时间精力去理解计算器的那些固定的存储单元的数据类型,粗略一算,计算机执行时间少了,我们想的更多了,还要更多时间去了解各式的数据类型。这到底是造出机器后,减少工作量,还是增加了工作量? 正因为如此,出现了面向对象的语言。二者的差异在于:我们可以通过对问题的抽象定义成类来求解问题,而不是被迫只能使用已有的数据类型求解问题。也就是问题解答自由多了,不再局限那些数据类型的条件了。

     那么怎么根据将答案与对象一一对应呢?必须产生对该对象的请求,使对象按照请求做出相应动作,完成解答。这些请求就由接口来定义。比如乘客电梯的升降问题,首先将乘客电梯抽象成一个类,再将一个变量名称用来指向乘客电梯某个实体,紧接着new 一个乘客电梯(也就是实例化乘客电梯的某一个实体),电梯有升降功能,那么指向某一个乘客电梯实体的变量调用所有乘客电梯都有的升降方法(这个方法是父类乘客电梯的),引用变量名以点符号连接一个方法这就是发出的请求。在这里我们就应该很明了了,原来接口就是用来做什么的。比如喝水是一个接口,吃饭也是一个接口,打球还是一个接口。引用变量指向某一个实例化对象(假如实例化对象的那个人叫翠花)翠花。翠花可以喝水吗?可以吃饭吗?可以打球吗?这些她都能做吧?也就是对象可以实现多个方法。还有一点:拿喝水来说吧,为什么接口里只有抽象的方法?因为接口是公开的,所以定义的变量只能是公共的静态的常量(也就是只可以定义static final成员变量)。公开可以实现不同对象的相同行为(可以理解为不同对象实现同一个方法有不同形态),因此接口要被类实现。如果接口定义时就已经实现了,那么问题来了,假如喝水这个接口里的方法是实现的,狗喝水是舌头慢慢舔,人喝水是举杯慢饮的。喝水的这个接口是实现了,无论是实现是人的还是狗的,这都不合理。所以接口的方法只能申明但不能实现。

  下面说说抽象类,抽象类是说明对象是什么?不同的对象可能存在很多相似点,有没有办法可以将他们相同的部分复用呢?这就是抽象类与接口的本质区别,接口是为了实现多态,抽象类是为了代码的复用,当然,抽象类与接口区别可不止这一点,举个例子:灵长类是一个抽象类,人是灵长类,人能创造,能写很多字。这是人独有的方法,也就是说抽象类可以有方法是私有并已经实现了的,而接口的方法就不能实现。抽象类的抽象方法不可以为private修饰,若没有写则默认为public,抽象类被另一个类继承时,这个类就不能同时再去继承另一个抽象类了,与类的继承定义一样,也就是一个类只能继承一个,因为同时继承多个类,调用类中方法时,那么机器会去调哪个呢?所以在JAVA的世界里“单继承多实现”。当一个类继承抽象类后,没有对这个抽象类负责,没有实现抽象类的抽象方法,那么这个类必须得被定义成抽象类。最重要的一点是抽象类是有构造方法的,你可以把抽象类当成特殊的类,只是这个类不能直接实例化,实例化时是通过对父类的引用来指向子类的实例来间接地实现抽象类的实例化,因为子类实例化前肯定先会实例父类。接口不可以实例化,因为它连构造器都没有。。。

 

posted on 2017-11-18 16:37  浅楓  阅读(857)  评论(0编辑  收藏  举报