2013-11-04 72 views
2

我正在练习泛型,我做了以下操作。类型参数E隐藏类型E.类的泛型模板

创建一个名为man的类,如下所示。

public class Man{ 
int hands=2; 
int legs=2; 
boolean alive; 

public Man(boolean b) { 
    // TODO Auto-generated constructor stub 
    alive=b; 
} 

}

创建了一个名为Person类

public class Person<Man> { 
Man p; 
String name; 


public Person(Man p, String name) { 
    this.p = p; 
    this.name = name; 
} 
public Person() { 
    // TODO Auto-generated constructor stub 
} 

} 

试图一个人字符串类型的实例或者按照下面的诠释,它dosent抛出一个错误。

Person<String> p1 = new Person<String>(new String("test"), "test1"); 
    Person<Integer> p2=new Person<>(1,"test"); 

当我仔细检查,我得到了以下警告。 “类型参数Man是隐藏类型的人”

所以我明白,将Man作为类Person的类型参数与在Java示例中给出'E'一样好。它不是Man.class。为什么发生这种情况? 如何将我的Man.class分配为泛型类型参数?

你可以给我一些很好的问题/练习习题来学习泛型。

+2

因为'Man'是同一个包中类的名字。只需将您的通用名称从'Person '更改为'Person '或其他与“Man”或任何其他类别不相似的其他名称。 –

+0

我不明白。如果你想'Person'参考实际的'Man'类,并且你不希望'Person '和'Person '被允许,那你为什么还要使用泛型?看起来你只是想要一个普通的'Person'类,它通常指的是普通的'Man'类,没有任何参数化。 – ruakh

+0

人既不是人的子类也不是超人类。如果我有动物和植物类型的类,我想限制它们被用作Person的泛型类型。 – DJR

回答

4

因为Man是同一包中类的名称。只需将您的通用名称从Person<Man>更改为Person<T>或其他不类似的东西,也可以将Man或其他任何类别的名称都更改。

更多关于泛型:


看起来你想要的Person只有Man使用泛型属性。您将需要具有一个定义泛型的超类,并且Person将继承它,并将其定义为使用Man作为使用的类。简短的例子:

public abstract class AliveBeing<T> { 
    protected T livingBeing; 
    public AliveBeing(T livingBeing) { 
     this.livingBeing = livingBeing; 
    } 
} 

public class Person extends AliveBeing<Man> { 
    //now your livingBeing field is from Man type... 
    public Person(Man man) { 
     super(man); 
    } 
} 

这将使它,但IMO这种设计是奇怪的。为了得到更好更准确的答案,最好多解释一下你当前的问题。

注意区别:

//case 1 
public class Foo<T> { 
    //... 
} 

//case 2 
public class Bar<E> extends Foo<E> { 
    //... 
} 

//case 3 
public class Baz extends Foo<String> { 
    //... 
} 

在第一种情况下,Foo使用一个通用类,你可以通过T指这一类。在第二种情况下,BarFoo延伸,并宣布使用其自己的泛型类,你可以通过E参考,但是,这个E将从Foo使用(而不是T这将是E)相同的通用。在第三种情况下,Baz类扩展自Foo,但它不会定义任何通用行为,而是声明Foo中使用的通用类是String

+0

人既不是人的子类也不是超人类。如果我有类型的动物和植物类,我想限制它们被用作人类的通用类型 – DJR

+0

我从来没有说过“人类”是“人”的超类或子类,也不是反义词。请重新阅读答案。 –

+0

那么我如何限制植物或动物类被用作类型参数? – DJR