我只是好奇他们是否有任何不同的待遇.
例如,如果我们有:
界面:
public interface Test { public void method(); }
而抽象类:
public abstract class Test { public abstract void method(); }
JVM会以不同的方式处理这些类吗?这两个中的哪一个在存储期间占用了更多的磁盘空间,哪一个将耗尽最多的运行时内存,哪一个执行更多操作(性能更好).
这个问题不是关于何时使用接口或抽象类.
解决方法@H_404_18@
是的,他们是不同的.
通过接口,客户端可以实现它以及扩展类:
class ClientType implements YourInterface,SomeOtherInterface { //can still extend other types
}
使用类,客户端将能够扩展它,但不扩展任何其他类型:
class ClientType extends YourClass { //can no longer extend other types
}
当接口或抽象类只有一个抽象方法声明时,会出现另一个不同之处,它与匿名函数(lambdas)有关.
正如@AlexanderPetrov所说,具有一种方法的接口可以用作功能接口,允许我们“在运行中”创建功能,其中指定了功能接口类型:
//the interface
interface Runnable {
void run()
}
//where it's specified
void execute(Runnable runnable) {
runnable.run();
}
//specifying argument using lambda
execute(() -> /* code here */);
这不能用抽象类来完成.
所以你不能互换使用它们.不同之处在于客户端如何使用它的局限性,这是由JVM的语义强制执行的.
至于资源使用的差异,除非它导致您的软件问题,否则不必担心.使用内存管理语言的想法是不要担心这些事情,除非你遇到问题.不要预先优化,我确定差异是可以忽略的.即使存在差异,也应该重要的是它是否可能导致您的软件出现问题.
如果您的软件存在资源问题,请分析您的应用程序.如果它确实导致内存问题,您将能够看到它,以及每个消耗的资源量.在那之前,你不应该担心它.您应该更喜欢使代码更易于管理的功能,而不是消耗最少量的资源.
通过接口,客户端可以实现它以及扩展类:
class ClientType implements YourInterface,SomeOtherInterface { //can still extend other types }
使用类,客户端将能够扩展它,但不扩展任何其他类型:
class ClientType extends YourClass { //can no longer extend other types }
当接口或抽象类只有一个抽象方法声明时,会出现另一个不同之处,它与匿名函数(lambdas)有关.
正如@AlexanderPetrov所说,具有一种方法的接口可以用作功能接口,允许我们“在运行中”创建功能,其中指定了功能接口类型:
//the interface interface Runnable { void run() } //where it's specified void execute(Runnable runnable) { runnable.run(); } //specifying argument using lambda execute(() -> /* code here */);
这不能用抽象类来完成.
所以你不能互换使用它们.不同之处在于客户端如何使用它的局限性,这是由JVM的语义强制执行的.
至于资源使用的差异,除非它导致您的软件问题,否则不必担心.使用内存管理语言的想法是不要担心这些事情,除非你遇到问题.不要预先优化,我确定差异是可以忽略的.即使存在差异,也应该重要的是它是否可能导致您的软件出现问题.
如果您的软件存在资源问题,请分析您的应用程序.如果它确实导致内存问题,您将能够看到它,以及每个消耗的资源量.在那之前,你不应该担心它.您应该更喜欢使代码更易于管理的功能,而不是消耗最少量的资源.