
Ask HN: How often do you use inheritance? - _6cj7
It is widely taught in Intro to CS and Software Engineering classes, but how useful is it?
======
probinso
Inheritance is a great way to allow your newly defined class to interface with
the language syntax or system environment features in a useful way. Doing
something like inheriting from a dictionary in Python allows for you to extend
a very versatile tool that already exists, that has been optimized for use in
the language.

If you are going to bother inheriting from a class, then you should weigh the
cost of your code complexity against it. It is definitely worth it sometimes

If you wrote both the class and sub-class, then you're likely over engineering
the problem (unless you have a sufficiently large program you're working on)

------
tjalfi
I have used inheritance twice in the past two years. Here is the most recent
example. The code is from an iOS application written in Swift. The task was to
write a quiz application. I used a combination of a protocol and a base class
to avoid duplicating the code to advance to the next question. All view
controllers implement the Scorable protocol and the view controllers for
individual questions all inherit from ScorableViewController.

// Scorable.swift

import Foundation

    
    
      protocol Scorable {
        var totalScore : Int {get set}
      }
    
    

// ScorableViewController.swift

import UIKit

class ScorableViewController: UIViewController, Scorable {

    
    
        //overrides here...
        
        //This class exists to share the following code.
        var totalScore : Int = 0
        var currentChoice : Selection? = nil
        
        final var choseOption : Bool {
            get {
                return currentChoice != nil
            }
        }
        
        final override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
            precondition(choseOption, "must choose option before proceeding")
            precondition(segue.identifier != nil, "identifier is nil")
            precondition(!segue.identifier!.isEmpty, "identifier is empty")
            var dest = segue.destination as! Scorable
            dest.totalScore = Selection.add(score: totalScore, selection: currentChoice!)
        }
    }

------
twobyfour
Constantly. My company uses a popular framework that supports complex behavior
defined largely in a declarative manner using inheritance; with method
overrides for customizing business logic.

I also frequently use multiple inheritance and what are called "mix-in"
classes in python to make more complex customizations reusable.

~~~
wayn3
MixIn is just multiple inheritance rebranded.

~~~
twobyfour
Yes. Mixins are a particularly handy and slightly less dangerous form of
multiple inheritance than multiple inheritance from two fully-fledged and
usable classes (which IME causes more problems than it solves). I didn't
intend to imply they weren't multiple inheritance. Would it have been clearer
to have said "with" instead of "and"?

------
tony
Inheritance is helpful when the domain is well-defined and the underlying
problem is broadly similar enough to fill-in differences across what's being
abstracted.

Some hand-picked examples of well-implemented inheritance in open source:

An example of where inheritance makes great sense is Django CBV (Class-based
views), [https://docs.djangoproject.com/en/1.11/topics/class-based-
vi...](https://docs.djangoproject.com/en/1.11/topics/class-based-views/), as
well as Django REST Framework class views ([http://www.django-rest-
framework.org/api-guide/views/](http://www.django-rest-framework.org/api-
guide/views/))

An example of where inheritance in the form of _runtime metaprogramming_ makes
sense is SQLAlchemy declarative and Django ORM.

An example where inheritance in the form of _mixins_ make sense would be
Django ORM, such as TimeStampedModel in django-extensions
[https://github.com/django-extensions/django-
extensions/blob/...](https://github.com/django-extensions/django-
extensions/blob/365e7cf/django_extensions/db/models.py).

An example where classes make sense in standard libraries would be (impure)
interfaces such as csv.Dialect
([https://github.com/python/cpython/blob/6aee6fb/Lib/csv.py#L2...](https://github.com/python/cpython/blob/6aee6fb/Lib/csv.py#L24))

An example of where inherited classes make sense in abstraction would be types
([https://github.com/zzzeek/sqlalchemy/blob/master/lib/sqlalch...](https://github.com/zzzeek/sqlalchemy/blob/master/lib/sqlalchemy/sql/sqltypes.py))
and dialects in SQLAlchemy
([https://github.com/zzzeek/sqlalchemy/tree/master/lib/sqlalch...](https://github.com/zzzeek/sqlalchemy/tree/master/lib/sqlalchemy/dialects/postgresql))

As a closing note, It works a lot better when the use of inheritance
symbolically represents actual standards (SQL, HTTP, and/or standard libraries
API's) that developers already are familiar with, rather than abstract
concepts meaningful only to the writer.

------
foobarchu
Honestly, very rarely. Interfaces have been far more useful to me in my
career, as far as major OO concepts go. If I'm extending, it's usually because
someone brought in a new requirement after a products launch that requires
very similar, but not quite the same, behavior as existing work. For example,
we process data feed A already, and data feed B will be very similar. Rather
than modifying the existing A processor, its often easier to lift out an
abstract parent class and implement A and B as extensions of it. I almost
never find myself extending concrete classes.

------
itamarst
It's usually a bad idea, and often you have no choice because of library
design.

~~~
odonnellryan
Some APIs work really well with the pattern, but I've only used 2-3 that were
"wow, that's really neat!"

------
Cieplak
I use inheritance only if the model satisfies the Liskov Substitution
Principle and if the language has strong OO primitives. Functional languages
accomplish similar goals with different abstractions, e.g., type polymorphism,
pattern matching, functional composition.

~~~
Cieplak
As an example, working in the payments business, we often model credit cards
and bank accounts as different subclasses (or types) of a common superclass,
given that these objects share a lot of semantics, i.e., they both send and
receive payments.

------
mabynogy
Never. Only plain objects in JS and structs in C++.

IMHO OOP is a trap.

------
cpcat
If you're an Android developer basically most of your work is extending
existing classes.

------
coralreef
In iOS development, all the time. I subclassed UI components like UITextView
and other things so I could customize its appearance and add functionality.

------
fuball63
In my web development career (with python) it is usually only simple mixin-
like inheritance, mostly because I can't stand code redundancy.

In game development though, it is way easier to develop a full fledged class
hierarchy. I think it is because OOP is supposed to model a physical world of
objects, which is generally what you'll be simulating in games too.

------
wayn3
You use inheritance when a library provides an interface that you want to use.
Other than that, you're probably better off not using it. Certainly not in the
idiot Programming 101 "lets design a restaurant" OOP way.

------
anustretch
Over time you'll get a better sense of which methods or properties ought to be
overloaded, and how/when to invoke super(). So it's best to think of
polymorphism as residing in gradations, best applied infrequently.

------
gusmd
It is kind of a necessity in some domains. For instance, I could cite Android
applications in Java, or using Qt in C++.

------
AznHisoka
Just once in the past 5 years. But I hear its very useful in dummy, trivial
applications with no real life purpose.

