2012-03-27 41 views
3

我使用hibernate和id ...用於持久性(這就是爲什麼它在比較中被省略)。 (另外,使用谷歌番石榴幫手等於)我如何正確覆蓋在java中的繼承等於?

HolidayPackageVariant:

public abstract class HolidayPackageVariant { 
    private Integer idHolidayPackageVariant; 
    private HolidayPackage holidayPackage; 
    private String typeHolidayPackage; 

@Override 
public boolean equals(Object obj) { 
    if (obj == this) 
     return true; 
    if(obj == null) 
     return false; 

    if (getClass().equals(obj.getClass())) { 
     final HolidayPackageVariant otherPackageVariant = (HolidayPackageVariant) obj; 
     return Objects.equal(getTypeHolidayPackage(),otherPackageVariant.getTypeHolidayPackage()) 
       && Objects.equal(getHolidayPackage(), 
         otherPackageVariant.getHolidayPackage()); 
    } 
    return false; 
} 

@Override 
public int hashCode() { 
    return Objects.hashCode(getTypeHolidayPackage(), getHolidayPackage()); 
} 

FlightHolidayPackageVariant:

public final class FlightHolidayPackageVariant extends HolidayPackageVariant{ 
    private Destination originCity; 
    public boolean equals(Object obj) { 
    // .. 

我應該完全覆蓋了equals()或者我應該調用super.equals(.. 。) 某種程度上來說 ?

+2

getClass()。equals(obj.getClass()) - >如果obj爲null,則爲NPE。 – aviad 2012-03-27 08:32:48

+6

[平等的祕密](http://www.angelikalanger.com/Articles/JavaSolutions/SecretsOfEquals/Equals.html); [Effective Java](https://docs.google.com/viewer?a=v&q=cache:qjZ_JbpnXCUJ:java.sun.com/developer/Books/effectivejava/Chapter3.pdf+effective+java+equals&hl=en&gl=uk&pid = BL&srcid = ADGEESith0oQAHumur5q4botdHMQ2NK7pVUOZBXXeQk_Pcu-mh2V0hXFmDkyE3H50j5RtvvTWcqjq62EaK27r9Y0UzQDTaOXYQp2mrYJNCngyeRblQ4taQx4tucpV1He2BSkI8zLRZM5與SIG = AHIEtbR9cAUIlgBoIS1NqH5eCPPR-7HitA) – McDowell 2012-03-27 08:47:48

+0

@aviad更新的空檢查答案。 – brainydexter 2012-03-27 09:20:02

回答

2

Secret of Equals

HolidayPackageVariant:

public abstract class HolidayPackageVariant { 
    private Integer idHolidayPackageVariant; 
    private HolidayPackage holidayPackage; 
    private String typeHolidayPackage; 

    @Override 
    public boolean equals(Object obj) { 
     if (obj == this) return true; 
     if(obj == null) return false; 

     if (getClass().equals(obj.getClass())) { 
      final HolidayPackageVariant otherPackageVariant = (HolidayPackageVariant) obj; 
      return Objects.equal(getTypeHolidayPackage(),otherPackageVariant.getTypeHolidayPackage()) 
        && Objects.equal(getHolidayPackage(), 
          otherPackageVariant.getHolidayPackage()); 
     } 
     return false; 
    } 
} 

FlightHolidayPackageVariant:

public final class FlightHolidayPackageVariant extends HolidayPackageVariant{ 
    private Destination originCity; 

    @Override 
    public boolean equals(Object obj) { 

     if(super.equals(obj)){ 
      return Objects.equal(getOriginCity(), 
        ((FlightHolidayPackageVariant)(obj)).getOriginCity()); 
     } 
     return false; 
    } 
} 

這將確保變種只有相同類型是彼此相等。

+0

在'FlightHolidayPackageVariant'中,兩行if(obj == this)返回true; if(obj == null)return false;'完全沒有必要,因爲這些測試是在'super.equals(obj)'中執行的第一個測試。 – 2012-03-27 12:39:15

+0

@ogregoire:真的! :(我的大腦只是沒有直接思考 – brainydexter 2012-03-27 12:45:06

+0

這個鏈接似乎完全忽略了可替換性的問題,這很重要,作者甚至引用了Effective Java,因此似乎她發現了EJ還沒有的東西,但EJ已經認爲她解決方案並駁斥它 – 2012-03-27 14:44:09

3

這就是你應該如何實現數據對象:不允許繼承,僅限構成。

這些是不可變的對象,但您可能想要修改它們,因此在需要時刪除final。你也可以從類定義中刪除final,因爲Hibernate不支持它,但在這種情況下,你應該記錄這些類不適合繼承。

主要的優點是有效的Java加上描述的所有的,在這種情況下,你不必通過Hibernate管理繼承,這有時會是一個真正的痛苦。

public final class HolidayPackageVariant { 
    private final Integer idHolidayPackageVariant; 
    private final HolidayPackage holidayPackage; 
    private final String typeHolidayPackage; 

    ... 

    @Override 
    public boolean equals(Object obj) { 
    if (obj == this) 
     return true; 
    if (!(obj instanceof HolidayPackageVariant)) 
     return false; 

    HolidayPackageVariant that = (HolidayPackageVariant) obj; 
    return Objects.equal(this.typeHolidayPackage, that.typeHolidayPackage) 
     && Objects.equal(this.holidayPackage, that.holidayPackage); 
    } 

    @Override 
    public int hashCode() { 
    return Objects.hashCode(this.typeHolidayPackage, this.holidayPackage); 
    } 
} 

public final class FlightHolidayPackageVariant { 
    private HolidayPackageVariant holidayPackageVariant; 
    private Destination originCity; 

    ... 

    public HolidayPackageVariant asHolidayPackageVariant() { 
    return this.holidayPackageVariant; 
    } 

    public boolean equals(Object obj) { 
    if (obj == this) 
     return true; 
    if (!(obj instanceof FlightHolidayPackageVariant)) 
     return false; 

    FlightHolidayPackageVariant that = (FlightHolidayPackageVariant) obj; 
    return Objects.equal(this.holidayPackageVariant, that.holidayPackageVariant) 
     && Objects.equal(this.originCity, that.originCity); 
    } 

    @Override 
    public int hashCode() { 
    return Objects.hashCode(this.holidayPackageVariant, this.originCity); 
    } 
} 
+0

我一直在想這個問題,我想到的一個問題是,在我的HolidayPackage中,我存儲了一個Set 變體;指向具體HolidayPackageVariant的實現,即LandHolidayPackageVariant和FlightHolidayPackageVariant。如果我將它改爲組合,那麼如何存儲r對該套裝中的「FlightHolidayPackageVariant」的引用? – brainydexter 2012-03-28 09:59:28

+0

你真的需要把他們全部放在一個集合嗎?難道你不能使用幾個集合,你可以在需要時使用番石榴的'Iterables.transform(Iterable,Function)'來聚合? – 2012-03-28 11:08:26