When is it suitable to use inheritance [duplicate]

I recently had a small “argument” about inheritance with a friend. I think people overuse it a lot. Intuition tells me that that the only good reason for class inheritance is polymorphism – when there is a case that you want to treat uniquely object of different but related classes.

Our argument was about having a BaseEntity class for Entity Framework that only has Id property. My friend says it’s good because he can have generic repositories then. W don’t agree with him.

  1. Usually there’s no such thing as a generic repository, you’ll end up with “Refused bequest” smell.
  2. What’s the point of treating let’s say a user and an invoice uniquely? These are 2 totally different things.

Unfortunately I couldn’t make any good points in spite of “it makes no sense”. 🙂

After a while I also realized that I drifted away from inheritance itself and now I tend to use interfaces instead. Actually in my recent web project (quite a big one) I can’t recall any inheritance. Now I’m not sure when it is an appropriate technique anymore.

So guys, please help me here.

  1. What do you think about what I wrote?
  2. Can you find any arguments I can use against my friend?
  3. When it really is a good practice to use inheritance? (Please be specific and throw some examples)

Please don’t try to explain to me what the inheritance is all about. I’m very familiar with that and I used it a lot. Like I mentioned above, over time I just drifted away from it, because I couldn’t find the right usage for it. Simply interfaces seem to be a better approach to me in most cases.

3

Like you, I tend to favor composition over inheritance. However, let me give you an example where I find inheritance works really well…

Let’s say you have a screen where you’re editing a list of Users. So you have an entity called User which is your persistence object. Then I prefer to present a flattened model of this to my UI for editing, since there’s usually extra logic and checks going on:

class User
{
    public string Name { get; set; }
    public DateTime DateOfBirth { get; set; }
}

interface IEditUser
{
    string Name { get; set; }
    DateTime DateOfBirth { get; set; }
    int Age { get; }
    void CommitChanges();
    void Delete();
}

Now when there’s editing going on, we need to load the list of Users with the initial values, let them be edited, and then you can choose whether to Save or Cancel those changes. Since handling a newly created User is much different than handling an existing User (some fields are only edited in one of those situations, the code for persisting them are different, etc.). That’s why I like to do this:

abstract class EditUserBase : IEditUser
{
    public string Name { get; set; }
    public DateTime DateOfBirth { get; set; }
    public int Age { get { return DateTime.Today.Year - this.DateOfBirth.Year; } }
    public abstract void CommitChanges();
    public abstract void Delete();
}

Then my class for tracking new users added to the list (but not saved to the database):

class EditNewUser : EditUserBase
{
    public EditNewUser()
    {
        this.Name = string.Empty;
        this.DateOfBirth = DateTime.Today;
    }

    public override void CommitChanges()
    {
        var user = new User()
            {
                Name = this.Name,
                DateOfBirth = this.DateOfBirth,
            };
        // persist to database
    }

    public override void Delete() {} // nothing to do
}

…and finally a class for tracking changes to existing entities:

class EditExistingUser : EditUserBase
{
    private readonly User existingUser;

    public EditExistingUser(User existingUser)
    {
        this.existingUser = existingUser;
        this.Name = existingUser.Name;
        this.DateOfBirth = existingUser.DateOfBirth;
    }

    public override void CommitChanges()
    {
        this.existingUser.Name = this.Name;
        this.existingUser.DateOfBirth = this.DateOfBirth;
        // possibly make database call here
    }

    public override void Delete()
    {
        // code to delete this.existingUser from database
    }
}

I’ve found this works really well. It separates my editing logic from my entities, and separates the logic of creating a new entity from editing an existing one. It also creates a place to put logic that’s common to both new and existing entities (such as the Age calculated property, and yes I know it’s not implemented right 🙂

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật