Inheritance is an operation of type algebra that creates a new type from one or several parent types. The obtained type is called derived type. It inherits some of the properties of its parent types. Usually inherited properties are:

  • methods
  • components
  • parts of the representation
Task
Inheritance/Single
You are encouraged to solve this task according to the task description, using any language you may know.
This task is about derived types; for implementation inheritance, see Polymorphism.

The class of the new type is a subclass of the classes rooted in the parent types. When all (in certain sense) properties of the parents are preserved by the derived type, it is said to be a Liskov subtype. When properties are preserved then the derived type is substitutable for its parents in all contexts. Usually full substitutability is achievable only in some contexts.

Inheritance is

  • single, when only one parent is allowed
  • multiple, otherwise

Some single inheritance languages usually allow multiple inheritance for certain abstract types, interfaces in particular.

Inheritance can be considered as a relation parent-child. Parent types are sometimes called supertype, the derived ones are subtype. This relation is transitive and reflexive. Types bound by the relation form a directed acyclic graph (ignoring reflexivity). With single inheritance it becomes a tree.

Task: Show a tree of types which inherit from each other. The top of the tree should be a class called Animal. The second level should have Dog and Cat. Under Dog should be Lab and Collie. None of the classes need to have any functions, the only thing they need to do is inherit from the specified superclasses (overriding functions should be shown in Polymorphism). The tree should look like this:

    Animal
      /\
     /  \
    /    \
   Dog   Cat
   /\
  /  \
 /    \
Lab   Collie

ActionScript

<lang actionscript>public class Animal {

   // ...

}</lang> <lang actionscript>public class Cat extends Animal {

   // ...

}</lang> <lang actionscript>public class Dog extends Animal {

   // ...

}</lang> <lang actionscript>public class Lab extends Dog {

   // ...

}</lang> <lang actionscript>public class Collie extends Dog {

   // ...

}</lang>

Ada

<lang ada>package Inheritance is

  type Animal is tagged private;
  type Dog is new Animal with private;
  type Cat is new Animal with private;
  type Lab is new Dog with private;
  type Collie is new Dog with private;

private

  type Animal is tagged null record;
  type Dog is new Animal with null record;
  type Cat is new Animal with null record;
  type Lab is new Dog with null record;
  type Collie is new Dog with null record;

end Inheritance;</lang>

C

C++

<lang cpp>class Animal {

 // ... 

};

class Dog: public Animal {

 // ... 

};

class Lab: public Dog {

 // ...

};

class Collie: public Dog {

 // ...

};

class Cat: public Animal {

 // ...

};</lang>

Common Lisp

Using CLOS classes, we have the following:

<lang lisp>(defclass animal () ()) (defclass dog (animal) ()) (defclass lab (dog) ()) (defclass collie (dog) ()) (defclass cat (animal) ())</lang>

Alternatively, since there is no multiple inheritance, structures could also be used:

<lang lisp>(defstruct animal) (defstruct (dog (:include animal))) (defstruct (lab (:include dog))) (defstruct (collie (:include dog))) (defstruct (cat (:include animal)))</lang>

(Structures are less flexible than CLOS objects but often somewhat more efficiently implemented, due to those restrictions.)

C#

<lang csharp>class Animal { /* ... */ }

class Dog : Animal { /* ... */ }

class Lab : Dog { /* ... */ }

class Collie : Dog { /* ... */ }

class Cat : Animal { /* ... */ }</lang>

D

<lang d>class Animal {

 // ... 

}

class Dog: Animal {

 // ... 

}

class Lab: Dog {

 // ...

}

class Collie: Dog {

 // ...

}

class Cat: Animal {

 // ...

}</lang>

E

Outside of interactions with the host platform's objects, E does not generally deal in complex type hierarchies; the focus is more on "what guarantees does this object provide", and composition rather than inheritance. However, it is possible to set up a type hierarchy scheme with just a bit of code.

In E, a guard accepts, or coerces, certain objects and rejects others; its range constitutes a type. An auditor examines the implementation of an object and marks it approved; a stamp is an auditor which does no actual checking. Here, we create a guard/stamp pair; the guard accepts every stamped object. The stamp also asks for each supertype's stamp on the objects it audits.

