2016-09-18 63 views
1

这是我第一次发布,但我遇到了很多麻烦的问题。 我现在有一个AbstractDevice类的标题:Java抽象,仿制药和建设者

public abstract class AbstractDevice<T extends AbstractDevice.Builder<T>> implements Device 

这个类与头嵌套生成器类:

public static abstract class Builder<T> 

我也有头一个AbstractPeripheral类:

public abstract class AbstractPeripheral<T extends AbstractPeripheral.Builder<T>> extends AbstractDevice<AbstractPeripheral.Builder> 

并且此类还具有其自己的嵌套构建器类,其标题为:

public static abstract class Builder<T> extends AbstractDevice.Builder<Builder>. 

我的目标是使AbstractPeripheral扩展AbstractDevice和AbstractPeripheral的构造器扩展AbstractDevice的。然而,在编译的时候我收到此错误:

类型参数uxb.AbstractPeripheral.Builder不是类型变量T.

任何帮助表示赞赏范围内。由于 抽象设备:

package uxb; 

import java.util.List; 
import java.util.Optional; 
import java.util.ArrayList; 
import java.math.BigInteger; 


public abstract class AbstractDevice<T extends AbstractDevice.Builder<T>>  
implements Device{ 

public static abstract class Builder<T>{ 

private Integer version; 

private Optional<Integer> productCode; 

private Optional<BigInteger> serialNumber; 

private List<Connector.Type> connectors; 

public Builder(Integer version){ 
    this.version = version; 
} //end constructor method 


public T productCode(Integer productCode){ 
    if(productCode != null){ 
    this.productCode = Optional.of(productCode); 
    } //end if statement 
    else{ 
    this.productCode = Optional.empty(); 
    } //end else statement 
    return getThis(); 
} //end method productCode() 

public T serialNumber(BigInteger serialNumber){ 
    if(serialNumber != null){ 
    this.serialNumber = Optional.of(serialNumber); 
    } //end if statement 
    else{ 
    /*Class has a static field for ZERO value*/ 
    this.serialNumber = Optional.empty(); 
    } //end else statement 
    return getThis(); 
} //end method serialNumber() 


public T connectors(List<Connector.Type> connectors){ 
this.connectors = connectors; 
return getThis(); 
} //end method connectors 


protected abstract T getThis(); 


protected List<Connector.Type> getConnectors(){ 
    return connectors; 
} //end method getConnectors() 


protected void validate(){ 
    if(version == null){ 
    throw new NullPointerException("Cannot be validated"); 
    } 
} //end method validate() 

} //end nested abstract class Builder 


private final Integer version; 

private final Optional<Integer> productCode; 


private final Optional<BigInteger> serialNumber; 

private final List<Connector.Type> connectors; 

private final List<Connector> connectorObjects; 


protected AbstractDevice(Builder<T> builder){ 
    this.version = builder.version; 
    this.productCode = builder.productCode; 
    this.serialNumber = builder.serialNumber; 
    this.connectors = builder.connectors; 
    ArrayList<Connector> temp = new ArrayList<Connector>(); 
    for(int i = 0; i < connectors.size(); i++){ 
    temp.add(new Connector(this, i, connectors.get(i))); 
    } //end for loop 
    connectorObjects = temp; 
} //end constructor method 



public Optional<Integer> getProductCode(){ 
return productCode; 
} //end method getProductCode() 


public Integer getConnectorCount(){ 
/*Not Implemented Yet*/ 
return 0; 
} //end method getConnectorCount() 



public Optional<BigInteger> getSerialNumber(){ 
return serialNumber; 
} //end method getSerialNumber() 


public Integer getVersion(){ 
return version; 
} //end method getVersion() 

public List<Connector> getConnectors(){ 
return new ArrayList<Connector>(connectorObjects); 
} //end method getConnectors() 


public Connector getConnector(int index){ 
    if(! getConnectors().isEmpty()){ 
    return getConnectors().get(index); 
} //end if statement 
else{ 
    return null; 
} //end else statement 
} //end method getConnector() 

} //end abstract class AbstractDevice 

摘要外设: 包UXB;

import java.util.List; 

