抽象类和接口
Posted houwenbo
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了抽象类和接口相关的知识,希望对你有一定的参考价值。
抽象类(abstract class)
是什么
具有所有类的特性:属性、方法,该类不能建立对象,只能声明指针和引用,用于基础类的接口声明和运行时的多态,只能继承。所以一般都做为父类存在
能干什么
做父类用,让子类继承,抽象类不能被实例化。抽象类是用来被继承的,抽象类的子类必须重写父类的抽象方法,并提供方法体。若没有重写全部的抽象方法,仍为抽象类。
在哪用
抽象类
抽象类:抽象类就是不能使用new方法进行实例化的类,即没有具体实例对象的类,抽象类有点类似于“模板”的作用,目的是根据其格式来创建和修改新的类,对象不能由抽象类直接创建,只可以通过抽象类派生出新的子类,再由其子类来创建对象,当一个类被声明为抽象类时,要在这个类前面加上修饰符abstract,在抽象类中的成员方法可以包括一般方法和抽象方法
抽象方法
抽象方法:抽象方法就是以abstract修饰的方法,这种方法只声明返回的数据类型,方法名称和所需要的参数,没有方法体,也就是说抽象方法只需要声明而不需要事先,当一个方法为抽象方法时,意味着这个方法必须被子类的方法所重写,否则其子类的该方法仍然是abstract的,而这个子类也必须是抽象的,即声明为avstract
抽象方法:只有方法的声明,没有方法的实现。以分号结束:abstract int abstractMethod( int
注意:
含有抽象方法的类必须被声明为抽象类。
抽象类不能被实例化。抽象类是用来被继承的,抽象类的子类必须重写父类的抽象方法,并提供方法体。若没有重写全部的抽象方法,仍为抽象类。
怎么用
1.abstract:抽象的
2.可用修饰的结构:类 、 方法
类:访问修饰符 abstract class 类名()
方法:访问修饰符 abstract 返回值类型 方法名()
3.abstract修饰类:抽象类
>不可实例化
>仍然存在构造器。构造器的作用:便于子类对象实例化时进行调用
>通常情况,我们会提供抽象类的子类,让子类实例化,调用父类的结构。
>抽象类中不一定有抽象方法;抽象方法所在的类,一定是抽象类。
4.abstract修饰方法:抽象方法(没有方法体)
>如果子类重写了父类中的所有的抽象方法,则此子类可以实例化
>如果子类没有重写父类中的所有的抽象方法,则子类仍为抽象类
5.前提:抽象性使用的前提是类的继承性。
注意
abstract关键字不能用来修饰:属性、构造器。
abstract关键字不能与 final , private , static 共用。
接口(interface)
是什么
在Java中接口是一个全部由抽象方法组成的集合,接口需要用interface定义,里面只能有抽象的方法和常量。
接口体现的是事物扩展的功能,在Java中,类定义了一个实体,包括实体的属性,实体的行为。而接口定义了一个实体可能发生的动作,只有一个声明,没有具体的行为。
当一个方法在很多类中有不同的体现是时候这个时候就可以将这个方法抽象出来做成一个接口
能干什么
(1)通过接口可以实现不相关类的相同行为,而不需要了解对象所对应的类。
(2)通过接口可以指明多个类需要实现的方法。
(3)通过接口可以了解对象的交互界面,而不需了解对象所对应的类。
类描述了一个实体,包括实体的状态,也包括实体可能发出的动作。
接口定义了一个实体可能发出的动作。但是只是定义了这些动作的原型,没有实现,也没有任何状态信息。
所以接口有点象一个规范、一个协议,是一个抽象的概念;而类则是实现了这个协议,满足了这个规范的具体实体,是一个具体的概念。
从程序角度,简单理解,接口就是函数声明,类就是函数实现。需要注意的是同一个声明可能有很多种实现。
1、接口中定义类方法的原型,但是不能说是空方法,因为空方法的意思是有实现体,只不过实现体是空操作。实际上接口没有定义任何实现体。具体的实现体都是在实现接口的类中,接口只是定义了这些方法的调用方式。
你当然也可以不用接口,直接在类里面写方法,但是如果你的一组方法需要在很多类里实现,那么把它们抽象出来,做成一个接口规范,不是更好么?
2、一个类描述了一个实体,这个实体可能是一个复杂的对象,它的动作很多,如果把这些动作分类,用接口a定义其中的某一组动作,接口b定义其中的另外一组动作,这样的结构,比较清楚。
这种方式具备了多继承的优点,避免了多继承的缺陷。实际上在历史上,接口在很大程度上,是为了解决多继承带来的种种问题而设计出来的。
3、包中那些已定义的接口,怎么知道那里面定义了什么方法。
接口里定义了方法的输入输出,这些都是协议,具体的实现都在每个类中。对于很多只需要抽象接口的地方,不需要知道具体的类是什么,只要这个类实现了这个接口就可以了。
一、规范性
接口就是规范,在整个系统设计中,涉及到很多层,为了使各个层之间调用透明话,你只需要知道接口,按照这个接口做你具体做的事情,就可以融合到整个系统中了。
生活中的例子很多,例如:插头、插座,有标准的规范告诉你插头应该是几个脚,插座是几个孔等等,做插头、插座的公司就是根据这个规范来做插头、插座,而不需要做完一个插头就跑遍全世界去试用一下这个插头做的对不对。
二、扩展性
在项目开发过程中,由于客户的需求经常变化,如果不采用接口,那么我们必须不停改写现有的业务代码。改写代码可能产生新的BUG,而且改写代码还会影响到调用该业务的类,可能全都需要修改,影响系统本身的稳定性。到最后,可能会出现代码凌乱,不易读懂,
后接手的人无法读懂代码,系统的维护工作越来越重,最终可能导致项目失败。
三、接口在项目就是一个业务逻辑,面向接口编程就是先把客户的业务提取出来,作为接口。业务具体实现通过该接口的实现类来完成。当客户需求变化时,只需编写该业务逻辑的新的实现类,不需要改写现有代码,减少对系统的影响。从而让项目具有更大的扩展性。
在哪用
抽象类是对事物本身的抽象,比如教师类,学生类就可以抽象为人类。
接口是对行为的抽象,比如教师要学英语,学生也要学英语,学英语就可以抽象为接口。
抽象类表示的是这个对象是什么,接口是表示这个对象能干什么。
所以抽象类只能有一个子类,就比如教师和学生只能是人类不能是非人类。
而教师或者学生可以实现多个接口。他们既可以学英语也可以学数学。
怎么用
定义接口时使用interface定义,区别于抽象类,不需要加class。
接口不能被实例化,不能直接创建对象,因为接口里面只有抽象的方法,没有具体的功能。
接口可以继承接口,接口要实现具体的功能必须有实现他的子类,实现接口的子类中必须重写接口全部的抽象方法。
接口和接口之间可以多继承。
接口的子类可以是抽象类,但是没有实际的意义。
一个子类可以实现多个接口,通过implements关键字去实现。
接口需要通过多态才能创建对象
接口的使用:
1.接口(interface) 是与类(class)并列的结构
2.如何定义一个接口.使用interface关键字
3.接口中只能定义常量和抽象方法 ----> JDK7.0及以前。 (JDK8.0接口中引入默认方法、静态方法)
常量的定义:public static final修饰。
抽象方法的定义:public abstract修饰
4.接口中不能声明构造器! 接口是不可以直接实例化的。
5.类与接口之间的关系:实现(implements)关系. 类实现接口以后,就获取了接口中声明的结构:常量、抽象方法
格式:class SubClass extends SuperClass implements InterfaceA
6.类实现接口以后,要么实现接口中的所有抽象方法,方可实例化。
要么当前类声明为抽象类(因为内部包含从接口中获取的抽象方法)
7.java规定:类可以实现多个接口。--->一定程度上,解决了java类的单继承的局限性。
8.java规定:接口与接口之间是继承关系。而且是可以多继承的!
接口的特点:
用interface来定义。
接口中的所有成员变量都默认是由public static final修饰的。
接口中的所有方法都默认是由public abstract修饰的。
接口没有构造器。
接口采用多继承机制
1.接口与具体的实现类之间存在多态性
2.如何提供接口的匿名实现类,如何去创建匿名对象
3.接口,实际上可以理解定义了一套相应功能的规范、标准。
实现接口的类中必须提供接口中所有方法的具体实现内容,方可实例化。否则,仍为抽象类。
接口的主要用途就是被实现类实现。(面向接口编程)
与继承关系类似,接口与实现类之间存在多态性
定义Java类的语法格式:先写extends,后写implements
< modifier> class < name> [extends < superclass>]
[implements < interface> [,< interface>]* ]
< declarations>*
总结
通过接口可以实现不相关类的相同行为,而不需要考虑这些类之间的层次关系。
通过接口可以指明多个类需要实现的方法,一般用于定义对象的扩张功能。
接口主要用来定义规范。解除耦合关系。
Java 8中关于接口的改进
Java 8中,你可以为接口添加默认方法和静态方法。从技术角度来说,这是完全合法的,只是它看起来违反了接口作为一个抽象定义的理念。
默认方法:默认方法使用 default 关键字修饰。可以通过实现类对象来调用。我们在已有的接口中提供新方法的同时,还保持了与旧版本代码的兼容性。
比如:java 8 API中对Collection、List、Comparator等接口提供了丰富的默认方法。
静态方法:使用 static 关键字修饰。可以通过接口直接调用静态方法,并执行其方法体。我们经常在相互一起使用的类中使用静态方法。你可以在标准库中找到像Collection/Collections或者Path/Paths这样成对的接口和类。
接口中的默认方法
接口默认方法的“类优先”原则
若一个接口中定义了一个默认方法,而另外一个父类或接口中又定义了一个同名的方法时
选择父类中的方法。如果一个父类提供了具体的实现,那么接口中具有相同名称和参数的默认方法会被忽略。
接口冲突。如果一个父接口提供一个默认方法,而另一个接口也提供了一个具有相同名称和参数列表的方法(不管方法是否是默认方法),那么必须覆盖该方法来解决冲突
接口和抽象类的区别
No. |
区别点 |
抽象类 |
接口 |
1 |
定义 |
包含一个抽象方法的类 |
抽象方法和全局常量的集合 |
2 |
组成 |
构造方法、抽象方法、普通方法、常量、变量 |
常量、抽象方法 |
3 |
使用 |
子类继承抽象类(extends) |
子类实现接口(implements) |
4 |
关系 |
抽象类可以实现多个接口 |
接口不能继承抽象类,但允许继承多个接口 |
5 |
常见设计模式 |
模板设计 |
工厂设计、代理设计 |
6 |
对象 |
都通过对象的多态性产生实例化对象 |
|
7 |
局限 |
抽象类有单继承的局限 |
接口没有此局限 |
8 |
实际 |
作为一个模板 |
是作为一个标准或是表示一种能力 |
9 |
选择 |
如果抽象类和接口都可以使用的话,优先使用接口,因为避免单继承的局限 |
以上是关于抽象类和接口的主要内容,如果未能解决你的问题,请参考以下文章