简体   繁体   English

我怎样才能引用当前类的类型?

[英]How can I refer to the type of the current class?

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? 我也看过Stack Overflow问题如何引用接口在Java中实现的类类型? and How do I return an instance of an object of the same type as the class passed in using Java 6? 如何返回与使用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: 假设我有一些名为SelfMaker的界面:

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

And A have a Dog, which can procreate with another dogs. A有一只狗,可以与另一只狗生育。 So the dog is a "SelfMaker", like this: 所以狗是一个“SelfMaker”,像这样:

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". 现在,我有一些课程处理“SelfMaker”的事情,让我们把这个课称为“情侣”。 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 DomesticDog s. 当我想创建一些DomesticDog时会出现异常。 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> 这将在<DomesticDog>上引发异常抱怨: 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). 我已经尝试将类中的通用变量更改为: Couple<T extends SelfMaker<?>>但是“son”不是DomesticDog(我希望“son”成为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: 如果覆盖DomesticDog的procreate和getSelf方法并更改类Couple的声明,则问题将解决:

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: 如果你不想在Dog的每个子类中覆盖getSelf(),你可以在类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() . 这保证)由getSelf(返回的每个值的一个实例this.getClass() But you would still have to cast the return value of procreate() for subclasses. 但是你仍然需要为子类强制转换procreate()的返回值。 There is no way to explicitly specify a return type as this.getClass() . 无法将返回类型显式指定为this.getClass()

You will have to make Dog generic and abstract, with a type parameter that indicates the result of getSelf() . 你必须使用Dog通用和抽象,使用一个类型参数来指示getSelf()的结果。 Each type of Dog will then need to implement this with themselves as the parameter: 然后,每种类型的Dog都需要将它们作为参数实现:

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

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

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

}

public class DomesticDog extends Dog<DomesticDog> {
    private String name;

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM