相关疑难解决方法(0)

递归通用和流畅的接口

TL;博士

尝试实现一个层次流畅的界面,这样我就可以组合节点子类,同时也可以独立于类,但是获取类型参数不在其绑定错误范围内.

细节

我正在尝试实现一个解决方案,以便我可以创建一些类似于以下内容的东西:

farm
    .animal()
        .cat()
            .meow()
            .findsHuman()
                .saysHello()
                .done()
            .done()
        .dog()
            .bark()
            .chacesCar()
            .findsHuman()
                .saysHello()
                .done()
            .done()
        .done()
    .human()
        .saysHello()
        .done();
Run Code Online (Sandbox Code Playgroud)

同时也能做到:

Human human = new Human()
    .saysHello()
Run Code Online (Sandbox Code Playgroud)

我已经接近使用各种策略,但未能获得所描述的灵活性.

我当前的尝试使用以下类:

abstract class Base<T extends Base<T>>{

    private T parent;

    Base(){

    }

    Base( T parent ){
        this.parent = parent;
    }

    public T done() throws NullPointerException{
        if ( parent != null ){
            return (T) parent;
        }

        throw new NullPointerException();
    }   
}

class Farm<T extends Base<T>> extends Base{

    private Animal<Farm<T>> …
Run Code Online (Sandbox Code Playgroud)

java generics fluent-interface nested-generics

8
推荐指数
1
解决办法
1444
查看次数

将通用超类强制转换为子类

这是我的第一个问题,我希望它对读者和我自己都足够有用!在过去的两天里,我用Google搜索并躲过了这个世界.

我有抽象的模型和存储类,从中派生出具体的模型和存储类:

abstract class Food {}

abstract class FoodStorage<T extends Food> {
    abstract void setFood(T food);
}

class Apple extends Food {}

class Basket extends FoodStorage<Apple> {
    @Override
    void setFood(Apple apple) {
        // Save that apple to the basket
    }
}
Run Code Online (Sandbox Code Playgroud)

没问题.现在,我希望能够save()直接在一个Apple实例上调用它,将其持久化Basket(无需担心篮子),并在抽象类中实现.我发现的最好的是:

abstract class Food<T extends Food<T,S>,
        S extends FoodStorage<T,S>> {

    abstract S getStorage();

    void save() {
        getStorage().setFood((T)this); // <---- Unchecked cast warning
    }

}

abstract class FoodStorage<T extends Food<T,S>, S extends FoodStorage<T,S>> { …
Run Code Online (Sandbox Code Playgroud)

java generics casting type-safety

7
推荐指数
1
解决办法
1854
查看次数

家长/儿童仿制药关系

所以,我正在尝试这样的父/子类关系:

class ParentClass<C, T> where C : ChildClass<T>
{
    public void AddChild(C child)
    {
        child.SetParent(this); //Argument 1: cannot convert from 'ParentClass<C,T>' to 'ParentClass<ChildClass<T>,T>'
    }
}
class ChildClass<T>
{
    ParentClass<ChildClass<T>, T> myParent;
    public void SetParent(ParentClass<ChildClass<T>, T> parent)
    {
        myParent = parent;
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,这是一个编译错误.所以,我的第二个想法是SetParent用a 声明方法where.但问题是我不知道什么类型声明myParent(我知道类型,我只是不知道如何声明它.)

class ParentClass<C, T> where C : ChildClass<T>
{
    public void AddChild(C child)
    {
        child.SetParent(this);
    }
}
class ChildClass<T>
{
    var myParent; //What should I declare this as?
    public void SetParent<K>(ParentClass<K,T> …
Run Code Online (Sandbox Code Playgroud)

c# generics parent-child c#-4.0

7
推荐指数
1
解决办法
502
查看次数

Java泛型2向引用

我试图在java中创建两个相互包含的类之间的泛型关系.这些对象基本上形成一个alernating层树.到目前为止,我发现最接近的SO问题是:泛型的Java泛型,它对我的​​问题很接近并且有些帮助,但仍然不同,我想要额外的指导.这是情况,或者更确切地说,我希望它是什么:

abstract class Group<I extends Item<Group<I>>>{
     private List<I> items;
     public List<I> getItems(){...}
     public void setItems(List<I> items){...}
}

abstract class Item<G extends Group<Item<G>>>{
     private List<G> subGroups;
     public List<G> getSubGroups(){...}
     public void setSubGroups(List<G> subGroups){...}
}
Run Code Online (Sandbox Code Playgroud)

除了吸气剂和制定者之外,该类的某些方面使它们彼此明显不同,但包含应该遵循这样的方式.这背后的原因是我想强制执行,如果我有实现类,他们必须表现如下:

class AGroup extends Group<AItem>{...} //works
class AItem extends Item<AGroup>{...} //works
class BGroup extends Group<BItem>{...} //works
class BItem extends Item<BGroup>{...} //works
class MixedGroup extends Group<AItem>{...} //fails since AItem does
                                           //not extend Item<MixedGroup>
Run Code Online (Sandbox Code Playgroud)

到目前为止,编译器很好用

abstract class Group<I extends Item<Group<I>>>{
     private List<I> items;
     public List<I> getItems(){...}
     public …
Run Code Online (Sandbox Code Playgroud)

java generics

6
推荐指数
1
解决办法
352
查看次数

是否有理由为其他类型的类型实现java.util.Comparable?

实现的类Comparable<T>通常为自己实现它,例如

class MyInteger implements Comparable<MyInteger> { ... }
class MyString implements Comparable<MyString> { ... }
Run Code Online (Sandbox Code Playgroud)

但是没有什么可以阻止你为不同的类型实现它:

class MyString implements Comparable<MyInteger> { ... }
Run Code Online (Sandbox Code Playgroud)

这将允许您比较a MyString到a MyInteger.

正如Javadoc中所描述的那样,Comparable旨在模拟自然排序,这是一个总顺序,因此为了能够具有反对称性,参数的类型compareTo应该与该方法的类型相同.定义.

但实施有任何实际用途(滥用)class SomeType implements Comparable<OtherType>吗?


更新:Joni提供的答案提供了Comparable<Supertype>隐式实现的实际示例,即您的类可传递地实现该接口的位置.知道是否有人有明确使用它的例子会很有趣.

java

6
推荐指数
1
解决办法
469
查看次数

编写指向其实现者的通用接口的便捷方式

java中是否有一种编写通用接口的方法,以更方便的方式指出这种接口的实现者?

例如我写的界面:

public interface Updatable<T> {
    void updateData(T t);
}
Run Code Online (Sandbox Code Playgroud)

我想指出只有实现者的实例可以在updateData(T t)方法中传递.

所以,我必须写这样的东西:

public class Office implements Updatable<Office> {

@Override
    public void updateData(Office office) {
        //To change body of implemented methods use File | Settings | File Templates.
    }
...
...
...
}
Run Code Online (Sandbox Code Playgroud)

但似乎有点难看.你有更好的变种吗?

java generics

5
推荐指数
1
解决办法
339
查看次数

循环泛型(试2)

第二次尝试这个问题(初始代码不足以突出问题)

这是不编译的代码:

interface Player<R, G extends Game>
{
    R takeTurn(G game);
}

interface Game<P extends Player>
{
    void play(P player);
}

abstract class AbstractGame<R, P extends Player>
    implements Game<P>
{
    public final void play(final P player)
    {
        final R value;

        value = player.takeTurn(this);
        turnTaken(value);
    }

    protected abstract void turnTaken(R value);
}

public class XPlayer
    implements Player<Integer, XGame>
{
    @Override
    public Integer takeTurn(final XGame game)
    {
        return (42);
    }
}

public class XGame<P extends Player<Integer, XGame>>
    extends AbstractGame<Integer, XPlayer> …
Run Code Online (Sandbox Code Playgroud)

java generics

4
推荐指数
1
解决办法
199
查看次数

如何为我的流畅API构建接口层次结构?

我正在开发一个流畅的API,并尝试利用Java的通用方法来提供一个优雅的API来处理我的用户的类型转换.由于类型擦除,我遇到了一些麻烦.

这是我的界面的简化版本,显示了我遇到的问题:

interface Query<T extends Query<T>> {
  T execute();
  Query<T> appendClause();
}

interface A<T extends A> extends Query<T> { }

class AImpl implements A<A> {
  A execute() { ... }
  Query<A> appendClause() { ... }
}
Run Code Online (Sandbox Code Playgroud)

我收到了错误AImpl.appendClause().编译器说它A不在其范围内,应该扩展Query.据我所知,我的声明,AImpl实现A<A>该方法A 延长Query<A>.

在这里得到另一个答案后,我尝试通过更改AImpl为:分解任何潜在的无法解析的递归:

class AImpl implements A<AImpl> {
  AImpl execute() { ... }
  Query<AImpl> appendClause() { ... }
}
Run Code Online (Sandbox Code Playgroud)

现在我收到一个错误编译A,说"类型参数T不在其范围内".

有人对如何处理这个问题有任何建议吗?Java的泛型让我很头疼.

编辑

我把A的定义改为了

interface A<T extends A<T>> extends …
Run Code Online (Sandbox Code Playgroud)

java generics fluent-interface

4
推荐指数
1
解决办法
331
查看次数

我怎样才能使接口实例方法只接受同一个类的参数,真的吗?

这个SO讨论提出了以下习语:

public interface IComparable<T extends IComparable<T>> {
    int compare(T t);
}
Run Code Online (Sandbox Code Playgroud)

然后允许:

public class Foo implements IComparable<Foo> {
    public int compare(Foo foo) {
        return 0;
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,这个习惯用法不仅仅包括以上代码,因为下面的代码也可以编译:

class A implements IComparable<A> {
    public int compare(A a) {return 0;}
}

public class Foo implements IComparable<A> {

    public int compare(A a) {
        return 0;
    }
}
Run Code Online (Sandbox Code Playgroud)

因此(除非我误解了一些东西)原始成语并没有真正购买任何东西,而不是那么戏剧化:

public interface IComparesWith<T> {
    int compare(T t);
}

public class A implements IComparesWith<A> {
    public int compare(A a) {...}
}
Run Code Online (Sandbox Code Playgroud)

那么,有没有办法实际声明一个接口,以便任何类声明实现它有一个方法来与它自己的类的对象进行比较,没有任何漏洞,如上所述?

我显然无法将上述内容发布为评论,因此我创建了一个新帖子.

java generics interface

4
推荐指数
2
解决办法
1019
查看次数

在参数上强制执行子类 Java 类型

有什么方法可以在编译时对参数强制使用子类类型吗?

类似this但不适合实例 - 对于类?

我有课程:

public abstract class Animal {

  public abstract void follow(Animal a); // <-- how to declare it?

}
Run Code Online (Sandbox Code Playgroud)

但我希望子类永远不要使用基类Animal,而只使用它自己(派生类)作为参数:

public class Fish extends Animal {

  @Override
  public void follow(Fish f) { // error here, since it expects Animal
    tagAlong(f);
  }

  private void tagAlong(Fish f) {
    // do something  
  }

}
Run Code Online (Sandbox Code Playgroud)

我希望 aFish仅使用类型的参数Fish,而不是Animal像另一个子类Parrot仅使用Parrot方法上的参数一样follow()

我强烈希望在编译时强制执行此操作,但如果没有其他可能,则运行时是一个(不太理想的)选项。

java generics parameters inheritance

4
推荐指数
1
解决办法
1362
查看次数