<lang e>def makeType(label, superstamps) {

   def stamp {
       to audit(audition) {
           for s in superstamps { audition.ask(s) }
           return true
       }
   }
   def guard {
       to coerce(specimen, ejector) {
           if (__auditedBy(stamp, specimen)) {
               return specimen
           } else {
               throw.eject(ejector, `$specimen is not a $label`)
           }
       }
   }
   return [guard, stamp]

}</lang>

Setting up the task's specified tree:

<lang e>def [Animal, AnimalStamp] := makeType("Animal", [])

def [Cat, CatStamp] := makeType("Cat", [AnimalStamp]) def [Dog, DogStamp] := makeType("Dog", [AnimalStamp])

def [Lab, LabStamp] := makeType("Lab", [DogStamp]) def [Collie, CollieStamp] := makeType("Collie", [DogStamp])</lang>

Some example objects:

<lang e>def fido implements LabStamp {} def tom implements CatStamp {} def brick {} # not an animal</lang>

Testing against the types:

<lang e>? fido :Animal

  1. value: <fido>

? fido :Cat

  1. problem: <fido> is not a Cat

? fido :Lab

  1. value: <fido>

? tom :Animal

  1. value: <tom>

? tom :Cat

  1. value: <tom>

? brick :Animal

  1. problem: <brick> is not a Animal</lang>

Factor

<lang factor>TUPLE: animal ; TUPLE: dog < animal ; TUPLE: cat < animal ; TUPLE: lab < dog ; TUPLE: collie < dog ;</lang>

Groovy

<lang groovy>class Animal{

  //contents go here...

}</lang> <lang groovy>class Dog extends Animal{

  //contents go here...

}</lang> <lang groovy>class Cat extends Animal{

  //contents go here...

}</lang> <lang groovy>class Lab extends Dog{

  //contents go here...

}</lang> <lang groovy>class Collie extends Dog{

  //contents go here...

}</lang>

Haskell

A type can't inherit properties from other types, but it can belong to any number of type classes, which may themselves be subclasses of other type classes.

<lang haskell>class Animal a class Animal a => Cat a class Animal a => Dog a class Dog a => Lab a class Dog a => Collie a</lang>

HaXe

<lang haxe>class Animal {

   // ...

}</lang> <lang haxe>class Cat extends Animal {

   // ...

}</lang> <lang haxe>class Dog extends Animal {

   // ...

}</lang> <lang haxe>class Lab extends Dog {

   // ...

}</lang> <lang haxe>class Collie extends Dog {

   // ...

}</lang>

Io

<lang io>Animal := Object clone Cat := Animal clone Dog := Animal clone Collie := Dog clone Lab := Dog clone</lang>

J

Here is how this would normally be done:

<lang j>coclass 'Animal'</lang> <lang j>coclass 'Dog' coinsert 'Animal'</lang> <lang j>coclass 'Cat' coinsert 'Animal'</lang> <lang j>coclass 'Lab' coinsert 'Dog'</lang> <lang j>coclass 'Collie' coinsert 'Dog'</lang>

See http://www.jsoftware.com/help/jforc/modular_code.htm

That said, some operations in J -- including coinsert -- will create classes if they did not already exist. So the above may be simplified to:

<lang j>coinsert_Dog_ 'Animal' coinsert_Cat_ 'Animal' coinsert_Lab_ 'Dog' coinsert_Collie_ 'Dog'</lang>

Java

<lang java>public class Animal{

  //functions go here...

}</lang> <lang java>public class Dog extends Animal{

  //functions go here...

}</lang> <lang java>public class Cat extends Animal{

  //functions go here...

}</lang> <lang java>public class Lab extends Dog{

  //functions go here...

}</lang> <lang java>public class Collie extends Dog{

  //functions go here...

}</lang>

JavaScript

<lang javascript>function Animal() {

   // ...

}</lang>

<lang javascript>function Dog() {

   // ...

} Dog.prototype = new Animal();</lang>

<lang javascript>function Cat() {

   // ...

} Cat.prototype = new Animal();</lang>

<lang javascript>function Collie() {

   // ...

} Collie.prototype = new Dog();</lang>

<lang javascript>function Lab() {

   // ...

} Lab.prototype = new Dog();</lang>

