22

During a code review today, a colleague of mine said something interesting:

prototype is only useful when you need inheritance - and when's inheritance ever a good idea?

I thought about this and I realised that I usually use inheritance to get around code that was badly designed in the first place. Modern OO style prefers composition over inheritance, but I don't know of any languages which have taken this to heart and actually enforce it.

Are there any general-purpose programming languages with classes, objects, methods, interfaces, and so on, which disallow class-based inheritance? (If such an idea doesn't make sense, why not?)

  • 7
    Your colleague has led you astray. The prototype is also useful for when you have public methods and properties that should be shared between instances. It's also useful because it allows you to properly use the instanceof operator in JavaScript: if (foo instanceof Foo) { .... – Greg Burghardt Oct 6 '14 at 18:27
  • 2
    I think we should make a distinction between the inheritance of type, state and behaviour. The preference of composition is very common in the Java community but at the same time, inheritance (and even multiple inheritance) of types is widely used and encouraged... and realized using the implements keyword and interfaces (as opposed to the inheritance of state and behaviour introduced with the use of the extends keyword on classes containing any implementation). – toniedzwiedz Oct 6 '14 at 18:29
  • 6
    Preferring composition doesn't mean completely abandoning inheritance is a good idea. – Caleb Oct 6 '14 at 18:37
  • 5
    see Java without implementation inheritance: "Google's go is an example of a language which does away with implementation inheritance while being OOP..." – gnat Oct 6 '14 at 18:54
  • 1
    @GregBurghardt The same can be accomplished with a factory function which returns an object containing functions (storing private data in the closure). new, this and prototype are all too much of a minefield for common use IMO. – Benjamin Hodgson Oct 6 '14 at 21:02
18

Setting aside the question of the definition of object oriented programming the question becomes one of "are there languages which use composition only and have no tools for inheritance?"

The answer to this is quite simply "yes". In go, there are no way to do inheritance as one classically thinks of it. One can embedded an object in another object and the extend that object. From Object Desoriented Language (github mirror):

type Person struct {
        Name string
}

func (p *Person) Intro() string {
        return p.Name
}

type Woman struct {
        Person
}

func (w *Woman) Intro() string {
        return "Mrs. " + w.Person.Intro()
}

You've got a person struct that has a Name which is a String. It has a public function called Intro which returns the name. The Woman struct also has a function for Intro which accesses the strut embedded in it. And so one can fulfill the intentions of inheritance by using composition only.

More on this can be seen at GoLang Tutorials: Inheritance and subclassing in Go - or its near likeness.

So yes, it is possible to have an OO language without inheritance, and one does exist.

Within go this is known as embedding and gives enclosing structures the ability to access the embedded fields and functions as if it had them too - but it's not a subclass. The design philosophy can be found in the Go FAQ: Why is there no type inheritance?

  • One could also comment about the use of typedef and struct in C... – cwallenpoole Oct 6 '14 at 20:28
  • @cwallenpoole there are indeed similar ideas there, though I would hesitate to call C an object oriented language. – user40980 Oct 6 '14 at 20:36
  • I dunno. I'll admit the fact that you can't create objects with functions attached does work against it, but without inheritance, OOP looses much of its flavor. – cwallenpoole Oct 7 '14 at 10:12
  • @cwallenpoole and we start getting into defining what inheritance is and object orientation. But it is possible, its just a different way of thinking about the problem. The thing is that inheritance is the way most C++ and Java programers think of extension... but there are other models. Extension without inheritance: 1, 2, 3 are good reads. – user40980 Oct 7 '14 at 19:17
  • The link to "Object Desoriented Language" is stuck in a redirect loop at the moment, but I found the article here: github.com/nu7hatch/areyoufuckingcoding.me/blob/master/content/…. Thanks! – Matt Browne Apr 6 '15 at 13:20
7

Are there any general-purpose programming languages with classes, objects, methods, interfaces, and so on, which disallow class-based inheritance?

This reads very much like a description of VBA - Visual Basic for Applications, embedded in Microsoft Office and other VBA-enabled hosts (e.g. AutoCAD, Sage 300 ERP, etc.), or even VB6. The "A" of "Basic" stands for "All-purpose" anyway, so there's the "general-purpose" part.

VB6/VBA has classes (and therefore objects), methods and interfaces - you could define an ISomething interface in a class module like this:

Option Explicit

Public Sub DoSomething()
End Sub

And then have another class that does this:

Option Explicit
Implements ISomething

Private Sub ISomething_DoSomething()
    'implementation here
End Sub

Such a class, exposing no public members, could only ever be accessed via its ISomething interface - and there could very well be dozens of different implementations of ISomething out there, so OOP VBA code is perfectly capable of polymorphism, and it's perfectly legal for a given class to implement multiple interfaces, too.

VB6/VBA does not allow class inheritance however, so you can't inherit an implementation from another type, only its interface. Now, whether this is an accident, a design flaw, a stroke of genius or a huge ugly oversight is open for debate; it's not clear whether VB6/VBA takes this to heart, but it most definitely enforces it.

If Go doesn't do class inheritance and is nonetheless an OOP language, then I don't see why VB6/VBA couldn't be considered an OOP language as well. </PreemptiveResponseToVBAHatersThatWillSayItIsNotAnOOPLanguage>

  • 1
    To be fair, OP asked about modern languages. =;)- – RubberDuck Jun 14 '16 at 0:22
  • @RubberDuck #burn! – Mathieu Guindon Jun 14 '16 at 0:45
0

You can make the compiler enforce selective inheritance through the use of private / protected, and through modern use of "PImpl", or "Private Implementation" techniques.

Many APIs expose only those components which you would desire a user to inherit, and hide the rest in a separate implementation class. So you could write classes whose public interfaces are, in fact, uninheritable, only usable through object composition, and compiler-enforced. This is often good practice, when it uses the compiler to enforce the intent of the software.

A quick search for private member functions in javascript show there is a similar principle, although anybody can see your code if they can use it: http://www.crockford.com/javascript/private.html

protected by gnat Aug 7 '17 at 1:14

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.