Java中的方法重写和泛型问题

Java中的方法重写和泛型问题,java,generics,overriding,Java,Generics,Overriding,我一直在努力重写泛型抽象类中的方法 public abstract class Grandparent<T extends Grandparent> public T set(final T other) //does stuff I don't want to do public abstract class Parent<T extends Parent<T>> extends Grandparent<T> public

我一直在努力重写泛型抽象类中的方法

public abstract class Grandparent<T extends Grandparent>

    public T set(final T other) //does stuff I don't want to do


public abstract class Parent<T extends Parent<T>> extends Grandparent<T>

    public T set(final Parent<?> other) // does stuff I want to do
因为这样我就无法从另一个子类对象设置一个子类对象

我如何编写set()方法,以便在子对象调用它时触发它,传入任何其他子对象,而不对外部代码进行任何修改

如何将set()方法写入 在子对象调用时触发 它传递任何其他子对象, 不需要对外部进行任何修改 密码

你能包括你想做的代码建模吗?我只是想弄清楚你想做什么,因为目前我怀疑这是不允许的——不管你做什么

编辑

我用来测试的类

package test.stack.overflow;

public abstract class GrandParent<T extends GrandParent>
{
    public T set(final GrandParent<?> other)
    {
        System.out.println("GrandParent.set=" + other);

        return null;
    }
}

public abstract class Parent<T extends Parent<T>> extends GrandParent<T>
{
    public Parent<?> set(final Parent<?> other)
    {
        System.out.println("Parent.set=" + other);

        return other;
    }
}

public class Child_1 extends Parent<Child_1>
{
}

public class Child_2 extends Parent<Child_2>
{
}

public class TestPeerage
{    
    public static void main(String[] args)
    {
        Child_1 c1 = new Child_1();

        c1.set(new Child_2());
        c1.set(new Child_1());

        Parent<Child_1> pc1 = new Child_1();

        pc1.set(new Child_2());
        pc1.set(new Child_1());
    }
}
package test.stack.overflow;
公共抽象类祖父母
{
公共T集(最终祖父母其他)
{
System.out.println(“祖父母.set=“+其他”);
返回null;
}
}
公共抽象类父类扩展了祖父母类
{
公共父集合(最终父集合其他)
{
System.out.println(“Parent.set=“+other”);
归还他人;
}
}
公共类Child_1扩展了Parent
{
}
公共类Child_2扩展了Parent
{
}
公共等级贵族
{    
公共静态void main(字符串[]args)
{
Child_1 c1=新的Child_1();
c1.集合(新的子元素_2());
c1.集合(新的子元素_1());
父pc1=新的子_1();
pc1.set(新的Child_2());
pc1.set(新的Child_1());
}
}
如何将set()方法写入 在子对象调用时触发 它传递任何其他子对象, 不需要对外部进行任何修改 密码

你能包括你想做的代码建模吗?我只是想弄清楚你想做什么,因为目前我怀疑这是不允许的——不管你做什么

编辑

我用来测试的类

package test.stack.overflow;

public abstract class GrandParent<T extends GrandParent>
{
    public T set(final GrandParent<?> other)
    {
        System.out.println("GrandParent.set=" + other);

        return null;
    }
}

public abstract class Parent<T extends Parent<T>> extends GrandParent<T>
{
    public Parent<?> set(final Parent<?> other)
    {
        System.out.println("Parent.set=" + other);

        return other;
    }
}

public class Child_1 extends Parent<Child_1>
{
}

public class Child_2 extends Parent<Child_2>
{
}

public class TestPeerage
{    
    public static void main(String[] args)
    {
        Child_1 c1 = new Child_1();

        c1.set(new Child_2());
        c1.set(new Child_1());

        Parent<Child_1> pc1 = new Child_1();

        pc1.set(new Child_2());
        pc1.set(new Child_1());
    }
}
package test.stack.overflow;
公共抽象类祖父母
{
公共T集(最终祖父母其他)
{
System.out.println(“祖父母.set=“+其他”);
返回null;
}
}
公共抽象类父类扩展了祖父母类
{
公共父集合(最终父集合其他)
{
System.out.println(“Parent.set=“+other”);
归还他人;
}
}
公共类Child_1扩展了Parent
{
}
公共类Child_2扩展了Parent
{
}
公共等级贵族
{    
公共静态void main(字符串[]args)
{
Child_1 c1=新的Child_1();
c1.集合(新的子元素_2());
c1.集合(新的子元素_1());
父pc1=新的子_1();
pc1.set(新的Child_2());
pc1.set(新的Child_1());
}
}