<lang javascript>Animal.prototype.speak = function() {print("an animal makes a sound")};

var lab = new Lab(); lab.speak(); // shows "an animal makes a sound"</lang>

Lisaac

<lang Lisaac>Section Header + name := ANIMAL; // ...</lang> <lang Lisaac>Section Header + name := CAT; Section Inherit - parent : ANIMAL := ANIMAL; // ...</lang> <lang Lisaac>Section Header + name := DOG; Section Inherit - parent : ANIMAL := ANIMAL; // ...</lang> <lang Lisaac>Section Header + name := LAB; Section Inherit - parent : DOG := DOG; // ...</lang> <lang Lisaac>Section Header + name := COLLIE; Section Inherit - parent : DOG := DOG; // ...</lang>

Objective-C

<lang objc>@interface Animal : NSObject {

 // ... 

} // ... @end

@interface Dog : Animal {

 // ... 

} // ... @end

@interface Lab : Dog {

 // ... 

} // ... @end

@interface Collie : Dog {

 // ... 

} // ... @end

@interface Cat : Animal {

 // ... 

} // ... @end</lang>

OCaml

<lang ocaml>class animal =

 object (self)
   (*functions go here...*)
 end</lang>

<lang ocaml>class dog =

 object (self)
   inherit animal
   (*functions go here...*)
 end</lang>

<lang ocaml>class cat =

 object (self)
   inherit animal
   (*functions go here...*)
 end</lang>

<lang ocaml>class lab =

 object (self)
   inherit dog
   (*functions go here...*)
 end</lang>

<lang ocaml>class collie =

 object (self)
   inherit dog
   (*functions go here...*)
 end</lang>

Oz

<lang oz>class Animal

  %% ...

end

class Dog from Animal

  %% ... 

end

class Lab from Dog

  %% ... 

end

class Collie from Dog

  %% ... 

end

class Cat from Animal

  %% ... 

end</lang>

Perl

<lang perl>package Animal;

  1. functions go here...

1;</lang>

<lang perl>package Dog; use Animal; @ISA = qw( Animal );

  1. functions go here...

1;</lang>

<lang perl>package Cat; use Animal; @ISA = qw( Animal );

  1. functions go here...

1;</lang>

<lang perl>package Lab; use Dog; @ISA = qw( Dog );

  1. functions go here...

1;</lang>

<lang perl>package Collie; use Dog; @ISA = qw( Dog );

  1. functions go here...

1;</lang>

PHP

<lang php>class Animal {

  // functions go here...

}

class Dog extends Animal {

  // functions go here...

}

class Cat extends Animal {

  // functions go here...

}

class Lab extends Dog {

  // functions go here...

}

class Collie extends Dog {

  // functions go here...

}</lang>

Python

Unrevised style classes: <lang python>class Animal:

 pass #functions go here...

class Dog(Animal):

 pass #functions go here...

class Cat(Animal):

 pass #functions go here...

class Lab(Dog):

 pass #functions go here...

class Collie(Dog):

 pass #functions go here...</lang>

New style classes: <lang python>import time

class Animal(object):

   def __init__(self, birth=None, alive=True):
       self.birth = birth if birth else time.time()
       self.alive = alive
   def age(self):
       return time.time() - self.birth
   def kill(self):
       self.alive = False

class Dog(Animal):

   def __init__(self, bones_collected=0, **kwargs):
       self.bone_collected = bones_collected
       super(Dog, self).__init__(**kwargs)

class Cat(Animal):

   max_lives = 9
   def __init__(self, lives=max_lives, **kwargs):
       self.lives = lives
       super(Cat, self).__init__(**kwargs)
   def kill(self):
       if self.lives>0:
           self.lives -= 1
           if self.lives == 0:
               super(Cat, self).kill()
       else:
           raise ValueError
       return self

class Labrador(Dog):

   def __init__(self, guide_dog=False, **kwargs):
       self.guide_dog=False
       super(Labrador, self).__init__(**kwargs)

class Collie(Dog):

   def __init__(self, sheep_dog=False, **kwargs):
       self.sheep_dog=False
       super(Collie, self).__init__(**kwargs)

