我正在尝试编写两个通用的类/接口Tile(interface Tile<S extends Side<? extends Tile<S>>>
)和Side(abstract class Side<T extends Tile<? extends Side<T>>>
),其中一个接口的通用类型引用了另一个接口。
现在,当我尝试像这样实现Tile接口时:
public abstract class TileImpl<S> implements Tile<S extends Side<? extends Tile<S>>
我必须继续写S类型的边界:
S extends Side<? extends Tile<S>>
如何使此代码正常工作?
public interface Tile<S extends Side<? extends Tile<S>>> {
S getSide(Direction d);
/**
* Returns true if the current instance of Tile and the Tile t
* fit together.
* @param t a tile adjacent to the current tile
* @param d the position of the tile t with respect to the current tile
* @return true if the current tile and the tile t fit together
*/
boolean fitsWith(Tile<S> t, Direction d);
}
public abstract class Side<T extends Tile<? extends Side<T>>> {
private final T parent;
public Side(T parent) {
this.parent = parent;
}
public T getParent() {
return parent;
}
}
答案 0 :(得分:0)
public abstract class TileImpl<S> implements Tile<S extends Side<? extends Tile<S>>
您的问题是,您在S
上设置了界线,而在public abstract class TileImpl<S extends Side<? extends Tile<S>>> implements Tile<S>
上没有使用它。因此,只需将边界移到正确的位置即可。
/**
* Defines a {@link LiveData} object that wraps a {@link Publisher}.
*
* <p>
* When the LiveData becomes active, it subscribes to the emissions from the Publisher.
*
* <p>
* When the LiveData becomes inactive, the subscription is cleared.
* LiveData holds the last value emitted by the Publisher when the LiveData was active.
* <p>
* Therefore, in the case of a hot RxJava Observable, when a new LiveData {@link Observer} is
* added, it will automatically notify with the last value held in LiveData,
* which might not be the last value emitted by the Publisher.
*
* <p>
* Note that LiveData does NOT handle errors and it expects that errors are treated as states
* in the data that's held. In case of an error being emitted by the publisher, an error will
* be propagated to the main thread and the app will crash.
*
* @param <T> The type of data hold by this instance.
*/
private static class PublisherLiveData<T> extends LiveData<T> {
private final Publisher<T> mPublisher;
final AtomicReference<LiveDataSubscriber> mSubscriber;
PublisherLiveData(@NonNull Publisher<T> publisher) {
mPublisher = publisher;
mSubscriber = new AtomicReference<>();
}
@Override
protected void onActive() { // Problem
super.onActive();
LiveDataSubscriber s = new LiveDataSubscriber();
mSubscriber.set(s);
mPublisher.subscribe(s);
}
@Override
protected void onInactive() { // Problem
super.onInactive();
LiveDataSubscriber s = mSubscriber.getAndSet(null);
if (s != null) {
s.cancelSubscription();
}
}
final class LiveDataSubscriber extends AtomicReference<Subscription>
implements Subscriber<T> {
@Override
public void onSubscribe(Subscription s) {
if (compareAndSet(null, s)) {
s.request(Long.MAX_VALUE);
} else {
s.cancel();
}
}
@Override
public void onNext(T item) {
postValue(item);
}
@Override
public void onError(final Throwable ex) {
mSubscriber.compareAndSet(this, null);
ArchTaskExecutor.getInstance().executeOnMainThread(new Runnable() {
@Override
public void run() {
// Errors should be handled upstream, so propagate as a crash.
throw new RuntimeException("LiveData does not handle errors. Errors from "
+ "publishers should be handled upstream and propagated as "
+ "state", ex);
}
});
}
@Override
public void onComplete() {
mSubscriber.compareAndSet(this, null);
}
public void cancelSubscription() {
Subscription s = get();
if (s != null) {
s.cancel();
}
}
}
}