我怎样才能参考当前课程的类型? [英] How can I refer to the type of the current class?

查看:99
本文介绍了我怎样才能参考当前课程的类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一种很难解释的问题,但我到处寻找,我找不到任何好的答案。

我也看到堆栈溢出问题 我怎样才能引用一个接口在Java中实现的类类型? 如何返回与使用传入的类相同类型的对象的实例Java 6? ,但他们无法回答我的问题。我有一个例外,当我申请继承。



有一个例子,使它更容易理解:



假设我有一个名为SelfMaker的接口:

  public interface SelfMaker< SELF> {
public SELF getSelf );
}

A有一只狗,可以和另一只狗一起生产。所以狗是一个SelfMaker,就像这样:

  public class Dog实现SelfMaker< Dog> {
字符串颜色;

public String toString(){
returnsome+ color +dog;
}

public dog procreate(Dog anotherDog){
Dog son = getSelf();
son.color = color;
返回儿子;


@Override
public Dog getSelf(){
return new Dog();
}
}

但是,我有一个DomesticDog,他是狗,但它有一个可爱的家庭谁命名他。像这样:

  public class DomesticDog extends Dog {
private String name;

public String toString(){
return super.toString()+named+ name;


$ / code $ / pre

现在我有一些类可以处理一些事情那就是SelfMaker,我们称之为Couple。像这样:

  public class Couple< T extends SelfMaker< T>> {
私人T第一;
私人T秒;

public String toString(){
return first.toString()+and+ second.toString();
}
}

例外:



当我想创建一对 DomesticDog s时出现异常。像这样:

  public class CoupleOfDomesticDogs extends Couple< DomesticDog> {
public DomesticDog procreate(){
DomesticDog son = first.procreate(second);
返回儿子;


$ / code $ / pre

这会在< DomesticDog> 抱怨:绑定不匹配:类型DomesticDog不是绑定参数的有效替代< T extends SelfMaker< T>>夫妻< T>



我已经尝试将类Couple的广义变量更改为:夫妻< T延伸SelfMaker<>>< / code>但儿子不会是DomesticDog(我想让儿子成为DomesticDog)。如果我添加一些演员,那么它会编译,但它会更清晰。



所以...这是一个问题:有没有办法做到这一点,没有castings and generalizations?

解决方案

没有办法,我可以想到在不铸造的情况下做到这一点。如果您覆盖DomesticDog的procreate和getSelf方法并更改class类的声明,您的问题将得到解决:

  public类DomesticDog扩展Dog {
私有字符串名称;

public DomesticDog procreate(Dog anotherDog){
return(DomesticDog)super.procreate(anotherDog);
}

public Dog getSelf(){
return new DomesticDog();


public String toString(){
return super.toString()+named+ name;
}
}

公共类Couple< T扩展SelfMaker< super T>> {
首先保护T;
保护T秒;

public String toString(){
return first.toString()+and+ second.toString();




$ b如果你不想重写getSelf()在Dog的每个子类中,您都可以在类Dog中进行以下更改:

  public Dog getSelf(){
类< ;?延伸狗> thisClass = this.getClass();
尝试{
return thisClass.newInstance();
} catch(InstantiationException e){
} catch(IllegalAccessException e){
}
抛出新的UnsupportedOperationException(thisClass
+不提供public no-arg构造函数);



$ b

这保证getSelf()返回的每个值都是 this.getClass()。但是你仍然必须为子类投影procreate()的返回值。没有办法明确指定返回类型为 this.getClass()


This is kind of difficult to explain, but I've looked everywhere, and I couldn't find any good answer.

I've also seen Stack Overflow questions How can I refer to the class type a interface is implementing in Java? and How do I return an instance of an object of the same type as the class passed in using Java 6?, but they couldn't answer my question. There is an exception when I apply inheritance.

There is an example, to make it easier to understand:

Let's say I have some interface called SelfMaker:

public interface SelfMaker <SELF>{
    public SELF getSelf();
}

And A have a Dog, which can procreate with another dogs. So the dog is a "SelfMaker", like this:

public class Dog implements SelfMaker<Dog> {
    String color;

    public String toString() {
        return "some " + color + " dog";
    }

    public Dog procreate(Dog anotherDog) {
        Dog son = getSelf();
        son.color = color;
        return son;
    }

    @Override
    public Dog getSelf() {
        return new Dog();
    }
}

But then, I have a DomesticDog, who is a Dog, but it has a lovely family who named him. Like this:

public class DomesticDog extends Dog {
    private String name;

    public String toString() {
        return super.toString() + " named " + name;
    }
}

Now, I have some class that handles couples of things that are "SelfMaker"s, let's call this class "Couple". Like this:

public class Couple<T extends SelfMaker<T>> {
    private T first;
    private T second;

    public String toString() {
        return first.toString() + " and " + second.toString();
    }
}

THE EXCEPTION:

The exception comes when I want to create a couple of DomesticDogs. Like this:

public class CoupleOfDomesticDogs extends Couple<DomesticDog>{
    public DomesticDog procreate(){
        DomesticDog son = first.procreate(second);
        return son;
    }
}

This will throw an exception on <DomesticDog> complaining: Bound mismatch: The type DomesticDog is not a valid substitute for the bounded parameter <T extends SelfMaker<T>> of the type Couple<T>

I have already tried to change the generalised variable from class Couple to this: Couple<T extends SelfMaker<?>> but the "son" won't be a DomesticDog (and I want the "son" to be a DomesticDog). If I add some cast, then it will compile, but it will be less legible.

So... here is the question: Is there a way to achieve this without castings and generalizations?

解决方案

There is no way that I can think of to do this without casting. Your problem will be solved if you override the procreate and getSelf methods of DomesticDog and change the declaration of class Couple as such:

public class DomesticDog extends Dog {
    private String name;

    public DomesticDog procreate(Dog anotherDog) {
        return (DomesticDog)super.procreate(anotherDog);
    }

    public Dog getSelf() {
        return new DomesticDog();
    }

    public String toString() {
        return super.toString() + " named " + name;
    }
}

public class Couple<T extends SelfMaker<? super T>> {
    protected T first;
    protected T second;

    public String toString() {
        return first.toString() + " and " + second.toString();
    }
}

If you don't want to override getSelf() in every subclass of Dog, you could make the following change in class Dog:

public Dog getSelf() {
    Class<? extends Dog> thisClass = this.getClass();
    try {
        return thisClass.newInstance();
    } catch (InstantiationException e) {
    } catch (IllegalAccessException e) {
    }
    throw new UnsupportedOperationException(thisClass 
                         + " does not supply a public no-arg constructor");
}

This guarantees that every value returned by getSelf() is an instance of this.getClass(). But you would still have to cast the return value of procreate() for subclasses. There is no way to explicitly specify a return type as this.getClass().

这篇关于我怎样才能参考当前课程的类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