如何弃用内部接口
How to deprecate an inner interface
我需要弃用 Java SDK 中的 APIs 以使它们更通用。但我不知道如何处理以下情况:
public class AdoptDog {
public interface OnDogAdoption {
public void onDogAdoption(String dogName);
}
public void adoptDog(final String dogName, OnDogAdoption callbackObj) {
// Perform asynchronous tasks...
// Then call the callback:
callbackObj.onDogAdoption(dogName);
}
}
SDK用户调用如下:
AdoptDog adoptDog = new AdoptDog();
adoptDog.adoptDog("Snowball", new OnDogAdoption {
@Override
public void onDogAdoption(String dogName) {
System.out.println("Welcome " + dogName);
}
};
我想从 Dog 概括为 Pet,并弃用 API 提及 Dog 的内容。为了向后兼容,当我弃用 API 时,上面采用 Snowball 的代码片段不必更改。
我是如何贬低狗的API:
// Introduce Pet API
public class AdoptPet {
public interface OnPetAdoption {
public void onPetAdoption(String petName);
}
public void adoptPet(final String petName, OnPetAdoption callbackObj) {
// Perform asynchronous tasks...
// Then call the callback:
if (callbackObj instanceof OnDogAdoption) {
((OnDogAdoption) callbackObj).onDogAdoption(petName);
}
else {
callbackObj.onPetAdoption(petName);
}
}
}
// Dog API now extends Pet API for backward compatibility
@Deprecated
public class AdoptDog extends AdoptPet {
@Deprecated
public interface OnDogAdoption extends AdoptPet.OnPetAdoption {
@Deprecated
public void onDogAdoption(String dogName);
}
@Deprecated
public void adoptDog(final String dogName, OnDogAdoption callbackObj) {
super.adoptPet(dogName, callbackObj);
}
}
问题是它不完全向后兼容。 SDK 的用户必须实现 AdoptPet.OnPetAdoption.onPetAdoption() 否则他们会得到一个编译器错误:
AdoptDog adoptDog = new AdoptDog();
adoptDog.adoptDog("Snowball", new OnDogAdoption {
@Override
public void onDogAdoption(String dogName) {
System.out.println("Welcome " + dogName);
}
// PROBLEM: How avoid customers having to implement this dummy method?
@Override
public void onPetAdoption(String petName) {
assert("This code should not be reached");
}
};
是否有其他方法可以弃用 AdoptDog
(特别是 OnDogAdoption
)并保持完全向后兼容性?
Java 8 允许您指定 default
方法实现。您可以使用它来帮助您,例如:
@Deprecated
public interface OnDogAdoption extends AdoptPet.OnPetAdoption {
@Deprecated
void onDogAdoption(String dogName);
default void onPetAdoption(String petName) {
onDogAdoption(petName);
}
}
通过默认实现,客户端代码将不需要实现它(但如果他们愿意的话也可以),因此应该没有编译错误。
注: All interface methods are public
by default - in fact they can only be public
- there's no need to specify that.
您没有扩展 OnPetAdoption
。 OnDogAdoption
不是 OnPetAdoption
。 OnPetAdoption
也可以处理猫收养。一个OnDogAdoption
不能。
我建议您将 OnDogAdoption
包装在 OnDogAdoptionDispatcher
中,然后使用该调度程序调用新方法,例如:
@Deprecated
public class AdoptDog extends AdoptPet {
@Deprecated
public interface OnDogAdoption {
@Deprecated
public void onDogAdoption(String dogName);
}
private static class DogAdoptionDispatcher implements AdoptPet.OnPetAdoption {
final OnDogAdoption target;
public DogAdoptionDispatcher(OnDogAdoption target) {
this.target = target;
}
@Override
public void onPetAdoption(String petName) {
target.onDogAdoption(petName);
}
}
@Deprecated
public void adoptDog(final String dogName, OnDogAdoption callbackObj) {
super.adoptPet(dogName, new DogAdoptionDispatcher(callbackObj));
}
}
这样,您仍然具有向后兼容性和干净的新界面。
如果您使用的是 Java 8 或更高版本,则不需要单独的 class,您可以这样做
public void adoptDog(final String dogName, OnDogAdoption callbackObj) {
super.adoptPet(dogName, callbackObj::onDogAdoption);
}
我需要弃用 Java SDK 中的 APIs 以使它们更通用。但我不知道如何处理以下情况:
public class AdoptDog {
public interface OnDogAdoption {
public void onDogAdoption(String dogName);
}
public void adoptDog(final String dogName, OnDogAdoption callbackObj) {
// Perform asynchronous tasks...
// Then call the callback:
callbackObj.onDogAdoption(dogName);
}
}
SDK用户调用如下:
AdoptDog adoptDog = new AdoptDog();
adoptDog.adoptDog("Snowball", new OnDogAdoption {
@Override
public void onDogAdoption(String dogName) {
System.out.println("Welcome " + dogName);
}
};
我想从 Dog 概括为 Pet,并弃用 API 提及 Dog 的内容。为了向后兼容,当我弃用 API 时,上面采用 Snowball 的代码片段不必更改。
我是如何贬低狗的API:
// Introduce Pet API
public class AdoptPet {
public interface OnPetAdoption {
public void onPetAdoption(String petName);
}
public void adoptPet(final String petName, OnPetAdoption callbackObj) {
// Perform asynchronous tasks...
// Then call the callback:
if (callbackObj instanceof OnDogAdoption) {
((OnDogAdoption) callbackObj).onDogAdoption(petName);
}
else {
callbackObj.onPetAdoption(petName);
}
}
}
// Dog API now extends Pet API for backward compatibility
@Deprecated
public class AdoptDog extends AdoptPet {
@Deprecated
public interface OnDogAdoption extends AdoptPet.OnPetAdoption {
@Deprecated
public void onDogAdoption(String dogName);
}
@Deprecated
public void adoptDog(final String dogName, OnDogAdoption callbackObj) {
super.adoptPet(dogName, callbackObj);
}
}
问题是它不完全向后兼容。 SDK 的用户必须实现 AdoptPet.OnPetAdoption.onPetAdoption() 否则他们会得到一个编译器错误:
AdoptDog adoptDog = new AdoptDog();
adoptDog.adoptDog("Snowball", new OnDogAdoption {
@Override
public void onDogAdoption(String dogName) {
System.out.println("Welcome " + dogName);
}
// PROBLEM: How avoid customers having to implement this dummy method?
@Override
public void onPetAdoption(String petName) {
assert("This code should not be reached");
}
};
是否有其他方法可以弃用 AdoptDog
(特别是 OnDogAdoption
)并保持完全向后兼容性?
Java 8 允许您指定 default
方法实现。您可以使用它来帮助您,例如:
@Deprecated
public interface OnDogAdoption extends AdoptPet.OnPetAdoption {
@Deprecated
void onDogAdoption(String dogName);
default void onPetAdoption(String petName) {
onDogAdoption(petName);
}
}
通过默认实现,客户端代码将不需要实现它(但如果他们愿意的话也可以),因此应该没有编译错误。
注: All interface methods are public
by default - in fact they can only be public
- there's no need to specify that.
您没有扩展 OnPetAdoption
。 OnDogAdoption
不是 OnPetAdoption
。 OnPetAdoption
也可以处理猫收养。一个OnDogAdoption
不能。
我建议您将 OnDogAdoption
包装在 OnDogAdoptionDispatcher
中,然后使用该调度程序调用新方法,例如:
@Deprecated
public class AdoptDog extends AdoptPet {
@Deprecated
public interface OnDogAdoption {
@Deprecated
public void onDogAdoption(String dogName);
}
private static class DogAdoptionDispatcher implements AdoptPet.OnPetAdoption {
final OnDogAdoption target;
public DogAdoptionDispatcher(OnDogAdoption target) {
this.target = target;
}
@Override
public void onPetAdoption(String petName) {
target.onDogAdoption(petName);
}
}
@Deprecated
public void adoptDog(final String dogName, OnDogAdoption callbackObj) {
super.adoptPet(dogName, new DogAdoptionDispatcher(callbackObj));
}
}
这样,您仍然具有向后兼容性和干净的新界面。
如果您使用的是 Java 8 或更高版本,则不需要单独的 class,您可以这样做
public void adoptDog(final String dogName, OnDogAdoption callbackObj) {
super.adoptPet(dogName, callbackObj::onDogAdoption);
}