大家好,最近写一个涉及泛型的测试,真是死的心都有:
遇到如下问题,请高手指正:
1
public interface ILogicalProcess<LP,S extends AbstractState> extends IModel {
声明了这样一个接口,
但是在使用时,我希望把LP替换为一个ILogicalProcess类型,但似乎进入了一个递归的定义。,这样做是否合法,如果不合法,那么如何定义呢
这样写
ILogicalProcess<ILogicalProcess<ILogicalProcess<LP。,S extends AbstractState>
晕了,
2 父类型参数不能用子类替换的问题:
我声明了如下的类,
public class simpleLogicalProcess<LP,S extends AbstractState> extends
LogicalProcess<LP,S>{其中,一个函数changestate可以返回AbstractState类型的数据,
而另一个函数setInnerstate可以接受S类型的数据,但我在进行如下调用时
setInnerstate(((SimpleEvent)event).changestate(this.getInnerstate()));
居然报错:
The method setInnerstate(S) in the type simpleLogicalProcess<LP,S> is
not applicable for the arguments (AbstractState)不会吧public class simpleLogicalProcess<LP,S extends AbstractState> extends
LogicalProcess<LP,S>{
//WB do i really need the flexibility?
private S innerstate;
public simpleLogicalProcess() {
super();
// TODO Auto-generated constructor stub
} public simpleLogicalProcess(String name) {
super(name);
// TODO Auto-generated constructor stub
} @Override
public ArrayList<LP> influenced() {
// TODO Auto-generated method stub
return super.influenced();
} @Override
public ArrayList<IEvent<LP, ?, ?>> out() {
// TODO Auto-generated method stub
return super.out(); } @Override
protected void sendEvent(IEvent<LP, ?, ?> event) {
// TODO Auto-generated method stub
super.sendEvent(event);
} @Override
public void run(IEvent<?, ?, ?> event) {
// TODO Auto-generated method stub
if (event instanceof SimpleEvent)
{
setInnerstate(((SimpleEvent)event).changestate(this.getInnerstate()));
} } public S getInnerstate() {
return innerstate;
} public void setInnerstate(S innerstate) {
this.innerstate = innerstate;
}}
interface SimpleEvent extends IEvent{ public AbstractState changestate(AbstractState raw); }
遇到如下问题,请高手指正:
1
public interface ILogicalProcess<LP,S extends AbstractState> extends IModel {
声明了这样一个接口,
但是在使用时,我希望把LP替换为一个ILogicalProcess类型,但似乎进入了一个递归的定义。,这样做是否合法,如果不合法,那么如何定义呢
这样写
ILogicalProcess<ILogicalProcess<ILogicalProcess<LP。,S extends AbstractState>
晕了,
2 父类型参数不能用子类替换的问题:
我声明了如下的类,
public class simpleLogicalProcess<LP,S extends AbstractState> extends
LogicalProcess<LP,S>{其中,一个函数changestate可以返回AbstractState类型的数据,
而另一个函数setInnerstate可以接受S类型的数据,但我在进行如下调用时
setInnerstate(((SimpleEvent)event).changestate(this.getInnerstate()));
居然报错:
The method setInnerstate(S) in the type simpleLogicalProcess<LP,S> is
not applicable for the arguments (AbstractState)不会吧public class simpleLogicalProcess<LP,S extends AbstractState> extends
LogicalProcess<LP,S>{
//WB do i really need the flexibility?
private S innerstate;
public simpleLogicalProcess() {
super();
// TODO Auto-generated constructor stub
} public simpleLogicalProcess(String name) {
super(name);
// TODO Auto-generated constructor stub
} @Override
public ArrayList<LP> influenced() {
// TODO Auto-generated method stub
return super.influenced();
} @Override
public ArrayList<IEvent<LP, ?, ?>> out() {
// TODO Auto-generated method stub
return super.out(); } @Override
protected void sendEvent(IEvent<LP, ?, ?> event) {
// TODO Auto-generated method stub
super.sendEvent(event);
} @Override
public void run(IEvent<?, ?, ?> event) {
// TODO Auto-generated method stub
if (event instanceof SimpleEvent)
{
setInnerstate(((SimpleEvent)event).changestate(this.getInnerstate()));
} } public S getInnerstate() {
return innerstate;
} public void setInnerstate(S innerstate) {
this.innerstate = innerstate;
}}
interface SimpleEvent extends IEvent{ public AbstractState changestate(AbstractState raw); }
解决方案 »
- xml和数据库,该如何选择~
- 怎样设置窗口的初始位置?
- 救急救急,哪位高手能解答一下!!
- 希望能帮忙简化一下代码,谢谢!
- 如何从html文本中提取内容?
- 讨论一下,java中的成员方法和static方法的区别
- 基础问题,关于byte[]!
- 给我一个JCREATOR的注册码?
- 请问:在java的自带例子中(demo/jfc/Notepad/resources)中的资源文件Notepad_zh_CN.properties内的\uXXXX怎么显示出来,我怎么输入?
- 增强for遍历集合
- 帮忙给个java中的 arraylist或vector··代码实现数组队列中元素的写入和读出
- 学Java和C++将来的方向问题,我是个初学者,望前辈们给点指点,谢谢
泛型的定义是为了解决Object需强制转换的问题以及通过这样的不安全操作。
例如public interface ILogicalProcess <LP,S extends AbstractState> extends IModel
这里的是泛型的定义,其中定义两个泛型变量,LP与S,而在当前定义类中不确定LP与S是什么类型的数据(当然你声明的是一个接口)
而后面定义的extends AbstractState并不是继承,他和后面定义的extends IModel不是一个概念了,这个定义的意思是LP与S必须是AbstractState的子类才是有效定义,这个定义过程由调用者来定义。
当你用到这个接口的时候,泛型可以这样来定义。
ILogicalProcess<Aclass,Bclass> ilp=ILogicalProcessFactory.getILogicalProcess();//假定你是这样获得这个接口的对象的。
那么Aclass,Bclass是一个实际存在的类(你自己要实现这些类),而且他们必须继承AbstractState这个类。那么我回答你的第二个问题
setInnerstate(((SimpleEvent)event).changestate(this.getInnerstate()));
这一句,我知道getInnerstate你获取了一个S类型,这个类型是当前类定义的一个泛型变量,而你setInnerstate是接收一个S类型。如果你直接这样set或者get是不会错的,但是你的changestate方法返回的是一个AbstractState类型,这个地方就会出错,虽然S类型一定是AbstractState的一个子类,但是当前类还不知道它是什么类型,只知道它是一个S类型,这个S类型要被调用者定义。而且此方法从逻辑上来推理,S类型一定是一个AbstractState的子类,但是你返回的是父类,父类的类型是不能被子类的类型所接受的,所以你需要强转一下,也就是改成
setInnerstate((S)((SimpleEvent)event).changestate(this.getInnerstate()));
有点疑问,这里是说我不能进行递归的定义,如
ILogicalProcess<ILogicalProcess <Aclass,Bclass>.......?第二个问题,我采用了如下方法
public void run(IEvent<?, ?, ?> event) {
// TODO Auto-generated method stub
if (event instanceof SimpleEvent)
{
setInnerstate(((SimpleEvent<S>)event).changestate(this.getInnerstate()));
}
}
interface SimpleEvent<S extends AbstractState>extends IEvent{
public S changestate(S raw); }
因为泛型类可以继承或者实现其它泛型类或接口,例如ArrayList<T>实现了List<T>接口。因此ArrayList<Base>可以被转换成List<Base>,( 装苹果的袋子仍然是袋子)此外向List<Base>中添加base和derived也是合法的。
但是将list2赋值给list3会导致编译错误,就像关于继承的那个经典问题一样:苹果可以是水果的子类,但是能够装苹果的袋子不是能够装水果的袋子的子类。////////////
class Test<Test<....
这种定义到底行不行啊?
/////////
如果你希望所谓的递归定义,你完全可以拆开来定义。
ILogicalProcess<Aclass,Bclass> a............
ILogicalProcess <ILogicalProcess,......> b..........然后回到第二个问题,依旧是那句话,泛型的S类型是需要外部定义的,在内部不能用实际类型,因为泛型定义类不知道S类型是什么类型。S是一个动态的类型,它把定义权利移交给了类的使用者。既然不知道S类型是什么类型,所以从某种程度上来说,定义类型不好直接用S类型中的方法,除非extends某类来告诉定义类它一定是某类的子类,无论你多么确定传入的是什么参数,但是泛型定义类不会知道,它只知道有S这么一个类型,至于它是什么不知道。
你用通配符参数类型只能说明泛型参数可以是某类型的子类型,如果单纯是个?,默认的是extends Object而已(当然你在类里面定义了是AbstractState,但是他跟通配符传参也不是一个概念)。
再者,我不知道你的IEvent 接口是哪个接口,有没有被ILogicalProcess 继承,因为两个类或者接口之间的泛型是不能混用的,即使他们都是定义的S类型而且同时继承AbstractState,但是那不是一个东西了,不要把它们主观的认为是同一个东西。
extends要保证所有父类型出现的地方都可以用子类进行替换。
implements要保证所有接口出现的地方都可以用任意实现进行替换。现在看楼主的递归的问题,主要是这个接口的定义:
public interface ILogicalProcess <LP,S extends AbstractState> extends IModel
其中的LP实际上是ILogicalProcess本身。由于ILogicalProcess接口出现的地方都可以用任意实现类进行替换,那么public ArrayList<LP> influenced()
protected void sendEvent(IEvent<LP, ?, ?> event)这两个方法中的泛型变量LP完全可以直接使用ILogicalProcess进行定义。所以ILogicalProcess接口可以这样定义:public interface ILogicalProcess <S extends AbstractState> extends IModel
{
....
public ArrayList<ILogicalProcess> influenced()
protected void sendEvent(IEvent<ILogicalProcess, ?, ?> event)
....
}这样在ILogicalProcess的定义中就不会出现楼主所说的递归的问题了,因为根本不需要定义LP这个泛型变量。
public void run(IEvent <?, ?, ?> event) {
// TODO Auto-generated method stub
if (event instanceof SimpleEvent)
{
setInnerstate(((SimpleEvent <S>)event).changestate(this.getInnerstate()));
}
}
这是一个非常非常不好的使用方式,因为你传入的三个泛型变量为无限定通配符参数,如果了解这个东西你会明白的。
无线定通配符参数是不能传入任何参数,返回参数只能是Object。
就像setInnerstate(S innerstate) 方法,如果你定义的是SimpleEvent <?>,那么很遗憾,编译器会拒绝传入任何参数,因为编译器无法确认?的参数类型。而且你返回的也是一个?,基于对java机制的理解,这个地方编译器也无法确认你要返回一个什么值,那么这个?只能被所有类的超类Object类接收。
说句实话,通配符类型确实是一个让人头疼的类型。而且我也觉得你还没理解泛型的真正作用。
还有最后要声明的是,你在ILogicalProcess <LP,S extends AbstractState> extends IModel 定义的S泛型类型和在interface SimpleEvent <S extends AbstractState>extends IEvent定义的S类型不是同一个东西,不要误以为他们是同一个东西,他们之间不能互相传递。
ILogicalProcess is a raw type. References to generic type
ILogicalProcess<LP> should be parameterized
对了
in which circunstance shall I use
1 public class Ping extends LogicalProcess<Ping,PingPongState>{
2 public class Ping <Ping,PingPongState>extends
LogicalProcess<Ping,PingPongState>{
Ping and PingPong state r concrete class3 public class Ping <T,E>extends LogicalProcess<T,E>
T E and letter for Generic
4 public class Ping <T,E>extends LogicalProcess<?,?>这四种情况声明类的继承关系的句子都是合法的吧?
simpleLogicalProcess
////////////package generic;
import java.util.ArrayList;
public class simpleLogicalProcess<LP,S extends AbstractState> extends LogicalProcess<LP>{
//WB do i really need the flexibility?
private Integer name;
private S innerstate;
public simpleLogicalProcess() {
super();
// TODO Auto-generated constructor stub
}
public simpleLogicalProcess(Integer id) {
name=id;
// TODO Auto-generated constructor stub
}
@Override
public ArrayList<LP> influenced() {
// TODO Auto-generated method stub
return super.influenced();
} @Override
public ArrayList<IEvent<LP, ?, ?>> out() {
// TODO Auto-generated method stub
return super.out();
} @Override
protected void sendEvent(IEvent<LP, ?, ?> event) {
// TODO Auto-generated method stub
//super.sendEvent(event);
}
public void run(IEvent<?, ?, ?> event) {
// TODO Auto-generated method stub
if (event instanceof SimpleEvent)
{
System.out.print("we are running"+((SimpleEvent<SonofState>)event).);
setInnerstate(((SimpleEvent<S>)event).changestate(this.getInnerstate()));
}
}
public static void main(String args[])
{
Event fly,land,refly;
simpleLogicalProcess<Integer,SonofState> runner1
=new simpleLogicalProcess<Integer,SonofState>((Integer)1);
simpleLogicalProcess<Integer,SonofState> runner2
=new simpleLogicalProcess<Integer,SonofState>((Integer)2);
fly=new SimpleEvent<SonofState>(2,1,123,1.0);
runner1.run(fly);
}
public S getInnerstate() {
System.out.print("we are getInnerstate");
return innerstate;
} public void setInnerstate(S Sinnerstate) {
this.innerstate = Sinnerstate;
System.out.print("we are setInnerstate"+Sinnerstate.state1);
}
}
class SimpleEvent<S extends AbstractState> extends Event
{
public int =1234;
public SimpleEvent(Integer to,Integer from,Integer news,Double newTime)
{
super( to, from, news, newTime);
}
public S changestate(S raw){
return raw;
} }///////////////////////////package generic;public class AbstractState { public static int state1=123;
}
/////////////////////package generic;public class SonofState extends AbstractState {
public static int sons=111;
public void printson(){
System.out.print(sons);
}
}/////////////
package generic;public class Event implements IEvent<Integer,Integer,Integer> { private Integer sender,reciever,message;
private Double Time;
public Event(Integer to,Integer from,Integer news,Double newTime)
{
sender=from;
reciever=to;
message=news;
Time=newTime;
}
@Override
public Double getTime() {
// TODO Auto-generated method stub
return Time;
}}
第一个问题interface ILogicalProcess <LP extends ILogicalProcess,S extends AbstractState>这样可以就可以吗?