Composition vs Inerhitance in java

description:

  • I need write a new DTO(data transfer object) class AppleRequest use some of PriceRequest DTO class member.
  • The database table field be like:
ID, supplier_id, supplier_name, size, color, price, etc
  • I got a class PriceRequest which I can’t change it, but my co-workers may change its member into @NotBlank in the future. So if I use inherit to achieve it, it may not work in the future.
  • The AppleRequest class and PriceRequest class don’t have the “is-a” relationship, it means not all AppleRequest is PriceRequest.In other words,they don‘t have any obvious father-son relationship, just share some of member.
  • They are both DTO to a same database table.

code:

  • PriceRequest:
@Data
public class PriceRequest {
    private int id;

    @NotBlank
    private String supplierId;
    //maybe @NotBlank in the future
    private String supplierName;
}
  • AppleRequest:
@Data
public class AppleRequest extends PriceRequest {
    private String color;

    private String size;
}
  • main
public class Sandbox {

    public static void main(String[] args)
    {
        AppleRequest apple = new AppleRequest();
        apple.setId(1);
        apple.setColor("red");
        apple.setSupplierName("");
        System.out.println("id:"+apple.getId()+" SupplierName:"+apple.getSupplierName()+" Color:"+apple.getColor());
    }
}

what I have tried:

  • just copy-paste all member I need in PriceRequest into AppleRequest. But it seems a little stupid.
@Data
public class AppleRequest {
    private int id;
    
    private String supplierName;

    private String color;

    private String size;
}

question:

  • Should I use composition instead of inherit, or any better way to deal with this situation?
  • How to avoid the change of PriceRequest make AppleRequest not working.

  • 1

    Composition would be class Apple { private Father father; /* apple members: color, size */ }. I find the example very hard to follow, how is a Father related to an Apple? Could you maybe pick more obvious class names, e.g. Car/Wheel, Father/Child, House/Room?

    – 

  • I use these name on purpose, because these two classes don’t have any obvious father-son relationship in logic. @knittl

    – 




  • 1

    Yes but what kind of relationship do these classes have if it’s not an is-a relationship?

    – 

  • Why do you have public member fields in these classes at all? And you didn’t show a reason for inheritance so far – just because names of a field or method are the same, this doesn’t mean you should inherit. In total the code in your question looks completely made up, and as you are writing yourself at the beginning, it might be a complete X-Y problem, not just by the title but also by the content.

    – 

  • 1

    So are the two request classes in any way related or not? Would a base class make sense, i.e. both requests have fields that always need to be identical? Or do they simply share fields that have the same name and (currently) the same type? In the latter case, these are independent classes and you should keep them independent (each class defining its own fields – it does not matter that the other class has fields of the same name)

    – 




As pointed out in the comments. Composition vs Inerhitance.

class Apple extends Father{};

Then the apple has all of the fields/methods of Father. If you want to use composition.

class Apple{
    Father father;
}

Now the Apple has all of the data of a Father, but it doesn’t have to inherit.

Your example doesn’t really show why the two classes are related, so it is hard to justify one or the other. Consider setId. In the inheritance case, you can just use the fathers method. In the composition, you might need to delegate.

public void setId(int id){
    father.setId(id);
}

Which is a bit cumbersome in this simple example probably just repeating the fields is a better way.

Leave a Comment