2016-09-06 56 views
2

我有一個關於繼承的問題/強制給Java中的某個屬性賦予某個屬性我不確定,即使我花了很多時間思考它。我會盡量做到儘可能簡單。強制子類中的Java屬性類型

所以從來就得到了一個抽象Foo,其中有龍目註釋@Data

@Data 
public abstract class Foo{ 

private String id; 
protected BoundType type; 

public abstract void setBoundType(BoundType boundType); 
} 

這裏是枚舉BoundType

public enum BoundType { 

    IN, OUT; 
} 

而從來就得到了另外兩個類別InFooOutFoo,其延伸FooboundTypeInFoo應始終是枚舉類型IN。另一方面,OutFoo中的boundType應始終爲枚舉類型OUT。例如:

@Data 
public class InFoo extends Foo{ 

public void setBoundType() { 
    //ALWAYS HAS TO BE BoundType.IN 
} 
} 

我該如何執行此操作?不知道如何設計它。提前致謝。

+0

」不是個如果我們在InFoo類中將BouudType定義爲私有變量並且不暴露其getter和setter,那麼它會好嗎? –

+0

這是不是打破了讓子類定義類型的繼承原則? –

+1

是的,但任何我們強迫價值的方法都必須是IN或OUT,所以我認爲把它的二傳給他的孩子是沒有什麼意義的,因爲即使有二傳手,我們也需要限制孩子設置具體的價值只有 –

回答

2

確保構造函數爲每個子類設置正確的值,然後確保沒有setter,以便無法更改該值。

此外,請參閱此帖子Omitting one Setter/Getter in Lombok關於如何省略Boundter字段的setter。

+0

非常感謝,我實際上已經與Lombok一起強制執行此設置,但不知道如何實際執行此操作。你能否添加代碼? –

+0

嗯,我現在看不出來,但據我所見,你所要做的就是在你的Foo類的受保護的BoundType類型前面添加@Setter(AccessLevel.NONE),這意味着龍目島不會爲這個字段生成一個setter(這是你想要的)。 – Brumlebarten

+0

我在答案和@Beethoven答案之間做了某種混合,但即使我在Foo中使用註釋AllArgsConstructor,我也不能在InFoo和OutFoo中使用超級,它不被識別。任何提示?我是新龍目島 –

1

的正確值應該在子類的構造函數中設置:

public InFoo() { 
    boundType = BoundType.IN; 
} 

如果需要使用二傳手模式,您可以進行檢查,有:

public void setBoundType(BoundType boundType) { 
    if(boundType != BoundType.IN) 
     throw new IllegalArgumentException(); 
    this.boundType = boundType; // This line is actually unnecessary 
} 
+0

如果我這樣做,保持抽象類是否有意義? –

+0

是的,如果直接創建'Foo'的實例沒有意義,但只能創建其子類的實例。 – Beethoven

+0

那裏的有效點 –