若要重写方法,需要提供重写等效签名,这意味着方法名称、参数数量和类型必须相等。对于
祖父母.set()
父母.set()
,情况并非如此。因此,
Parent.set()
重载而不是重写,
Grandparent.set()

我看到的最简单的解决方案是将方法签名概括如下:

public abstract class Grandparent<T extends Grandparent>
    public T set(Grandparent<?> other) 

public abstract class Parent<T extends Parent<T>> extends Grandparent<T>
    public T set(Grandparent<?> other) 
公共抽象类祖父母
公共T集(祖父母或其他)
公共抽象类父类扩展了祖父母类
公共T集(祖父母或其他)

这样,方法将重写,并且您不必修改任何子类。

要重写方法,您需要提供一个重写等效签名,这意味着方法名称、参数数量和类型必须相等。对于
祖父母.set()
父母.set()
,情况并非如此。因此,
Parent.set()
重载而不是重写,
Grandparent.set()

Child_1 test = new Child_1();
Child_1 test_2 = new Child_1();
test.set(test_2) //this calls the function I don't want

Parent<Child_1> test_3 = new Child_1();
Parent<Child_1> test_4 = new Child_1();
test3.set(test_4) //this calls the function I do want
我看到的最简单的解决方案是将方法签名概括如下:

public abstract class Grandparent<T extends Grandparent>
    public T set(Grandparent<?> other) 

public abstract class Parent<T extends Parent<T>> extends Grandparent<T>
    public T set(Grandparent<?> other) 
公共抽象类祖父母
公共T集(祖父母或其他)
公共抽象类父类扩展了祖父母类
公共T集(祖父母或其他)

这样,方法就可以重写,您不必修改任何子类。

随后的评论有助于澄清您的意图,但我可能仍然感到困惑。也许这会有所帮助;如果没有,请尝试详细说明您的问题

Child_1 test = new Child_1();
Child_1 test_2 = new Child_1();
test.set(test_2) //this calls the function I don't want

Parent<Child_1> test_3 = new Child_1();
Parent<Child_1> test_4 = new Child_1();
test3.set(test_4) //this calls the function I do want
public abstract class Grandparent<T extends Grandparent<T, Q>, Q extends Grandparent<T, Q>>
{

  public abstract Q set(Q other);

}

class Parent<T extends Parent<T>>
  extends Grandparent<T, Parent<T>>
{

  @Override
  public Parent<T> set(Parent<T> other)
  {
    throw new UnsupportedOperationException("set");
  }

}
公共抽象类祖父母
{
公共抽象Q集(Q-other);
}
班级家长
祖父母
{
@凌驾
公共父集合(父集合其他)
{
抛出新的UnsupportedOperationException(“set”);
}
}

随后的评论有助于澄清您的意图,但我可能仍然感到困惑。也许这会有所帮助;如果没有,请尝试详细说明您的问题

public abstract class Grandparent<T extends Grandparent<T, Q>, Q extends Grandparent<T, Q>>
{

  public abstract Q set(Q other);

}

class Parent<T extends Parent<T>>
  extends Grandparent<T, Parent<T>>
{

  @Override
  public Parent<T> set(Parent<T> other)
  {
    throw new UnsupportedOperationException("set");
  }

}
公共抽象类祖父母
{
公共抽象Q集(Q-other);
}
班级家长
祖父母
{
@凌驾
公共父集合(父集合其他)
{
抛出新的UnsupportedOperationException(“set”);
}
}

我不确定这是否相关,因为我自己对泛型还是相当陌生的,但请记住Java泛型是通过erasure()实现的,这意味着源代码中可用的所有泛型类型信息都被编译器完全擦除,因此在运行时不可用。只是,这个问题对我来说没有任何意义。我不确定这是否相关,因为我自己对泛型还是相当陌生的,但请记住Java泛型是用erasure()实现的,这意味着源代码中可用的所有泛型类型信息都被编译器完全擦除,因此在运行时不可用。只是提醒一下,这个问题对我来说毫无意义,当然。有了两个子类child1和child2,它们分别扩展了Parent和Parent,我希望能够创建一个child1对象并调用child1.set(child2对象)。我倾向于同意user183406,尽管我只需要更改祖父母类set方法。请参阅上面我的测试类。不确定这是否会在以后产生其他不必要的问题