浅析Java抽象类和接口的比较
抽象方法和接口的区别

抽象方法和接口的区别
抽象方法和接口是面向对象编程中的两个重要概念,它们之间存在以下区别:
1. 定义方式:抽象方法是在抽象类中定义的方法,使用关键字abstract修饰,没有方法体;接口是由方法签名组成的集合,使用关键字interface进行定义。
2. 继承关系:抽象方法通过继承的方式实现子类对该方法的重写,一个类只能继承一个抽象类;接口通过实现的方式实现对接口中方法的定义,一个类可以实现多个接口。
3. 状态:抽象方法可以有非抽象方法和属性,并可以包含构造函数,一个抽象类可以有自己的状态;接口只能包含抽象方法和常量,没有自己的状态。
4. 实例化:抽象方法不能直接被实例化,需要通过子类继承和重写来实现;接口不能被实例化,但可以通过实现类实例化,使用接口引用来调用实现类的方法。
5. 使用场景:抽象方法适用于需要有默认实现和状态的情况,可以用作基类从而提供一些共享的实现;接口适用于需要强制与不同类之间进行某种逻辑上的约束的情况。
总结来说,抽象方法提供了一种非强制性的基类实现,而接口则是一种强制性的实现规范。
抽象方法更强调类的继承和共享实现,接口更强调类的多态和实现规范。
抽象类和接口的相同点跟区别

相同点:(1) 都可以被继承(2) 都不能被实例化(3) 都可以包含方法声明(4) 派生类必须实现未实现的方法区别:(1) 抽象基类可以定义字段、属性、方法实现。
接口只能定义属性、索引器、事件、和方法声明,不能包含字段。
(2) 抽象类是一个不完整的类,需要进一步细化,而接口是一个行为规范。
微软的自定义接口总是后带able字段,证明其是表述一类“我能做。
”(3) 接口可以被多重实现,抽象类只能被单一继承(4) 抽象类更多的是定义在一系列紧密相关的类间,而接口大多数是关系疏松但都实现某一功能的类中(5) 抽象类是从一系列相关对象中抽象出来的概念,因此反映的是事物的内部共性;接口是为了满足外部调用而定义的一个功能约定,因此反映的是事物的外部特性(6) 接口基本上不具备继承的任何具体特点,它仅仅承诺了能够调用的方法(7) 接口可以用于支持回调,而继承并不具备这个特点(8) 抽象类实现的具体方法默认为虚的,但实现接口的类中的接口方法却默认为非虚的,当然您也可以声明为虚的(9) 如果抽象类实现接口,则可以把接口中方法映射到抽象类中作为抽象方法而不必实现,而在抽象类的子类中实现接口中方法使用规则:1、抽象类主要用于关系密切的对象,而接口最适合为不相关的类提供通用功能2、如果要设计大的功能单元,则使用抽象类;如果要设计小而简练的功能块,则使用接口。
3、如果预计要创建组件的多个版本,则创建抽象类。
接口一旦创建就不能更改。
如果需要接口的新版本,必须创建一个全新的接口。
4、如果创建的功能将在大范围的全异对象间使用,则使用接口;如果要在组件的所有实现间提供通用的已实现功能,则使用抽象类。
5、分析对象,提炼内部共性形成抽象类,用以表示对象本质,即“是什么”。
为外部提供调用或功能需要扩充时优先使用接口6、好的接口定义应该是具有专一功能性的,而不是多功能的,否则造成接口污染。
如果一个类只是实现了这个接口的中一个功能,而不得不去实现接口中的其他方法,就叫接口污染7、尽量避免使用继承来实现组建功能,而是使用黑箱复用,即对象组合。
java abstract方法继承

