在我的采访中,我一直要求解释接口和抽象类的区别。
这里是我的回应:
Java接口的方法是含蓄抽象的,不能有实现。 一个Java抽象类可以实现一个默认的行为实例方法。
在Java接口声明的变量默认情况下决赛。 一个抽象类可以包含非final的变量。
Java接口的成员默认都是公有的。 一个Java抽象类可以有类成员像私有,保护等通常的味道
Java接口应使用关键字“工具”来实现; 一个Java抽象类应使用关键字“扩展”进行扩展。
一个接口只能扩展另一个Java接口,抽象类可以扩展另一个Java类,并实现多个Java接口。
一个Java类可以实现多个接口,但它只能扩展一个抽象类。
然而,面试官很不满意,并告诉我,这说明代表的“ 书本知识 ”。
他问我要更实际的回应,解释的时候我会选择一个抽象类,在接口上,使用实际的例子 。
我哪里做错了?
Answer 1:
我先举个例子吧:
public interface LoginAuth{
public String encryptPassword(String pass);
public void checkDBforUser();
}
现在,假设你有你的应用程序3个数据库。 然后,该数据库每一个执行需要定义上述2种方法:
public class DBMySQL implements LoginAuth{
// Needs to implement both methods
}
public class DBOracle implements LoginAuth{
// Needs to implement both methods
}
public class DBAbc implements LoginAuth{
// Needs to implement both methods
}
但是,如果encryptPassword()不是什么取决于数据库,它的每个类的一样吗? 然后上面就不会是一个好方法。
相反,考虑这种方法:
public abstract class LoginAuth{
public String encryptPassword(String pass){
// Implement the same default behavior here
// that is shared by all subclasses.
}
// Each subclass needs to provide their own implementation of this only:
public abstract void checkDBforUser();
}
现在,在每个子类中,我们只需要实现一个方法 - 这取决于数据库的方法。
我尽我所能,希望这会清除你的疑虑。
Answer 2:
没有什么是在这个世界上完美的。 他们可能一直期待更实用的办法。
但是你的解释后,你可以用稍微不同的方法添加这些行。
接口是规则(规则,因为你必须给他们一个实现,你不能忽视或回避,让他们强加的规则一样),它可以作为软件开发不同团队之间的共同谅解文件。
接口给知道什么是必须要做的,但它不会怎么做。 因此,实现完全按照给定的规则(给出的方法签名方式)取决于开发商。
抽象类可以包含抽象的声明,具体的实现,或两者兼而有之。
摘要声明是一样要遵循的规则和具体的实现是一样指引(您可以使用它,因为它是或者您可以通过重写,并给予自己的实现它忽略)。
此外,其与相同的签名方法可能会改变在不同的上下文中的行为被提供作为接口声明作为规则,以在不同的上下文遵照执行。
编辑:Java的8便于定义默认和接口的静态方法。
public interface SomeInterfaceOne {
void usualAbstractMethod(String inputString);
default void defaultMethod(String inputString){
System.out.println("Inside SomeInterfaceOne defaultMethod::"+inputString);
}
}
现在,当一个类将实现SomeInterface,不强制为接口的默认方法提供实现。
如果我们有以下方法另一个接口:
public interface SomeInterfaceTwo {
void usualAbstractMethod(String inputString);
default void defaultMethod(String inputString){
System.out.println("Inside SomeInterfaceTwo defaultMethod::"+inputString);
}
}
Java不允许扩展多个类,因为它导致了“钻石问题”,其中编译器不能决定使用哪个超类方法。 使用默认的方法,钻石的问题会出现的界面了。 因为如果一个类都实现
SomeInterfaceOne and SomeInterfaceTwo
并没有实现共同的默认方法,编译器不能决定选择哪一个。 为了避免这个问题,在Java 8中属于强制执行不同的接口的常用的默认方法。 如果有任何类实现上述两个接口,它提供实施defaultMethod()方法,否则编译器会抛出编译时错误。
Answer 3:
你做的使用和实施的实际差异一个很好的总结,但没有说意义存在的差异。
接口是其行为的实现类将有一个说明。 实现类保证,这将有这些方法,可以在其上使用。 它基本上是一个合同或者类必须作出承诺。
一个抽象类是共享行为,不需要重复创建不同的子类的基础。 子类必须完成的行为,并有覆盖预定义的行为选择(只要它没有被定义为final
或private
)。
你会发现在很好的例子java.util
包,其中包括像接口List
和抽象类,如AbstractList
已实现的接口。 在官方文档描述了AbstractList
,如下所示:
此类提供的骨干实现List接口,以尽量减少对实现此接口由“随机访问”数据存储备份所需的工作(如数组)。
Answer 4:
接口包括单变量(公共静态最终)和公共抽象方法。 我们通常喜欢当我们知道要做什么,但不知道怎么做 , 它可以利用实时的接口。
这个概念可以通过示例可以更好地理解:
考虑一个Payment类。 付款可以在许多方面,如贝宝,信用卡等,所以,我们通常需要支付作为我们的接口,它包含了进行makePayment()
方法和信用卡式和PayPal是两个实现类。
public interface Payment
{
void makePayment();//by default it is a abstract method
}
public class PayPal implements Payment
{
public void makePayment()
{
//some logic for PayPal payment
//e.g. Paypal uses username and password for payment
}
}
public class CreditCard implements Payment
{
public void makePayment()
{
//some logic for CreditCard payment
//e.g. CreditCard uses card number, date of expiry etc...
}
}
在上面的例子信用卡式和PayPal两种实现类/策略。 接口也允许我们在Java中多重继承不能用抽象类来实现的概念。
我们选择的时候有一些特点的,我们知道该怎么做,而且我们知道如何执行其他功能的抽象类。
请看下面的例子:
public abstract class Burger
{
public void packing()
{
//some logic for packing a burger
}
public abstract void price(); //price is different for different categories of burgers
}
public class VegBerger extends Burger
{
public void price()
{
//set price for a veg burger.
}
}
public class NonVegBerger extends Burger
{
public void price()
{
//set price for a non-veg burger.
}
}
如果加上在未来的方法(具体/抽象)给定的抽象类,然后实现类并不需要改变其代码。 但是,如果我们在一个接口在将来添加方法,我们必须添加实现到实现该接口的所有类,否则编译发生时间错误。
还有其他方面的差异,但这些是主要的可能是你的面试官所期望的。 希望这是有益的。
Answer 5:
Abstact类和接口的区别
- 抽象类与在Java接口8
- 概念上的差异:
在Java接口的默认方法8
- 什么是默认方法?
- 使用默认方法解决的ForEach方法编译错误
- 默认方法和多重继承歧义问题
- 关于Java界面的默认方法的要点:
Java接口静态方法
- Java接口静态方法,代码示例,静态方法VS默认方法
- 关于Java接口的静态方法的要点:
Java的功能接口
抽象类与在Java接口8
Java的8界面更改包括静态方法和接口的默认方法。 在此之前的Java 8中,我们可以在接口只有方法的声明。 但是从Java 8中,我们可以有默认的方法和在接口的静态方法。
引入默认方法后,似乎接口和抽象类是一样的。 然而,他们仍然在Java中8个不同的概念。
抽象类可以定义构造函数。 他们更结构化的,可以有与它们相关联的状态。 而相比之下,默认的方法只能调用其他的接口方法,没有提到具体实现的状态的条件来实现。 因此,这两种不同用途和两者之间的选择真的取决于具体的方案内容。
概念上的差异:
抽象类是有效的接口骨骼(即局部的)实施方案中,但不应该没有匹配的界面上。
所以,当抽象类是有效地减少低能见度,接口的骨干实现,可以默认方法借此走呢? 坚决:不! 几乎总是实现接口需要一些或所有这些类的建筑工具,默认的方法缺乏。 如果一些接口没有,这显然是一个特殊的情况下,不应该你引入歧途。
在Java接口的默认方法8
Java的8引入了“ 默认法 ”或(后卫方法)的新功能,它允许开发者将新方法添加到接口不破坏现有实现这些接口。 它提供了灵活性,以允许接口定义的实施,这将作为默认的情况,其中一个具体的类不能提供该方法的实现中使用。
让我们考虑小例子来理解它是如何工作的:
public interface OldInterface {
public void existingMethod();
default public void newDefaultMethod() {
System.out.println("New default method"
+ " is added in interface");
}
}
以下班将在Java的JDK 8编译成功,
public class OldInterfaceImpl implements OldInterface {
public void existingMethod() {
// existing implementation is here…
}
}
如果创建OldInterfaceImpl的一个实例:
OldInterfaceImpl obj = new OldInterfaceImpl ();
// print “New default method add in interface”
obj.newDefaultMethod();
默认方式:
默认的方法是没有最终的,不能同步,不能覆盖对象的方法。 他们始终是公开的,这严重限制了写短,可重复使用的方法的能力。
默认的方法可以提供给接口,而不会影响实现类,因为它包含的实现。 如果与实现定义在接口中的每个添加方法则没有实现类受到影响。 实现类可以覆盖接口提供的默认实现。
默认的方法能够在不破坏老的实现这些接口的新功能添加到现有的接口。
当我们扩展包含默认方法的接口,我们可以执行以下,
- 未覆盖默认方法,将继承的默认方法。
- 覆盖类似于我们在子类中覆盖其他方法的默认方法。
- 再次声明默认方法,抽象的,它迫使子类来覆盖它。
使用默认方法解决的ForEach方法编译错误
对于Java 8,JDK集合已扩展和foreach方法被添加到整个集合(其工作在与lambda表达式一起)。 与传统的方式,代码看起来像下面,
public interface Iterable<T> {
public void forEach(Consumer<? super T> consumer);
}
由于这个结果,针对每个实施类具因此编译错误,缺省方法加入具有所需的实现,以使现有的实现不应当被改变。
与默认方法Iterable接口低于,
public interface Iterable<T> {
public default void forEach(Consumer
<? super T> consumer) {
for (T t : this) {
consumer.accept(t);
}
}
}
同样的机制已被用于添加流在JDK接口而不会破坏实现类。
默认方法和多重继承歧义问题
由于Java类可以实现多个接口,并且每个接口可以定义相同的方法签名默认方法,因此,继承的方法可以彼此冲突。
考虑下面的例子,
public interface InterfaceA {
default void defaultMethod(){
System.out.println("Interface A default method");
}
}
public interface InterfaceB {
default void defaultMethod(){
System.out.println("Interface B default method");
}
}
public class Impl implements InterfaceA, InterfaceB {
}
上面的代码将失败,出现以下错误编译,
的java:类继承默认地将Impl为defaultMethod()从类型和了InterfaceA无关InterfaceB默认
为了解决这一类,我们需要提供的默认方法实现:
public class Impl implements InterfaceA, InterfaceB {
public void defaultMethod(){
}
}
此外,如果我们想调用由何超接口而不是我们自己的实现提供的默认实现,我们可以这样做如下,
public class Impl implements InterfaceA, InterfaceB {
public void defaultMethod(){
// existing code here..
InterfaceA.super.defaultMethod();
}
}
我们可以选择任何默认实现或两者作为我们新方法的一部分。
关于Java界面的默认方法的要点:
- Java接口默认的方法将帮助我们在扩展接口,而不必破坏实现类的恐惧。
- Java接口默认的方法具有桥接下来接口和抽象类之间的差异。
- Java的8界面的默认方法将帮助我们避免实用工具类,比如可以在界面本身提供类方法的所有类别。
- Java接口默认的方法将帮助我们去除基地实现类,我们可以提供默认的实现和实现类可以选择覆盖哪一个。
- 其中一个主要的原因在接口的引入缺省方法是增强的Java 8中的集合API支持lambda表达式。
- 如果层次结构中的任何类具有相同签名的方法,那么默认的方法变得无关紧要。 默认的方法不能覆盖从java.lang.Object继承的方法。 其理由很简单,这是因为对象是所有Java类的基类。 所以,即使我们定义为接口的默认方法Object类的方法,这将是无用的,因为Object类的方法将总是被使用。 这就是为什么为了避免混淆,我们不能被覆盖Object类方法的默认方法。
- Java接口的默认方法也被称为后卫方法或虚拟扩展方法。
资源链接:
- 接口与默认的方法VS在Java抽象类8
- 抽象类与接口在JDK 8时代
- 通过虚拟扩展方法接口演进
Java接口静态方法
Java接口静态方法,代码示例,静态方法VS默认方法
Java接口的静态方法类似,但我们不能在实现类重写它们默认的方法。 此功能可以帮助我们避免在实现类柜面执行不力,不想要的结果。 让我们来看看这个用一个简单的例子。
public interface MyData {
default void print(String str) {
if (!isNull(str))
System.out.println("MyData Print::" + str);
}
static boolean isNull(String str) {
System.out.println("Interface Null Check");
return str == null ? true : "".equals(str) ? true : false;
}
}
现在,让我们看到是有ISNULL()与执行不力方法的实现类。
public class MyDataImpl implements MyData {
public boolean isNull(String str) {
System.out.println("Impl Null Check");
return str == null ? true : false;
}
public static void main(String args[]){
MyDataImpl obj = new MyDataImpl();
obj.print("");
obj.isNull("abc");
}
}
需要注意的是ISNULL(字符串str)是一个简单的类方法,它不重写接口方法。 例如,如果我们将@Override标注添加到ISNULL()方法,它会导致编译错误。
现在,当我们运行应用程序,我们得到如下的输出。
接口空检查
IMPL空检查
如果我们做的接口方法从静态到默认情况下,我们会得到下面的输出。
IMPL空检查
迈德特打印::
IMPL空检查
Java接口的静态方法是可见的唯一接口中的方法,如果我们删除从MyDataImpl类ISNULL()方法中,我们将不能够使用它的MyDataImpl对象。 然而像其他的静态方法,我们可以使用使用类名接口的静态方法。 例如,一个有效的声明将是:
boolean result = MyData.isNull("abc");
关于Java接口的静态方法的要点:
- Java接口的静态方法是界面的一部分,我们不能用它来实现类的对象。
- Java接口的静态方法有利于提供实用方法,例如空检查,收集整理等。
- Java接口的静态方法帮助我们不容许实现类重写他们提供安全保障。
- 我们不能为Object类的方法定义接口的静态方法,我们将得到编译器错误的“这个静态方法不能隐藏对象的实例方法”。 这是因为它的Java不允许的,因为对象是所有类的基类,我们不能有一个一流水平的静态方法,并用相同的签名另一实例方法。
- 我们可以使用Java接口的静态方法来去除工具类等类别,并将所有的它的静态方法来相应的接口,这将是很容易找到和使用。
Java的功能接口
在我结束后,我想提供一个简要介绍功能接口。 正好与一个抽象方法的接口被称为功能性接口。
新诠@FunctionalInterface
已被引入到标记某一接口功能接口。 @FunctionalInterface
注解是一个设施以避免意外的加入在功能接口的抽象方法。 它是可选的,但良好的做法是使用它。
功能接口都期待已久的和非常受欢迎的Java应用8的功能,因为它使我们能够使用lambda表达式来实例化它们。 与一堆功能接口的新包java.util.function被添加到用于lambda表达式和方法参考文献提供的目标类型。 我们将考虑在未来的职位功能接口和lambda表达式。
资源位置:
- Java的8接口的变化-静态方法,默认方法
Answer 6:
你所有的语句是有效的,除了你的第一条语句(在Java 8发布后):
Java接口的方法是含蓄抽象的,不能有实现
从文档页面 :
一个接口是一个引用类型,类似于类,它可以包含只常量,方法签名,默认的方法,静态方法和嵌套类型
方法体只存在默认的方法和静态方法。
默认的方法:
接口可以有默认的方法 ,但比在抽象类中的抽象方法的不同。
默认方法让你新的功能添加到您的库的接口,保证与旧版本的这些接口编写的代码的二进制兼容性。
当您扩展包含默认方法的接口,你可以做到以下几点:
- 不提默认的方法在所有的,它可以让你的扩展接口继承的默认方法。
- 重新声明默认的方法,这使得它
abstract
。 - 重新定义默认的方法,这将覆盖它。
静态方法:
除了默认的方法,你可以定义接口的静态方法。 (静态方法是与在其中它被定义,而不是与任何对象类相关的方法。所述类的每个实例共享其静态方法。)
这使得它更容易为你整理的辅助方法在你的图书馆;
从文档页面的示例代码约interface
具有static
和default
方法。
import java.time.*;
public interface TimeClient {
void setTime(int hour, int minute, int second);
void setDate(int day, int month, int year);
void setDateAndTime(int day, int month, int year,
int hour, int minute, int second);
LocalDateTime getLocalDateTime();
static ZoneId getZoneId (String zoneString) {
try {
return ZoneId.of(zoneString);
} catch (DateTimeException e) {
System.err.println("Invalid time zone: " + zoneString +
"; using default time zone instead.");
return ZoneId.systemDefault();
}
}
default ZonedDateTime getZonedDateTime(String zoneString) {
return ZonedDateTime.of(getLocalDateTime(), getZoneId(zoneString));
}
}
使用下面的准则来选择是否使用一个接口或抽象类。
接口:
- 要定义一个合同 (最好是无状态的-我的意思是不变量)
- 要链接无关的类与有能力的。
- 要声明公用常数变量( 不可变的状态 )
抽象类:
几个密切相关的类之间共享代码。 它是建立一个关系。
共享相关的类之间的共同状态(状态可以在具体的类进行修改)
相关文章:
接口VS抽象类(一般OO)
实现VS扩展:何时使用? 有什么不同?
通过这些例子中去,你能理解
不相关的类可以通过接口的能力,但相关的类通过基类的扩展名更改的行为。
Answer 7:
你的解释看起来不错,但可能是它看起来像你从课本阅读这一切? : - /
什么我更烦恼的是,如何固体是你的榜样? 你懒得包括几乎所有的抽象和接口之间的区别是什么?
就个人而言,我建议这个链接: http://mindprod.com/jgloss/interfacevsabstract.html#TABLE
对于不同的详尽清单..
希望它可以帮助你,他们对未来的访谈所有其他读者
Answer 8:
许多初级开发人员做出的接口,同样的事情的细微变化抽象和具体类思维的错误,并选择其中一个纯粹的技术理由: 我需要多重继承? 我需要一些地方把常用的方法? 我需要的不仅仅是一个具体的类以外的东西费心? 这是错误的,而隐藏在这些问题的主要问题是:“I”。 当你为自己编写代码,由你自己,你很少想其他的现在或将来的开发或与您的代码工作。
接口和抽象类,虽然从技术上看明显相似,具有完全不同的意义和目的。
摘要
接口定义了一个合同 ,一些实施将满足你 。
抽象类提供 您的实现可以重复使用一个默认行为 。
以上这两点是我要找采访时,而且是不够紧凑总结。 请阅读以获得更多详情。
另类总结
- 接口是用于定义公共API
- 一个抽象类是供内部使用,并且用于限定的SPI
举例
换一种说法:一个具体的类做实际的工作,在一个非常特殊的方式。 例如, ArrayList
使用一个连续的内存区域来存储以紧凑的方式提供了快速的随机访问,迭代的对象的列表,并就地变化,但是可怕在插入,缺失,偶尔甚至增加; 同时, LinkedList
采用双联节点的存储对象的列表,这反而提供快速迭代,就地变化,和插入/删除/添加,但在随机存取可怕。 这两种类型的名单不同的使用情况进行了优化,而且是相当重要的,你打算如何使用它们。 当你要挤表现出来,你有大量交互的列表,并选择列表中的类型时,是你的,你应该仔细挑选你实例化哪一个。
在另一方面,一个列表的高层次用户并不真正关心它是如何切实执行,他们应该从这些细节绝缘。 让我们想象一下Java的没有暴露的List
界面,但只能有一个具体的List
类,实际上什么LinkedList
是现在。 所有的Java开发者定制他们的代码,以适应实施细则:避免随机访问,添加缓存来加速访问,或者只是重新实现ArrayList
自己,虽然这将是与所有的实际上运作的其他代码不兼容List
只。 这将是可怕的......但现在想象一下Java的主人居然意识到,一个链表是可怕的最实际的使用情况,并决定切换到一个数组列表,因为他们唯一List
可用类。 这将影响到世界上每一个Java程序的性能,人们就不会感到高兴。 而罪魁祸首就是实现细节是可用的,并且开发商认为这些细节是,他们可以依靠长期合同。 这就是为什么它隐藏实现细节是很重要的,并且只定义一个抽象的合同。 这是一个接口的目的:确定什么样的输入的方法接受,并预计什么样的输出,而不会暴露一切,将吸引程序员胆量去调整自己的代码,以适应可能与任何未来更新改变内部细节。
一个抽象类是接口和具体类之间的中间。 它应该帮助实现共享公共或枯燥的代码。 例如, AbstractCollection
提供了基本的实施方式中isEmpty
基于大小为0时, contains
作为迭代和比较, addAll
作为重复add
,等等。 这让实现重点放在区分它们的关键部分:如何实际存储和检索数据。
另一种观点:API的与SPI接口
接口的代码的不同部分之间的低凝聚力网关 。 他们允许图书馆存在,并没有打破每个图书馆用户,当一些内部的变化发展。 这就是所谓的应用程序编程接口 ,而不是应用程序编程类。 规模较小,他们还允许多个开发人员在大型项目成功合作,通过分离,通过有据可查的接口不同的模块。
抽象类是高内聚助手实现一个接口时,假设的实现细节一定程度的使用。 可替代地,抽象类用于定义的SPI,服务提供程序接口。
一个API和SPI之间的区别很微妙,但重要的是:一个API,重点是谁使用它,以及一个SPI焦点是谁实现它。
添加方法的API是容易的,API的所有现有用户仍然编译。 添加方法和SPI是很难的,因为每一个服务提供商(具体实现)将执行新的方法。 如果接口是用来定义一个SPI,提供者将有每当SPI合同变更发布一个新版本。 如果抽象类代替,新方法,既可以将在现有的抽象方法,或作为空定义的throw not implemented exception
存根,这将至少允许服务实现的旧版本仍然编译和运行。
关于Java 8和默认方法的注意事项
虽然Java 8接口的引入默认方法,这使得接口和抽象类,甚至较模糊的界线,这是不是让实现可重用代码,而是为了使其更容易改变既作为一个API和一个SPI接口(或错误地用于定义的SPI代替抽象类的)。
“书本知识”
在OP的回答提供的技术细节被认为是“书本知识”,因为这通常是在学校和有关语言的大多数技术书籍所使用的方法:一件事是什么 ,而不是如何使用它在实践中,特别是在大规模应用。
这里有一个比喻:假设的问题是:
什么是最好租毕业舞会,汽车或酒店房间?
技术答案听起来像:
那么,在一个车,你可以做到这一点早,但在一个酒店房间,你可以更舒适地做到这一点。 在另一方面,该酒店房间只在一个地方,而你能做到在更多的地方的车一样,比方说,你可以去到Vista的点的美景,或在汽车电影院,或许多其他地方,甚至不止一处。 此外,酒店房间设有淋浴。
这是所有真实的,但完全忽略他们是两个完全不同的事情的点,都可以在同一时间,不同的目的使用,而“做”方面是不是任何两个选项中最重要的事情。 答案缺少的角度来看,它显示了一种思维方式不成熟,而正确地呈现真正的“事实”。
Answer 9:
接口是一个“契约”里实现合同类承诺实现的方法。 在这里我不得不写的接口,而不是一类的一个例子是,当我升级从2D游戏到3D。 我不得不创建共享2D和游戏的3D版本之间的类的接口。
package adventure;
import java.awt.*;
public interface Playable {
public void playSound(String s);
public Image loadPicture(String s);
}
然后,我可以实现基于环境的方法,同时仍然能够调用从一个对象,不知道是游戏加载哪个版本的那些方法。
public class Adventure extends JFrame implements Playable
public class Dungeon3D extends SimpleApplication implements Playable
public class Main extends SimpleApplication implements AnimEventListener, ActionListener, Playable
通常,在游戏世界,这个世界可以是执行上的游戏方法的抽象类:
public abstract class World...
public Playable owner;
public Playable getOwner() {
return owner;
}
public void setOwner(Playable owner) {
this.owner = owner;
}
Answer 10:
怎么样的思维方式如下:
- 一类和一个抽象类之间的关系的类型是“是一个”
- 一个类和接口之间的关系的类型是“具有-A”
所以,当你有一个抽象类哺乳动物,子类人,以及接口驱动,那么你可以说
- 每个人是-一个哺乳动物
- 每个人都有,一个驾驶(行为)
我的建议是书本知识短语表明他想听到这两个之间的语义差别(其他人一样在这里已经建议)。
Answer 11:
抽象类并非纯粹的抽象BCZ其具体的(实现的方法)收集以及未实现的方法。 但接口是纯抽象BCZ只有未实现的方法不具体方法。
为什么抽象类?
- 如果用户想对所有对象编写通用的功能。
- 抽象类是在未来的重新实施,为没有最终用户的影响添加更多的功能最好的选择。
为什么接口?
- 如果用户想要写不同的功能,这将是在对象上不同的功能。
- 接口是,如果没有需要修改的要求,一旦接口已经出版的最佳选择。
Answer 12:
接口就像是一组基因被公开记录有一些样的影响:一个DNA测试会告诉我,我是否已经得到了他们-如果我这样做,我可以公开让他们知道,我是一个“载体“我的行为或状态的一部分将符合他们。 (当然,我可能有提供此范围之外的特质许多其他基因。)
抽象类是像的死祖先单性物种 (*):她不能被赋予生命,但活(即非抽象 )的后裔继承了她所有的基因。
(*)伸展这个比喻,假设该物种的所有成员都住在同一年龄。 这意味着死祖先的所有祖先也一定是死了 - 同样地,一个活着的祖先的后代必须是活。
Answer 13:
我做的工作面试,我会不利看待你的答案藏汉(抱歉,但即时通讯非常诚实)。 这听起来像你读过有关的区别和修订的答案,但也许你从来没有用过它在实践中。
一个很好的解释,为什么你会使用每个可能远比具有差异的精确的解释更好。 雇主ultimatley希望编程人员做的事情不知道他们这是很难在接受采访时证实。 如果申请的技术或基于文件的工作,但没有一个开发商的角色,你给出的答案将是一件好事。
祝您好运在未来的采访。
另外我回答这个问题更多的是关于面试技巧,而不是你已提供的技术材料。 也许可以阅读一下。 https://workplace.stackexchange.com/可以为这样的事情的好地方。
Answer 14:
接口是纯粹抽象的。 我们没有在任何界面实现代码。
抽象类包含两种方法及其实现。
点击这里观看接口和抽象类教程
Answer 15:
我所观察到的主要区别是抽象类为我们提供了已经实施了一些共同的行为和子类只需要实现它们相对应的特定功能。 其中,作为接口只能指定任务,哪些需要做,没有实现将根据界面给出。 我可以说,它本身指定和实施类之间的合同。
Answer 16:
连我都面临着多方采访了同样的问题,相信我,它使你的时间惨说服面试官。 如果我内在所有从上面然后我需要的答案,增加一个关键点,使在其最好的更有说服力和利用OO
如果你不打算在规则的任何修改 ,有关后面的子类,长期的未来,去的界面,你将无法在它来修改,如果你这样做,你需要去的变化中的所有其他子类,而如果你想, 你想重用的功能,设置一些规则,也使得它打开修改 ,去为抽象类。
这样想,你已经使用的易耗品服务,或者您已经提供了一些代码的世界,你有机会改变一些东西,假设一个安全性检查,如果我是代码的消费者和一天早上,更新后,我找到所有阅读我的Eclipse的痕迹,整个应用程序了。 因此,为了防止这样的恶梦,运用抽象的接口上
我认为这可能提前说服面试官的程度......快乐的采访。
Answer 17:
您在Java中选择界面,避免钻石问题的多重继承 。
如果你想所有的方法来通过客户端来实现你去界面。 这意味着你在抽象设计整个应用程序。
您可以选择抽象类,如果你已经知道什么是共同的。 例如以一个抽象类Car
。 在较高的水平,你实现共同轿车方法,如calculateRPM()
它是一种常见的方法,并让客户实现自己的行为像
calculateMaxSpeed()
等,可能你会给予您在您的日常工作也遇到了一些实时的例子已经说明。
Answer 18:
当我试图分享2个密切相关的类之间的行为,我创建包含常见的行为,并作为家长既类的抽象类。
当我试图定义一个类型,我对象的用户能够可靠地在调用方法的列表,然后创建一个接口。
例如,由于抽象类是有关分享行为我永远不会创建1个具体子类的抽象类。 但是,我很可能会创建一个只有一个实现的接口。 我的代码的用户将不知道,只有一个执行。 事实上,在未来的版本中可能有几个实现,所有这些都是一些新的抽象类,当我创建的接口根本不存在的子类。
这可能显得有点太书生气太(虽然我从来没有见过它把这样任何地方,我记得)。 如果面试官(或OP)真的希望更多的对我个人的经验,我已经准备好与接口的轶事已经演变出必要性反之亦然和。
还有一件事。 Java的8现在允许你把默认的代码到一个接口,进一步模糊接口和抽象类之间的界线。 但是,从我所看到的,该功能是即使在Java核心类库的制造者滥用。 加入这个功能,这是正确的,使人们有可能无需创建二进制不兼容扩展接口。 但是,如果你是通过定义一个接口让一个全新的类型,那么接口应该只是一个接口。 如果你也想提供通用的代码,然后通过各种手段使一个辅助类(抽象或具体)。 不要从功能开始,你可能要改变弄乱接口。
Answer 19:
据我所知,一个接口,它是由最终的变量和与没有实现方法,是由类实现来获得的一组彼此相关的其它方法或方法。 在另一方面,一个抽象类,可以包含非最终变量和方法与实施方式中,通常被用作一个引导件或从其中所有相关的或类似的类从继承的超类。 换句话说,一个抽象类包含所有被它的所有子类共享的方法/变量。
Answer 20:
在抽象类,你可以写的方法默认实现! 但在界面你不能。 基本上,在界面存在必须由它实现了接口的类来实现纯虚方法。
Answer 21:
据我了解,我如何处理,
接口是像一个规范/合同,一个实现接口类必须实现在抽象类定义的所有方法的任何类(除缺省方法(在Java中引入8))
而我定义了一个抽象类,当我知道类的一些方法和一些方法我还是不知道会是怎样实施所需的实现(我们可能知道函数签名,但不是实现)。 我这样做,这样以后在发展的一部分,当我知道这些方法是如何被实现的,我可以扩展这个抽象类,并实现这些方法。
注意:你不能有函数体在接口中的方法,除非该方法是静态的或默认。
Answer 22:
是的,你的反应是技术上是正确的,但你在哪里错了不向他们展示你理解了上升空间,并选择一个比其他的缺点。 另外,他们可能担心/吓坏了关于在将来升级他们的代码库的兼容性。 这种反应可能有助于(除了你说的):
“在一个接口类,选择一个抽象类,取决于我们项目中的代码的未来会。
抽象类向前兼容允许更好,因为你可以继续添加行为,以一个抽象类,以及未来不破坏现有的代码 - >这是不可能与一个接口类。
在另一方面,接口类比抽象类更灵活。 这是因为它们可以实现多个接口 。 问题是Java没有因此使用抽象类不会让你使用任何其他的类层次结构中的多个继承...
那么,到底一个很好的经验一般规则是:当有你的代码库中没有现成/默认实现尽量使用接口类。 而且,使用抽象类,以保持兼容性,如果你知道你会在未来的更新您的课。”
祝你好运在你的下一次面试!
Answer 23:
我将尝试使用的实际情况,以显示两者之间的区别来回答。
接口配备了零负载即无状态必须保持,因此是更好的选择,只是一个类合同(能力)相关联。
例如,说我有一个执行某种动作,现在执行的单独的线程任务的任务类我并不真的需要扩展Thread类,而更好的选择是让任务实现Runnable接口(即实现其run()方法),然后通过本Task类的对象到一个线程实例并调用其start()方法。
现在,你可以问什么,如果Runnable接口是一个抽象类?
那么在技术上,这是可能的,但聪明的设计将是一个糟糕的选择理由是:
- Runnable接口没有与它没有它的报价“为运行任何默认实现()方法相关联的状态
- 任务必须扩展它因此它不能扩展任何其他类
- 任务无关的观光专业化运行的类,它需要的只是重写run()方法
换句话说,任务类需要它通过实现继承Thread类,想使它成为一个线程Runnable接口的诗句实现一个线程来运行的能力。
简而言之US接口定义功能(合同),而使用抽象类定义骨架(普通/分)实现它。
免责声明:傻例子如下,尽量不要去判断:-P
interface Forgiver {
void forgive();
}
abstract class GodLike implements Forgiver {
abstract void forget();
final void forgive() {
forget();
}
}
现在你已经被赋予了选择,是神圣的,但你可以选择是只宽恕(即不神圣的),然后执行:
class HumanLike implements Forgiver {
void forgive() {
// forgive but remember
}
}
或者你可能可以选择是神圣的,做:
class AngelLike extends GodLike {
void forget() {
// forget to forgive
}
}
PS用java 8接口还可以具有静态以及默认(重写的实现)的方法和由此差的B / W接口和抽象类更加变窄。
Answer 24:
几乎一切似乎已经在这里覆盖..添加上实际执行的只是多一个点abstract
类:
abstract
关键词也被用来防止刚一类被实例化。 如果你有你不希望被实例化的具体类-让它abstract
。
Answer 25:
接口和抽象类之间的基本区别,接口支持多重继承,但抽象类没有。
在抽象类,你也可以提供所有抽象方法一样的界面。
为什么抽象类是必需的?
在某些情况下,在处理用户请求时,抽象类并不知道用户的意图。 在这种情况下,我们将定义在类一个抽象方法,并询问谁扩展此类用户,请提供您打算在抽象方法。 在这种情况下,抽象类是非常有用的
为什么需要接口?
比方说,我有我没有这方面的经验工作。 例如,如果你想建造建筑物或大坝,那么你会在那种情况下怎么办?
- 你会找出你有什么要求,并与要求的合同。
- 然后调用招标建设项目
- 谁曾经建设项目,应该满足你的要求。 但施工逻辑是从一个供应商到其它厂商不同。
在这里,我不打扰他们是如何构建的逻辑。 最终的目的达到了我的要求与否,这只是我的关键点。
在这里您的需求称为接口和构造函数的调用实现者。
Answer 26:
嗯,现在的人都hungery切实可行的办法,你说的很对,但大多数面试官看上去按照他们目前的要求及需要一个实用的方法。
在完成你的答案后,你应该跳上例如:
抽象:
比如我们有有一些共同所有员工的工资parametar功能。 那么我们就可以有一个名为CTC与partialy定义的方法体抽象类,它会得到所有类型的员工延伸,并得到redeined按照他们的额外beefits。 对于普通functonality。
public abstract class CTC {
public int salary(int hra, int da, int extra)
{
int total;
total = hra+da+extra;
//incentive for specific performing employee
//total = hra+da+extra+incentive;
return total;
}
}
class Manger extends CTC
{
}
class CEO extends CTC
{
}
class Developer extends CTC
{
}
接口
在Java接口允许有interfcae功能不延长一个,你必须与你想在应用程序中引入的功能特征的实现清晰。 它会迫使你有definiton。 对于不同的功能。
public interface EmployeType {
public String typeOfEmployee();
}
class ContarctOne implements EmployeType
{
@Override
public String typeOfEmployee() {
return "contract";
}
}
class PermanentOne implements EmployeType
{
@Override
public String typeOfEmployee() {
return "permanent";
}
}
您可以太受定义methgos作为一个抽象的具有抽象类这样的强迫行为,现在一个班塔扩展抽象类remin抽象的,直到它覆盖的是抽象的功能。
Answer 27:
我相信面试官试图让在可能是接口和实现之间的区别。
更一般地说不是Java的接口,但是“接口” - - 接口的代码模块,基本上与使用接口的客户端代码所做的合同。
代码模块的实现是内部代码,使该模块的工作。 通常你可以实现在多个不同的方式一个特定的接口,甚至更改,恕不客户端代码甚至未意识到实施变革。
Java接口只能用作上述一般意义上的接口,定义类的行为方式为使用类客户端代码的好处,不指定任何执行。 因此,接口包括方法的签名 - 名称,返回类型和参数列表 - 对于预期由客户端代码调用的方法,并在原则上应该有很多的Javadoc用于描述方法所做的各种方法。 最有说服力的理由使用的界面是,如果你打算拥有多个接口不同的实现,也许选择取决于部署配置的实现。
一个Java抽象类,与此相反,提供了一个部分实施的类的,而不是指定的接口的主要目的。 当多个类共享代码应该使用,但也时预计的子类提供了实现的一部分。 这允许共享代码出现在只有一个地方 - 抽象类 - 而这就很清楚,执行的部分是不存在于抽象类,预计由子类提供。
Answer 28:
你的答案是正确的,但面试官需要你按不按到Java的细节软件工程的角度来区分。
简单的一句话:
接口就是这样显示在它应该在店里是有一个商店什么的接口,所以在界面的任何方法都必须在具体的类中有实现的。 现在,如果一些类分享一些具体的方法和别人不同。 假设接口是关于包含两件事情,并假设一个店,我们有两个店都包含运动器材,但有一个额外的衣服和其他有多余的鞋子。 所以,你要做的就是让体育一个抽象类,实现了体育法并保留其他方法未实现。 这里抽象类意味着这个店并不存在本身,而是它是其他类/店铺的基础。 这样,你的组织代码,避免复制代码,统一代码,并确保通过一些其他类的可重用性的错误。
文章来源: How should I have explained the difference between an Interface and an Abstract class?