james_dean
james_dean

Reputation: 1517

Abstract Methods vs Inheritance

I am trying to learn more about class design and have come across a dilemma. Say I have an online auction with three abstractions: Sale, Seller and Buyer. A Sale has a Seller and Buyer.Both Seller and Buyer have similar sets of fields, such as name, telephone number and address and it would make sense to group them into a single class, say Person. We could then centralize the code, for the fields and accessors in an Abstract Person class and have specific types for Teacher and Student.

This might lead to code such as:

class Sale {
    Person teacher;
    Person student;

    String description;
    int hourlyRate;

    // Some lesson methods
}

abstract class Person {
    private String name;
    private String address;
    private String telephoneNumber;
    // Getters & setters...
}

class Seller extends Person {
    // Some teacher stuff   
}

class Buyer extends Person {
    // Some student stuff
}

Now, application needs incorporate business-to-business customers, but because Sellers and Buyers are of type Person, they don't fit into our class hierarchy. If we used an interface, this could be prevented but we'd need to duplicate the different contact fields.

What's the best way out of this situation?

Upvotes: 0

Views: 117

Answers (3)

bmeurant
bmeurant

Reputation: 3287

Consider using composition over inheritance for your contact fields that are not properly part of your business but rather a shared tool. For instance :

class Identity {
    private String name;
    private String address;
    private String telephoneNumber;
    // Getters & setters...

    // behaviours
}

class Seller {
    private Identity identity;
    // Getters & Setters

    // behaviours   
}

class Buyer {
    private Identity identity;
    // Getters & Setters

    // behaviours
}

Thus, you can share Identity contact information related behaviours through Buyer and Seller classes while keeping your Type hierarchy to really significant business related functionalities

Upvotes: 1

Hovercraft Full Of Eels
Hovercraft Full Of Eels

Reputation: 285403

Consider extension through composition rather than inheritance. And in doing this you could use both abstract classes and interfaces, where sellers and buyers contain an agent of some sort defined by an interface, and that have your person abstract class implement the interface as well has have the abstract Business client implement the interface.

For example

//  both buyer and seller
class BusinessEntity {
  // an interface that can be a person, or a business
  private Agent agent;

Then the Person class...

abstract class Person implements Agent {

}

and the Business class

abstract class Business implements Agent {

}

and consider setting things up so that it would be easy to use dependency injection to change the agent held by your BusinessEntity

Upvotes: 3

fpw
fpw

Reputation: 799

Rename Person to NaturalPerson and derive it from BusinessObject or whatever name might be fitting in your jurisdiction. You can then derive Person and Business from there.

Upvotes: 0

Related Questions