我有一个使用数组列表的 java 程序 - 这些数组列表存储“变量”,其中“变量”是一个抽象类。
现在,为了节省内存,我想使用一个名为 HugeCollections-VanillaJava 的 java 库,但是这个库需要定义一个接口。
如何将抽象类转换为接口?我必须遵循哪些规则/限制才能正确执行转换?
最后,我是否可以通过最少的代码更改来使用我的抽象类,以便需要接口的库也可以正常工作?理想情况下,我根本不想更改抽象类……这可能吗?
我有一个使用数组列表的 java 程序 - 这些数组列表存储“变量”,其中“变量”是一个抽象类。
现在,为了节省内存,我想使用一个名为 HugeCollections-VanillaJava 的 java 库,但是这个库需要定义一个接口。
如何将抽象类转换为接口?我必须遵循哪些规则/限制才能正确执行转换?
最后,我是否可以通过最少的代码更改来使用我的抽象类,以便需要接口的库也可以正常工作?理想情况下,我根本不想更改抽象类……这可能吗?
如何将抽象类转换为接口?
制作抽象类源文件的副本。
在初始声明中将“类”更改为“接口”。
更改名称(可选,取决于您在做什么)。
删除类实现的任何方法的主体。
从其他词中删除“抽象”一词。
删除所有私有成员和受保护成员。
删除所有构造函数。
从公共成员中删除关键字“public”。
如果您删除了任何代码(实现的方法、私有或受保护的东西),请让您的原始抽象类实现您的接口并将这些东西留在那里。
(不完整)示例:
Foo
作为一个抽象类:
public abstact class Foo
{
private int bar;
public static final int SOME_CONSTANT = 42;
public Foo(b) {
this.bar = b;
}
public abstract void doSomething(String s);
protected int doSomethingElse() {
return this.bar * 2;
}
}
Foo
作为接口:
public interface Foo
{
int SOME_CONSTANT = 42;
void doSomething(String s);
}
就我而言,因为我确实有一些旧的东西Foo
,我可能会拥有AbstractFoo
或其他东西:
public abstact class AbstractFoo implements Foo
{
private int bar;
public Foo(b) {
this.bar = b;
}
public abstract void doSomething(String s);
protected int doSomethingElse() {
return this.bar * 2;
}
}
...因此,如果需要,实现可以将其用作起点(尽管private
bar
在那里,它没有多大意义)。
模式适配器可能会对您有所帮助。
想象一下,你必须使用SomeClass作为TargetInterface
public abstract class SomeClass {
// some code here
public abstract void someMethod();
}
public interface TargetInterface {
public void someMethodBlaBla();
}
它们有不同的方法签名—— someMethod()和someMethodBlaBla()。
所以你可能会创建这样的适配器类:
public class Adapter implements TargetInterface {
private SomeClass adaptee;
public Adapter( SomeClass adaptee ) {
this.adaptee = adaptee;
}
public void someMethodBlaBla() {
this.adaptee.someMethod();
}
//delegate all calls to adaptee
}
在代码中的某个地方,您可能会同时使用适配器和抽象类的实例,而不会干扰当前代码:
SomeClass abstractClassInstance = ... //get instance of your abstract class
TargetInterface targetInterfaceInstance = new Adapter( abstractClassInstance );
如果抽象类没有定义任何具体方法,你甚至可以使用正则表达式。从:
public abstract class Abstract {
public abstract void method();
//...
}
至:
public interface Interface {
void method();
//...
}
public abstract
修饰符对于接口是隐式的。如果abstract
该类确实定义了一些方法(并非所有方法都是abstract
)或具有某些字段,则无法完成(至少很容易)。