Java Abstract方法继承一、什么是Abstract方法Abstract方法是Java中一种特殊的方法,它只有声明而没有具体的实现。
在定义一个Abstract方法时,需要使用abstract关键字修饰方法,并且该方法所在的类必须是抽象类或者接口。
Abstract方法的定义如下:public abstract void methodName();二、抽象类与接口抽象类(Abstract Class)是一个不能被实例化的类,它可以包含Abstract方法和具体的方法实现。
抽象类通过使用abstract关键字进行修饰。
接口(Interface)是一种纯抽象的类,它只包含Abstract方法和常量。
接口定义方法时,默认使用public abstract修饰。
抽象类和接口的区别如下: - 抽象类可以有构造方法,而接口不能有构造方法。
- 类只能继承一个抽象类,但可以实现多个接口。
- 抽象类可以有成员变量,而接口只能有常量。
- 接口中的方法默认是public的,而抽象类中的方法可以有不同的访问修饰符。
三、Abstract方法的继承方式Abstract方法在继承关系中有以下几种继承方式:子类覆盖方法、子类重载方法、子类继续声明抽象方法。
1. 子类覆盖方法当一个子类继承自一个抽象类或者实现一个接口时,它必须实现抽象类或接口中的所有Abstract方法。
子类通过覆盖Abstract方法来提供具体的实现。
例如,有一个抽象类Animal,其中定义了一个Abstract方法eat(),如下所示:public abstract void eat();}如果一个子类Dog继承自Animal,则必须实现eat()方法:public class Dog extends Animal {@Overridepublic void eat() {System.out.println("狗吃骨头");}}2. 子类重载方法除了覆盖Abstract方法,子类还可以重载Abstract方法。
Java抽象类与接口-笔记

抽象类与接口-笔记关键字:接口抽象类,接口与类是一个层次的概念,是java中极其重要的概念抽象类是从多个类中抽象出来的公共模板,提供子类均具有的功能。
接口是从多个类中抽象出来的规范,体现的是规范和实现分离的原则,同时也有效的解决Java单重继承的缺陷。
*******普通方法与抽象方法的不同*******普通方法需要有访问修饰符,返回类型,方法名,还要有一个方法体,抽象方法也有访问修饰符,返回类型,方法名,但是它还多了一个修饰符——abstract,同时没有方法体,也就是说抽象方法没有实现。
普通方法与抽象方法的区别:1,普通方法必须要有实现体,抽象方法不能有实现体,抽象方法要用abstract修饰符来修饰。
********普通类与抽象类的区别*********普通类:要有访问修饰符,class关键字和类名。
抽象类:在普通类的基础之上,还多了一个abstract修饰符。
在使用的时候抽象类与普通类也不一样:普通类:可以通过new关键字实例化。
抽象类:不能使用new关键字来实例化。
**********抽象类********************抽象类:是一个不能实例化的类,它可以具有抽象方法或者普通方法。
定义抽象类的语法与定义普通类类似,只是多了一个关键字abstract。
注意:抽象类中可以定义抽象方法,也可以拥有普通方法,而普通类当中只能定义普通方法。
********对比抽象类与接口***************抽象类用abstract修饰符来定义,而且抽象类中可以有抽象方法,也可以有普通方法。
**接口是使用interface关键字来定义,关键字后面是接口名。
注意::定义接口的时候不再使用class关键字。
同时,接口只能拥有抽象方法。
***从定义就可以看出抽象类与接口的区别:1,抽象类使用abstract声明,接口使用interface声明。
2,抽象类除了抽象方法,还可以有普通方法,而接口中只能有抽象方法。
Java抽象类、抽象方法详解