lassie = Collie() felix = Cat() felix.kill().kill().kill() mr_winkle = Dog() buddy = Labrador() buddy.kill() print "Felix has",felix.lives, "lives, ","Buddy is %salive!"%("" if buddy.alive else "not ")</lang>

Output:

Felix has 6 lives,  Buddy is not alive!

R

S3

Inheritance is implemented by setting the object's class attribute with a character vector. <lang R>aCollie <- "woof" class(aCollie) <- c("Collie", "Dog", "Animal")</lang>

S4

Inheritance is implemented by using the 'contains' argument in setClass <lang R>setClass("Animal", representation(), prototype()) setClass("Dog", representation(), prototype(), contains="Animal") setClass("Cat", representation(), prototype(), contains="Animal") setClass("Collie", representation(), prototype(), contains="Dog") setClass("Lab", representation(), prototype(), contains="Dog")</lang>

REBOL

<lang REBOL>REBOL [ Title: "Inheritance" Author: oofoe Date: 2009-12-08 URL: http://rosettacode.org/wiki/Inheritance ]

REBOL provides subclassing through its prototype mechanism

Animal: make object! [ legs: 4 ]

Dog: make Animal [ says: "Woof!" ] Cat: make Animal [ says: "Meow..." ]

Lab: make Dog [] Collie: make Dog []

Demonstrate inherited properties

print ["Cat has" Cat/legs "legs."]

print ["Lab says:" Lab/says]</lang>

Output:

Cat has 4 legs.
Lab says: Woof!

Ruby

inherited is a method defined on an instance of a Class object. It is invoked when a new subclass of the current class is defined (i.e. at the end statement of a class definition). <lang ruby>class Animal

 #functions go here...
 def self.inherited(subclass)
   puts "new subclass of #{self}: #{subclass}"
 end

end

class Dog < Animal

 #functions go here...

end

class Cat < Animal

 #functions go here...

end

class Lab < Dog

 #functions go here...

end

class Collie < Dog

 #functions go here...

end</lang>

Output

new subclass of Animal: Dog
new subclass of Dog: Lab
new subclass of Dog: Collie
new subclass of Animal: Cat

Scala

Scala has both classes and traits. Classes can only be singly inherited, but both can inherit a trait multiple times. This inheritance can be declared at the point of instantiation as well, precluding the need to declare a trait or class for the sole purpose of combining traits. For the simple inheritance chain of this task, any (or all) of the class keywords below can be replaced with trait

<lang scala>class Animal class Dog extends Animal class Cat extends Animal class Lab extends Dog class Collie extends Dog</lang>

Slate

<lang slate>define: #Animal &parents: {Cloneable}. define: #Dog &parents: {Animal}. define: #Cat &parents: {Animal}. define: #Lab &parents: {Dog}. define: #Collie &parents: {Dog}.</lang>

Smalltalk

This is an example of the object serialization format used by many varieties of Smalltalk. Normally the class tree would be defined and navigated via a class browser within a graphical Smalltalk environment. <lang smalltalk>Object subclass: #Animal

 instanceVariableNames: ' ' "* space separated list of names *"
 classVariableNames: ' '
 poolDictionaries: ' '
 category: ' ' !

"* declare methods here, separated with '!' *" "* !Animal methodsFor: 'a category'! *" "* methodName *" "* method body! !

!Animal subclass: #Dog

  "* etc. *" !

!Animal subclass: #Cat

 "* etc. *" !

!Dog subclass: #Lab

 "* etc. *" !

!Dog subclass: #Collie

 "* etc. *" !</lang>

Tcl

Works with: Tcl version 8.6


Works with: Tcl version 8.5

and the TclOO package

<lang Tcl>oo::class create Animal {

  # ...

} oo::class create Dog {

  superclass Animal
  # ...

} oo::class create Cat {

  superclass Animal
  # ...

} oo::class create Collie {

  superclass Dog
  # ...

} oo::class create Lab {

  superclass Dog
  # ...

}</lang>

Vorpal

<lang vorpal>pet = new() cat = new(pet) dog = new(pet) fido = new(dog) felix = new(cat)</lang>

Factor

<lang factor> TUPLE: animal TUPLE: dog < animal TUPLE: cat < animal TUPLE: lab < dog TUPLE: collie < dog </lang>