接口和抽象类

来源:互联网 发布:华为手机应用数据清理 编辑:程序博客网 时间:2024/05/21 10:28

参考资料:《Java编程思想》

抽象类:

包含抽象方法的类叫做抽象类。如果一个类包含一个或多个抽象方法,该类必须被限定为抽象的。当然,也可以创建一个没有任何抽象方法的抽象类。抽象方法的方法仅有申明没有方法体。

如果一个类继承抽象类,那么它必须重写父类的抽象方法,即要提供方法体。如果不这样做的话,那么它也是一个抽象类,而且编译器会强制我们用abstract关键字来限定这个类。

 

接口:

接口相对于抽象类而言抽象程度更高,Interface这个关键字产生一个完全抽象的类,它根本没有提供任何具体实现。它允许创建确定方法名、参数列表和返回类型,但是没有任何方法体。

接口不仅仅是一个极度抽象的类,因为它允许人们通过创建一个能够被向上转型为多种基类的类型,来实现某种类似多重继承变种的特性。

 

接口中的方法可以显示申明为public的,即使不显示申明,也是public的。试想一下,如果不是public的话,那其他实现接口的类怎么对方法进行具体地实现。当这个类实现该接口时,重写接口中的方法必须显式地定义为public的,不然编译器也会提示出错。因为你不定义成public的话,它只具有包访问权限,这样方法被继承的过程中,可访问权限就被降低了,这是Java编译器不允许的。


接口中的所有方法都必须实现。

接口中的域(成员变量)都是自动static和final的,而且也是自动public的,即你不需要显示申明这些。

因为是final的,所以必须要初始化,但是可以用非常量表达式初始化。因为是static的,所以它们就可以在类第一次被加载时初始化,这发生在任何域首次访问时。当然,这些域不是接口的一部分,它们的值被存储在该接口的静态存储区域内。

Java中标识具有常量初始化值的staticfinal时,会使用大写字母的风格(在一个标识符中用下划线来分隔多个单词)

 

使用接口的核心原因:

1.      为了能够向上转型为多个基类型(以及由此而带来的灵活性)

2.      第二个原因和使用抽象基类相同:防止客户端程序创建该类的对象,并确保这仅仅是建立一个接口。


 接口,还有一个很吸引人的原因之一就是允许同一个接口具有多个不同的具体实现。在简单的情况中,它的体现形式通常是一个接受接口类型的方法,而该接口的实现和向该方法传递的对象则取决于方法的使用者。

因此,接口的一种常见用法就是策略设计模式,此时你编写一个执行某些操作的方法,而该方法将接受一个同样是你指定的接口。你主要就是要声明:“你可以用任何你想要的对象来调用我的方法,只要你的对象遵循我的接口。”这使得你的方法更加灵活、通用、并更具有可复用性。

例如,Scanner类的构造器接受的就是一个Readable接口。你会发现Readable没有用作Java标准库中其他任何方法的参数,它是单独为Scanner创建的,以使得Scanner不必将其参数限制为某个特定类。通过这种方式,Scanner可以作用于更多的类型。如果你创建一个新的类,并且想让Scanner可以作用于它,那么你就应该让它成为Readable。


什么时候使用接口,什么时候使用抽象类?

如果创建不带任何方法定义和成员变量的基类,那么就应该选择接口而不是抽象类。事实上,如果知道某事物应该成为一个基类,那么第一选择应该是使它成为一个接口。

恰当的原则应该是优先选择类而不是接口。从类开始,如果接口的必需性变得非常明确,那么就进行重构。

 


原创粉丝点击