public abstract class AbstractPeripheral<T extends 
AbstractPeripheral.Builder<T>> extends 
AbstractDevice<AbstractPeripheral.Builder>{ 

public static abstract class Builder<T> extends 
AbstractDevice.Builder<Builder>{ 

protected void validate(){ 
    super.validate(); 
    if(getConnectors().equals(null)){ 
    throw new IllegalStateException("Cannot be validated"); 
    } //end if statement 
    if(checkTypes(getConnectors())){ 
    throw new IllegalStateException("Cannot be validated"); 
    } //end if statement 
} //end method 

private boolean checkTypes(List<Connector.Type> types){ 
    for(Connector.Type type: types){ 
    if(type != Connector.Type.PERIPHERAL){ 
     return false; 
    } //end if statement 
    } //end for each loop 
    return true; 
} //end method checkTypes 

public Builder(Integer version){ 
    super(version); 
} //end constructor method 
} //end nested class Builder 

public AbstractPeripheral(Builder<T> builder){ 
super(builder); 
} 
} //end class AbstractPeripheral 

集线器: 包UXB;

public class Hub extends AbstractDevice<Hub.Builder>{ 

    public static class Builder extends AbstractDevice.Builder<Builder>{ 

public Builder(Integer version){ 
    super(version); 
} //end constructor method 

public Hub build(){ 
validate(); 
return new Hub(getThis()); 
} //end method build() 

protected Builder getThis(){ 
    return this; 
} //end method getThis() 

protected void validate(){ 
    super.validate(); 
    if(!(super.getConnectors().contains(Connector.Type.COMPUTER))){ 
    throw new IllegalStateException("Cannot be validated"); 
    } //end if statement\ 
    if(!(super.getConnectors().contains(Connector.Type.PERIPHERAL))){ 
    throw new IllegalStateException("Cannot be validated"); 
    } //end if statement 
} //end validate() 
} //end nested class Builder 

private Hub(Builder builder){ 
super(builder); 
} //end constructor method 

public DeviceClass getDeviceClass(){ 
return DeviceClass.HUB; 
} //end method getDeviceClass() 


} //end class Hub 
+0

你能发布实际的代码吗? – nitinsh99

+0

抽象溢出 – 2016-09-18 16:56:29

+0

什么是你的'意图>' – Kelvin

回答

1

你真的需要同时使用类正在兴建,的建设者,作为建设者参数。正在构建的对象不是而是需要了解构建器,但是,因此不需要它作为参数。

我已经在几个开源项目中使用了这种模式或略有变化,包括Apache Brooklyn和jclouds。

所以,从你的例子,如下更改父类:

public abstract class AbstractDevice implements Device { 
    public static abstract class Builder<T, B> { 
     public abstract B self(); 
     public abstract T build(); 
     public B example(String value) { 
      // do something with value 
      return self(); 
     } 
    } 
} 

注意,我添加了一个抽象build()方法为好,这将返回生成的对象。 self()方法是必需的,因为如果构建器方法返回this,它将具有错误的类型。相反,每个构建器方法都必须以return self();结尾,如​​所示。那么孩子就变成了:

public abstract class AbstractPeripheral extends AbstractDevice { 
    public static abstract class Builder<T, B> extends AbstractDevice.Builder<T, B> { 
    } 
} 

你可以看到TB通用参数被用来指向类的类型和制造商的分别类型。因此,为了使用这些具体的类,这样的事情应该被创建:

public class Hub extends AbstractPeripheral { 
    public static class Builder extends AbstractPeripheral.Builder<Hub, Builder> { 
     public static final Builder builder() { 
      return new Builder(); 
     } 
     public Builder self() { 
      return this; 
     } 
     public Hub build() { 
      return new Hub(); 
     } 
    } 
} 

这也有一个静态builder()方法,返回正确Builder类的实例,你也可以直接调用构造函数如果你想要的话。 build()方法只是创建并返回具体的类,并且self()方法实现这里返回this哪些将具有正确的类型。

将所有内容放在一起,我们可以用它来创建一个Hub对象如下:

Hub hub = Hub.Builder.builder() 
     .example("something") 
     .build(); 

注意,AbstractDevice.Builder#example(String)方法,因为它实际上是调用Hub#self()返回正确的类型,build()返回Hub具体实例如预期。

为了解决这个问题,并删除重复的样板,您也可以尝试使用Google AutoValue项目,我们现在在jcloud中切换到该项目。

+0

非常感谢你的帮助! –

+0

请注意,类型参数*仅*需要在构建器上,而不是正在构建的类上,我已更新答案以使其清晰 – grkvlt