Java抽象类、抽象⽅法详解⽬录1. 概述类⽤于描述现实⽣活中⼀类事物。
类中有属性、⽅法等成员。
⽗类中的⽅法,被它的⼦类们重写,⼦类各⾃的实现都不尽相同。
那么⽗类的⽅法声明和⽅法主体,只有声明还有意义,⽽⽅法主体则没有存在的意义了。
某种情况下,⽗类只能知道⼦类应该具备⼀个怎样的⽅法,但是不能够明确知道如何实现该⽅法。
只能在⼦类中才能确定如何去实现⽅法体。
例如:所有⼏何图形都应该具备⼀个计算⾯积的⽅法。
但是不同的⼏何图形计算⾯积的⽅式不同。
我们把没有⽅法主体的⽅法称为抽象⽅法。
Java语法规定,包含抽象⽅法的类就是抽象类。
2. 抽象⽅法抽象⽅法:只有⽅法的声明,没有⽅法体,以分号 ; 结尾,使⽤abstract关键字修饰定义格式:修饰符 abstract 返回值类型⽅法名(参数列表);代码举例:public abstract void run();抽象⽅法不能⽤private、final、static、native修饰3. 抽象类抽象类:包含抽象⽅法的类。
如果⼀个类包含抽象⽅法,那么该类必须是抽象类,使⽤abstract关键字修饰定义格式:public abstract class 类名 {//抽象类中可以包含变量、常量,抽象⽅法,⾮抽象⽅法}代码举例:public abstract class Person {public abstract void work();}抽象类的使⽤抽象类不能实例化,不能直接创建对象。
抽象类是⽤来被继承的,继承抽象类的⼦类必须重写⽗类所有的抽象⽅法。
否则,该⼦类也必须声明为抽象类,使⽤abstract关键字修饰抽象类也是类,因此原来类中可以有的成员,抽象类都可以有,那么抽象类不能直接创建对象,为什么还有构造器呢?供⼦类调⽤,⼦类创建对象时,需要为从⽗类继承的属性初始化。
抽象类不能使⽤final修饰public class Teacher extends Person {public void work() {System.out.println("讲课");}}public class AbstractClassTest {public static void main(String[] args) {// 创建⼦类对象Teacher t = new Teacher();// 调⽤run⽅法t.work();}}输出结果:讲课此时的⽅法重写,是⼦类对⽗类抽象⽅法的完成实现,我们将这种⽅法重写的操作,叫做实现⽅法。
接口和抽象类的区别是什么?Java接口中声明的变量默认都是final的。(为什么)

接⼝和抽象类的区别是什么?Java接⼝中声明的变量默认都是final的。
(为什么)接⼝和抽象类的区别是什么?参考答案Java提供和⽀持创建抽象类和接⼝。
它们的实现有共同点,不同点在于:接⼝中所有的⽅法隐含的都是抽象的。
⽽抽象类则可以同时包含抽象和⾮抽象的⽅法。
类可以实现很多个接⼝,但是只能继承⼀个抽象类类可以不实现抽象类和接⼝声明的所有⽅法,当然,在这种情况下,类也必须得声明成是抽象的。
抽象类可以在不提供接⼝⽅法实现的情况下实现接⼝。
?Java接⼝中声明的变量默认都是final的。
(为什么)抽象类可以包含⾮final的变量。
Java接⼝中的成员函数默认是public的。
抽象类的成员函数可以是private,protected或者是public。
接⼝是绝对抽象的,不可以被实例化。
抽象类也不可以被实例化,但是,如果它包含main⽅法的话是可以被调⽤的。
也可以参考JDK8中抽象类和接⼝的区别问题1.Java接⼝中声明的变量默认都是final的。
(为什么)interface中的变量是当作常量来设计的,它不但是final,⽽且还是public static的,也即interface中的变量⼀定是public static final的,换⾔之,这个变量实际上已经是个“常量”。
解答:java接⼝中成员变量必须是final类型的原因如下:1. 接⼝中的数据对所有实现类只有⼀份,所以是static2.要使实现类为了向上转型成功,所以必须是final的.这个举例⼦很好理解.⽐如接⼝A,A有变量value.实现类A1,A2,可以向上转型.假如代码中有⼀句:A a=null;a=....(2)实际实现类System.out.println(a.value);利⽤向上转型,可以得到接⼝a的值,在第2步中,我不关你是实现类A1,还是new A2(),通过转型,我们可以得到正确的值.要是类中可以更改,我们得不到⼀个统⼀的值,接⼝也没有了意义.假设接⼝的成员变量x不是final的,且默认有值。
抽象类和接口的区别

抽象类和接口的区别对于面向对象编程来说,抽象是它的一大特征之一。
在Java中,可以通过两种形式来体现OOP的抽象:接口和抽象类。
这两者有太多相似的地方,又有太多不同的地方。
下面是为大家准备的抽象类和接口的区别,希望大家喜欢!抽象类和接口的相关知识一.抽象类在了解抽象类之前,先来了解一下抽象方法。
抽象方法是一种特殊的方法:它只有声明,而没有具体的实现。
抽象方法的声明格式为:1abstract void fun();抽象方法必须用abstract关键字进行修饰。
如果一个类含有抽象方法,则称这个类为抽象类,抽象类必须在类前用abstract关键字修饰。
因为抽象类中含有无具体实现的方法,所以不能用抽象类创建对象。
下面要注意一个问题:在《JAVA编程思想》一书中,将抽象类定义为“包含抽象方法的类”,但是后面发现如果一个类不包含抽象方法,只是用abstract修饰的话也是抽象类。
也就是说抽象类不一定必须含有抽象方法。
个人觉得这个属于钻牛角尖的问题吧,因为如果一个抽象类不包含任何抽象方法,为何还要设计为抽象类?所以暂且记住这个概念吧,不必去深究为什么。
123[public] abstract class ClassName {abstract void fun();}从这里可以看出,抽象类就是为了继承而存在的,如果你定义了一个抽象类,却不去继承它,那么等于白白创建了这个抽象类,因为你不能用它来做任何事情。
对于一个父类,如果它的某个方法在父类中实现出来没有任何意义,必须根据子类的实际需求来进行不同的实现,那么就可以将这个方法声明为abstract方法,此时这个类也就成为abstract类了。
包含抽象方法的类称为抽象类,但并不意味着抽象类中只能有抽象方法,它和普通类一样,同样可以拥有成员变量和普通的成员方法。
注意,抽象类和普通类的主要有三点区别:1)抽象方法必须为public或者protected(因为如果为private,则不能被子类继承,子类便无法实现该方法),缺省情况下默认为public。
C#抽象类和接口的区别

C#抽象类和接口的区别c#接口和抽象类的区别大家都容易把这两者搞混,我也一样,在听李建忠老师的设计模式时,他也老把抽象类说成接口,弄的我就更糊涂了,所以找了些网上的资料.一、抽象类:抽象类是特殊的类,只是不能被实例化;除此以外,具有类的其他特性;重要的是抽象类可以包括抽象方法,这是普通类所不能的。
抽象方法只能声明于抽象类中,且不包含任何实现,派生类必须覆盖它们。
另外,抽象类可以派生自一个抽象类,可以覆盖基类的抽象方法也可以不覆盖,如果不覆盖,则其派生类必须覆盖它们。
二、接口:接口是引用类型的,类似于类,和抽象类的相似之处有三点:1、不能实例化;2、包含未实现的方法声明;3、派生类必须实现未实现的方法,抽象类是抽象方法,接口则是所有成员(不仅是方法包括其他成员);另外,接口有如下特性:接口除了可以包含方法之外,还可以包含属性、索引器、事件,而且这些成员都被定义为公有的。
除此之外,不能包含任何其他的成员,例如:常量、域、构造函数、析构函数、静态成员。
一个类可以直接继承多个接口,但只能直接继承一个类(包括抽象类)。
三、抽象类和接口的区别:1.类是对对象的抽象,可以把抽象类理解为把类当作对象,抽象成的类叫做抽象类.而接口只是一个行为的规范或规定,微软的自定义接口总是后带able字段,证明其是表述一类类“我能做。
”.抽象类更多的是定义在一系列紧密相关的类间,而接口大多数是关系疏松但都实现某一功能的类中.2.接口基本上不具备继承的任何具体特点,它仅仅承诺了能够调用的方法;3.一个类一次可以实现若干个接口,但是只能扩展一个父类4.接口可以用于支持回调,而继承并不具备这个特点.5.抽象类不能被密封。
6.抽象类实现的具体方法默认为虚的,但实现接口的类中的接口方法却默认为非虚的,当然您也可以声明为虚的.7.(接口)与非抽象类类似,抽象类也必须为在该类的基类列表中列出的接口的所有成员提供它自己的实现。
但是,允许抽象类将接口方法映射到抽象方法上。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
abstract class和interface是Java语言中对于抽象类定义进行支持的两种机制,正是由于这两种机制的存在,才赋予了Java强大的面向对象能力。
abstract class和interface之间在对于抽象类定义的支持方面具有很大的相似性,甚至可以相互替换,因此很多开发者在进行抽象类定义时对于abstract class和interface的选择显得比较随意。
其实,两者之间还是有很大的区别的,对于它们的选择甚至反映出对于问题领域本质的理解、对于设计意图的理解是否正确、合理。
本文将对它们之间的区别进行一番剖析,试图给开发者提供一个在二者之间进行选择的依据。
理解抽象类在面向对象的概念中,我们知道所有的对象都是通过类来描绘的,但是反过来却不是这样。
并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。
抽象类往往用来表征我们在对问题领域进行分析、设计中得出的抽象概念,是对一系列看上去不同,但是本质上相同的具体概念的抽象。
比如:如果我们进行一个图形编辑软件的开发,就会发现问题领域存在着圆、三角形这样一些具体概念,它们是不同的,但是它们又都属于形状这样一个概念,形状这个概念在问题领域是不存在的,它就是一个抽象概念。
正是因为抽象的概念在问题领域没有对应的具体概念,所以用以表征抽象概念的抽象类是不能够实例化的。
下面从三个方面进行比较:一、从语法定义层面看abstract class和interface在语法层面,Java语言对于abstract class和interface给出了不同的定义方式,下面以定义一个名为Demo的抽象类为例来说明这种不同。
使用abstract class的方式定义Demo抽象类的方式如下:abstract class Demo {abstract void method1();abstract void method2();…}使用interface的方式定义Demo抽象类的方式如下:interface Demo {void method1();void method2();…}在abstract class方式中,Demo可以有自己的数据成员,也可以有非abstarct的成员方法,而在interface方式的实现中,Demo只能够有静态的不能被修改的数据成员(也就是必须是static final的,不过在interface中一般不定义数据成员),所有的成员方法都是abstract的。
从某种意义上说,interface是一种特殊形式的abstract class。
二、从编程层面看abstract class和interface从编程的角度来看,abstract class和interface都可以用来实现"design by contract"的思想。
但是在具体的使用上面还是有一些区别的。
首先,abstract class在Java语言中表示的是一种继承关系,一个类只能使用一次继承关系。
但是,一个类却可以实现多个interface。
也许,这是Java语言的设计者在考虑Java 对于多重继承的支持方面的一种折中考虑吧。
其次,在abstract class的定义中,我们可以赋予方法的默认行为。
但是在interface的定义中,方法却不能拥有默认行为,为了绕过这个限制,必须使用委托,但是这会增加一些复杂性,有时会造成很大的麻烦。
在抽象类中不能定义默认行为还存在另一个比较严重的问题,那就是可能会造成维护上的麻烦。
因为如果后来想修改类的界面(一般通过abstract class或者interface来表示)以适应新的情况(比如,添加新的方法或者给已用的方法中添加新的参数)时,就会非常的麻烦,可能要花费很多的时间(对于派生类很多的情况,尤为如此)。
但是如果界面是通过abstractclass来实现的,那么可能就只需要修改定义在abstract class中的默认行为就可以了。
同样,如果不能在抽象类中定义默认行为,就会导致同样的方法实现出现在该抽象类的每一个派生类中,违反了"one rule,one place"原则,造成代码重复,同样不利于以后的维护。
因此,在abstract class和interface间进行选择时要非常的小心。
三、从设计理念层面看abstract class和interface上面主要从语法定义和编程的角度论述了abstract class和interface的区别,这些层面的区别是比较低层次的、非本质的。
本小节将从另一个层面:abstract class和interface所反映出的设计理念,来分析一下二者的区别。
作者认为,从这个层面进行分析才能理解二者概念的本质所在。
前面已经提到过,abstarct class在Java语言中体现了一种继承关系,要想使得继承关系合理,父类和派生类之间必须存在"is a"关系,即父类和派生类在概念本质上应该是相同的(参考文献〔3〕中有关于"is a"关系的大篇幅深入的论述,有兴趣的读者可以参考)。
对于interface 来说则不然,并不要求interface的实现者和interface定义在概念本质上是一致的,仅仅是实现了interface定义的契约而已。
为了使论述便于理解,下面将通过一个简单的实例进行说明。
考虑这样一个例子,假设在我们的问题领域中有一个关于Door的抽象概念,该Door具有执行两个动作open和close,此时我们可以通过abstract class或者interface来定义一个表示该抽象概念的类型,定义方式分别如下所示:使用abstract class方式定义Door:abstract class Door {abstract void open();abstract void close();}使用interface方式定义Door:interface Door {void open();void close();}其他具体的Door类型可以extends使用abstract class方式定义的Door或者implements使用interface方式定义的Door。
看起来好像使用abstract class和interface 没有大的区别。
如果现在要求Door还要具有报警的功能。
我们该如何设计针对该例子的类结构呢(在本例中,主要是为了展示abstract class和interface反映在设计理念上的区别,其他方面无关的问题都做了简化或者忽略)?下面将罗列出可能的解决方案,并从设计理念层面对这些不同的方案进行分析。
解决方案一:简单的在Door的定义中增加一个alarm方法,如下:abstract class Door {abstract void open();abstract void close();abstract void alarm();}或者interface Door {void open();void close();void alarm();}那么具有报警功能的AlarmDoor的定义方式如下:class AlarmDoor extends Door {void open() { … }void close() { … }void alarm() { … }}或者class AlarmDoor implements Door {void open() { … }void close() { … }void alarm() { … }}这种方法违反了面向对象设计中的一个核心原则ISP(Interface Segregation Priciple),在Door的定义中把Door概念本身固有的行为方法和另外一个概念"报警器"的行为方法混在了一起。
这样引起的一个问题是那些仅仅依赖于Door这个概念的模块会因为"报警器"这个概念的改变(比如:修改alarm方法的参数)而改变,反之依然。
解决方案二:既然open、close和alarm属于两个不同的概念,根据ISP原则应该把它们分别定义在代表这两个概念的抽象类中。
定义方式有:这两个概念都使用abstract class方式定义;两个概念都使用interface方式定义;一个概念使用abstract class方式定义,另一个概念使用interface方式定义。
显然,由于Java语言不支持多重继承,所以两个概念都使用abstract class方式定义是不可行的。
后面两种方式都是可行的,但是对于它们的选择却反映出对于问题领域中的概念本质的理解、对于设计意图的反映是否正确、合理。
我们一一来分析、说明。
如果两个概念都使用interface方式来定义,那么就反映出两个问题:1、我们可能没有理解清楚问题领域,AlarmDoor在概念本质上到底是Door还是报警器?2、如果我们对于问题领域的理解没有问题,比如:我们通过对于问题领域的分析发现AlarmDoor在概念本质上和Door是一致的,那么我们在实现时就没有能够正确的揭示我们的设计意图,因为在这两个概念的定义上(均使用interface方式定义)反映不出上述含义。
如果我们对于问题领域的理解是:AlarmDoor在概念本质上是Door,同时它有具有报警的功能。
我们该如何来设计、实现来明确的反映出我们的意思呢?前面已经说过,abstract class在Java语言中表示一种继承关系,而继承关系在本质上是"is a"关系。
所以对于Door 这个概念,我们应该使用abstarct class方式来定义。
另外,AlarmDoor又具有报警功能,说明它又能够完成报警概念中定义的行为,所以报警概念可以通过interface方式定义。
如下所示:abstract class Door {abstract void open();abstract void close();}interface Alarm {void alarm();}class AlarmDoor extends Door implements Alarm {void open() { … }void close() { … }void alarm() { … }}这种实现方式基本上能够明确的反映出我们对于问题领域的理解,正确的揭示我们的设计意图。
其实abstract class表示的是"is a"关系,interface表示的是"like a"关系,大家在选择时可以作为一个依据,当然这是建立在对问题领域的理解上的,比如:如果我们认为AlarmDoor在概念本质上是报警器,同时又具有Door的功能,那么上述的定义方式就要反过来了。