【问题标题】:How do I convert an abstract class into an interface?如何将抽象类转换为接口?
【发布时间】:2012-05-28 14:59:18
【问题描述】:
我有一个使用数组列表的 java 程序 - 这些数组列表存储“变量”,其中“变量”是一个抽象类。
现在,为了节省内存,我想使用一个名为 HugeCollections-VanillaJava 的 java 库,但是这个库需要定义一个接口。
如何将抽象类转换为接口?我必须遵守哪些规则/限制才能正确执行转换?
最后,我是否可以通过最少的代码更改来使用我的抽象类,以便需要接口的库也能正常工作?理想情况下,我根本不想更改抽象类...这可能吗?
【问题讨论】:
标签:
java
interface
abstract-class
【解决方案1】:
如何将抽象类转换为接口?
复制抽象类源文件。
在初始声明中将“类”更改为“接口”。
更改名称(可选,取决于您在做什么)。
删除该类实现的任何方法的主体。
从其他词中删除“抽象”一词。
删除所有私有成员和受保护成员。
删除所有构造函数。
从公共成员中删除关键字“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,但没有多大意义)。
【解决方案2】:
模式Adapter 可能会对您有所帮助。
想象一下,你必须使用 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 );
【解决方案3】:
如果抽象类没有定义任何具体的方法,你甚至可以使用正则表达式。来自:
public abstract class Abstract {
public abstract void method();
//...
}
到:
public interface Interface {
void method();
//...
}
public abstract 修饰符对于接口是隐式的。如果abstract 类确实定义了一些方法(并非所有方法都是abstract)或者有一些字段,这不能(至少很容易)。