我試圖用類型化的回調實現抽象片段來在幾個子類中使用它。如何檢查Fragment.onAttach()內的類型化回調類型
如何檢查Context是否爲適當類的實例?
我abstact CallbackFragment代碼:
public abstract class CallbackFragment<C> extends Fragment {
protected C mCallback;
public CallbackFragment() {
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
//just in case
if(context == null)
throw new NullPointerException();
try {
mCallback = (C) context; //this line not seems to throw any exception
} catch (ClassCastException exception) {
throw new RuntimeException(context.toString() + " must implement Callbacks");
}
}
@Override
public void onDetach() {
super.onDetach();
mCallback = null;
}
}
車輛名單片段:
public abstract class VehicleListFragment<T extends Vehicle>
extends CallbackFragment<VehicleListFragment.Callback<T>> {
//callback for any list of any vehicle
public interface Callback<T extends Vehicle> {
void onListItemSelected(T selectedItem);
}
//common code for list of any vehicle
public VehicleListFragment() {
}
}
巴士,卡車,輪船,自行車,無論列表的片段:
public class BusListFragment
extends VehicleListFragment<Bus> {
//code specific for list of bus
public BusListFragment() {
}
}
車輛細節片段:
public abstract class VehicleDetailsFragment<T extends Vehicle, C extends VehicleDetailsFragment.Callback<T>>
extends CallbackFragment<C> {
//common methods of callback for any vehicle
public interface Callback<T> {
void onVehicleEdited(T editeItem);
}
//common code for any vehicle
public VehicleDetailsFragment() {
}
}
巴士,卡車,輪船,自行車,無論細節片段:
public class BusDetailsFragment
extends VehicleDetailsFragment<Bus, BusDetailsFragment.Callback> {
//specific for Bus methods
public interface Callback
extends VehicleDetailsFragment.Callback<Bus> {
void onSomethingSpecificForBusHappened(Bus bus);
}
//code specific for Bus
public BusDetailsFragment() {
}
}
我試圖添加一個抽象方法CallbackFragment得到回調類:
public abstract class CallbackFragment<C> extends Fragment {
...
@NonNull
protected abstract Class<C> getCallbackClass();
@Override
public void onAttach(Context context) {
super.onAttach(context);
...
//now checking instanceof like this
if(!getCallbackClass().isAssignableFrom(context.getClass())){
throw new RuntimeException(context.toString() + " must implement Callbacks");
}
}
}
隨着BusDetailsFragment一切看起來不錯:
public class BusDetailsFragment
extends VehicleDetailsFragment<Bus, BusDetailsFragment.Callback> {
@NonNull
@Override
protected Class<Callback> getCallbackClass() {
return Callback.class;
}
...
}
但不能與BusListFragment:
public class BusListFragment
extends VehicleListFragment<Bus> {
@NonNull
@Override
protected Class<Callback<Bus>> getCallbackClass() {
/**
* I'm not seeing any option here
*
* mCallback - is null yet. So, there is no way to use mCallback.getClass()
*
* Callback<Bus>.class - Cannot select from parameterized type
*/
//return mCallback.getClass();
//return Callback<Bus>.class;
}
...
}
當然,我可以創造VehicleListFragment的每個子類,擴展VehicleListFragment.Callback的自己的接口(如在VehicleDetailsFragment的子類),但它總是這個樣子:
public interface Callback
extends VehicleListFragment.Callback<Bus> {
//nothing more here
}
這看起來不是最適合我的選擇。 也許還有其他解決方案?請分享您的想法。任何幫助,將不勝感激。
更新了'ps' - 爲一點小毛病:) – dognose
哇!謝謝。我會試試這個。我只是不確定我現在已經完全理解你的答案。你有沒有注意到BusListFragment的回調函數是VehicleListFragment.Callback,我無法獲得.class的參數化類型? –
user2661298
@ user2661298使用泛型作爲具有自己類型的類型,同時繼承其他類型的其他泛型時,很難跟蹤泛型 - 不需要一步一步地調試。拇指規則:儘可能跟蹤您的實際班級,並且您可以隨時確定實際的班級類型並「保存」。 – dognose