这篇文章主要小编主要给大家讲解的是Java编程中的接口,文章会从抽象类和抽象方法开始展开内容,感兴趣的小伙伴可以参考下面文章的具体内容
正文
Java编程接口详细
一、抽象类和抽象方法
抽象:从具体事物抽出、概括出它们共同的方面、本质属性与关系等,而将个别的、非本质的方面、属性与关系舍弃,这种思维过程,称为抽象。
这句话概括了抽象的概念,而在Java
中,你可以只给出方法的定义不去实现方法的具体事物,由子类去根据具体需求来具体实现。
抽象类除了包含抽象方法外,还可以包含具体的变量和具体的方法。类即使不包含抽象方法,也可以被声明为抽象类,防止被实例化。
抽象类不能被实例化,也就是不能使用new
关键字来得到一个抽象类的实例,抽象方法必须在子类中被实现。
抽象类总结规定:
- 抽象类不能被实例化,如果被实例化,就会报错,编译无法通过。只有抽象类的非抽象子类可以创建对象。
- 抽象类中不一定包含抽象方法,但是有抽象方法的类必定是抽象类。
- 抽象类中的抽象方法只是声明,不包含方法体,就是不给出方法的具体实现也就是方法的具体功能。
- 构造方法,类方法(用 static 修饰的方法)不能声明为抽象方法。
- 抽象类的子类必须给出抽象类中的抽象方法的具体实现,除非该子类也是抽象类。
二、接口
interface
关键字使得抽象的概念更加向前迈进了一步,abstract
关键字允许人们在类中创建一个或多个没有任何定义的方法---提供了接口部分。但是没有提供任何相应的具体实现,这些实现是由此类的继承者实现的。
在抽象类中,可以包含一个或多个抽象方法;但在接口(interface
)中,所有的方法必须都是抽象的,不能有方法体,它比抽象类更加“抽象”。
接口使用 interface
关键字来声明,可以看做是一种特殊的抽象类,可以指定一个类必须做什么,而不是规定它如何去做。
与抽象类相比,接口有其自身的一些特性:
-
接口中只能定义抽象方法,这些方法默认为
public abstract
的,因而在声明方法时可以省略这些修饰符。试图在接口中定义实例变量、非抽象的实例方法及静态方法,都是非法的 - 接口中没有构造方法,不能被实例化
- 一个接口不实现另一个接口,但可以继承多个其他接口。接口的多继承特点弥补了类的单继承
接口与抽象类的区别:
接口作为系统和外界交互的窗口,接口体现的是一种规范。对于接口的实现者而言,接口规定了实现者必须向外提供哪些服务(以方法的形式来提供);对于接口的调用者而言,接口规定了调用者可以调用哪些服务,以及如何调用这些服务(就是如何来调用方法)。当在一个程序中使用接口时,接口是多个模块间的耦合标准;当在多个应用程序之间使用接口时,接口是多个程序之间的通信标准。
从某种角度上来看,接口类似于整个系统的“总纲”,它制定了系统各模块之间应该遵循的标准,因此一个系统中的接口不应该经常改变。一旦接口改变,对整个系统而言甚至其他系统的影响将是辐射式的,导致系统中的大部分类都需要改写。所以,在一般的应用里,最顶级的是接口,然后是抽象类实现接口,最后才到具体类实现。
抽象类则不一样,抽象类作为系统中多个子类的共同父类,它所体现的是模板式设计。抽象类作为多个子类的的抽象父类,可以被当成系统实现过程中的中间产品,这个产品已经实现了系统的部分功能(那些在抽象类中已经提供实现的方法),但这个产品依然不能当成最终产品,必须有更进一步的完善。
除此之外,接口和抽象类在用法上也存在如下区别:
- 接口里只能包含抽象方法,抽象类则可以包含普通方法。
- 接口里不能定义静态方法,抽象类里可以定义静态方法。
- 接口里不包含构造器,抽象类可以包含构造器。抽象类里的构造器并不是用于创建对象,而是让其子类调用这些构造器来完成属于抽象类的初始化操作。
- 接口里不能包含初始化块,但抽象类可以包含初始化块。
- 接口里只能定义静态常量,抽象类既可以定义普通变量,也可以定义静态常量。
- 接口可以可以继承多个接口,类只能继承一个类。
- 抽象类主要是用来抽象类别,接口主要是用来抽象方法功能。当关注事物的本质时,使用抽象类,当关注一种操作时,使用接口。
三、Java中的多重继承
接口不仅仅是一种更加纯粹的抽象类,它的目标比这更高。因为接口中根本没有任何具体实现,所以没有任何与接口相关的存储,因此也就无法阻止多个接口的组合。在C++
中,组合多个类的接口的行为叫做多重继承,但这可能会带来很多副作用,因为每个类都有一个具体实现。在Java
中,可以执行一样的行为,但是只有一个类可以有具体实现,所以通过组合多个接口,C++的问题不会在Java中发生。
表达这样一个意思:“ x 从属于 a,也从属于 b,也从属于 c ”
使用接口的核心原因:
1).为了能够向上转型为多个基类型(以及由此带来的灵活性);
2).防止客户端程序员创建该类的对象,并确保这仅仅是建立一个接口(这与使用抽象基类原因相同)
这带来的一个问题是,应该使用接口还是抽象类?
如果要创建不带任何方法定义和成员变量的基类,那么就应该选择接口而不是抽象类。事实上,若知道某事物应该成为一个基类,那么第一选择应该是接口。
四、通过继承来扩展接口
1、组合接口时的名字冲突
在实现多重继承时,会碰到一个小陷阱,在前面的例子中,CanFight
和ActionCharacter
都有一个相同的void fight()
方法。问题不是它们方法相同,问题是,如果它们的签名(参数)或返回类型不同,会怎么样呢?
发表评论