Inheritance/Multiple

From Rosetta Code
Jump to: navigation, search
Task
Inheritance/Multiple
You are encouraged to solve this task according to the task description, using any language you may know.

Multiple inheritance allows to specify that one class is a subclass of several other classes. Some languages allow multiple inheritance for arbitrary classes, others restrict it to interfaces, some don't allow it at all.

Write two classes (or interfaces) Camera and MobilePhone, then write a class CameraPhone which is both a Camera and a MobilePhone.

There is no need to implement any functions for those classes.

Contents

[edit] Ada

Ada 2005 has added interfaces, allowing a limited form of multiple inheritance.

package Multiple_Interfaces is
type Camera is tagged null record;
type Mobile_Phone is limited Interface;
type Camera_Phone is new Camera and Mobile_Phone with null record;
end Multiple_Interfaces;

[edit] Aikido

Aikido does not support multiple inheritance, but does allow multiple implementation of interfaces.

 
interface Camera {
}
 
interface Mobile_Phone {
}
 
class Camera_Phone implements Camera, Mobile_Phone {
}
 
 

[edit] BBC BASIC

      INSTALL @lib$+"CLASSLIB"
 
DIM Camera{TakePicture}
PROC_class(Camera{})
 
DIM MobilePhone{MakeCall}
PROC_class(MobilePhone{})
 
DIM CameraPhone{methods}
PROC_inherit(CameraPhone{}, Camera{})
PROC_inherit(CameraPhone{}, MobilePhone{})
PROC_class(CameraPhone{})

[edit] C++

class Camera
{
// ...
};
 
class MobilePhone
{
// ...
};
 
class CameraPhone:
public Camera,
public MobilePhone
{
// ...
};

[edit] C#

In C# you may inherit from only one class, but you can inherit from multiple interfaces. Also, in C# it is standard practice to start all interface names with a capital 'I' so I have altered the name of the interface. In the example we inherit from a class and an interface.

interface ICamera {
// ...
}
 
class MobilePhone {
// ...
}
 
class CameraPhone: ICamera, MobilePhone {
// ...
}

[edit] Clojure

(defprotocol Camera)
 
(defprotocol MobilePhone)
 
(deftype CameraPhone []
Camera
MobilePhone)

[edit] COBOL

       CLASS-ID. Camera.
*> ...
END CLASS Camera.
 
CLASS-ID. Mobile-Phone.
*> ...
END CLASS Mobile-Phone.
 
CLASS-ID. Camera-Phone INHERITS Camera, Mobile-Phone.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
REPOSITORY.
CLASS Camera
CLASS Mobile-Phone.
 
*> ...
END CLASS Camera-Phone.

[edit] Common Lisp

(defclass camera () ())
(defclass mobile-phone () ())
(defclass camera-phone (camera mobile-phone) ())

[edit] D

D doesn't allow multiple inheritance, but you can inherit after multiple interfaces.

interface Camera {
// member function prototypes and static methods
}
 
interface MobilePhone {
// member function prototypes and static methods
}
 
class CameraPhone: Camera, MobilePhone {
// member function implementations for Camera,
// MobilePhone, and CameraPhone
}

D also supports template mixins and alias this (multiple alias this are planned) that allows various forms of static composition.

[edit] Delphi

Delphi doesn't support multiple inheritance, but it does have multiple interfaces.

type
ICamera = Interface
// ICamera methods...
end;
 
IMobilePhone = Interface
// IMobilePhone methods...
end;
 
TCameraPhone = class(TInterfacedObject, ICamera, IMobilePhone)
// ICamera and IMobilePhone methods...
end;

[edit] DWScript

See Delphi.

[edit] E

E does not have multiple inheritance as a built-in feature. In fact, E only has inheritance at all as a light syntactic sugar over delegation (message forwarding). However, using that facility it is possible to implement multiple inheritance.

This is a quick simple implementation of multiple inheritance. It simply searches (depth-first and inefficiently) the inheritance tree for a method; it does not do anything about diamond inheritance. These shortcomings could be fixed if more powerful multiple inheritance were needed.

def minherit(self, supers) {
def forwarder match [verb, args] {
escape __return {
if (verb == "__respondsTo") {
def [verb, arity] := args
for super ? (super.__respondsTo(verb, arity)) in supers {
return true
}
return false
} else if (verb == "__getAllegedType") {
# XXX not a complete implementation
return supers[0].__getAllegedType()
} else {
def arity := args.size()
for super ? (super.__respondsTo(verb, arity)) in supers {
return E.call(super, verb, args)
}
throw(`No parent of $self responds to $verb/$arity`)
}
}
}
return forwarder
}

The task example:

def makeCamera(self) {
return def camera extends minherit(self, []) {
to takesPictures() { return true }
}
}
 
def makeMobilePhone(self) {
return def mobilePhone extends minherit(self, []) {
to makesCalls() { return true }
to internalMemory() { return 64*1024 }
}
}
 
def makeCameraPhone(self) {
return def cameraPhone extends minherit(self, [
makeCamera(self),
makeMobilePhone(self),
]) {
to internalMemory() {
return super.internalMemory() + 32 * 1024**2
}
}
}

And testing that it works as intended:

 
? def p := makeCameraPhone(p)
> [p.takesPictures(), p.makesCalls(), p.internalMemory()]
# value: [true, true, 33619968]

[edit] Eiffel

class
CAMERA
end
class
MOBILE_PHONE
end
class
CAMERA_PHONE
inherit
CAMERA
MOBILE_PHONE
end

[edit] Fantom

Fantom only permits inheritance from one parent class. However, Fantom supports 'mixins': a mixin is a collection of implemented methods to be added to the child class. Any number of mixins can be added to any given child class. It is an error for method names to conflict.

 
// a regular class
class Camera
{
Str cameraMsg ()
{
"camera"
}
}
 
// a mixin can only contain methods
mixin MobilePhone
{
Str mobileMsg ()
{
"mobile phone"
}
}
 
// class inherits from Camera, and mixes in the methods from MobilePhone
class CameraPhone : Camera, MobilePhone
{
}
 
class Main
{
public static Void main ()
{
cp := CameraPhone ()
echo (cp.cameraMsg)
echo (cp.mobileMsg)
}
}
 

[edit] F#

A class can only inherit from one other class, but it can implement any number of interfaces.

type Picture = System.Drawing.Bitmap // (a type synonym)
 
// an interface type
type Camera =
abstract takePicture : unit -> Picture
 
// a class with an abstract method with a default implementation
// (usually called a virtual method)
type MobilePhone() =
abstract makeCall : int[] -> unit
default x.makeCall(number) = () // empty impl
 
// a class that inherits from another class and implements an interface
type CameraPhone() =
inherit MobilePhone()
interface Camera with
member x.takePicture() = new Picture(10, 10)

[edit] Go

Go abandons traditional object oriented concepts of inheritance hierarchies, yet it does have features for composing both structs and interfaces.

// Example of composition of anonymous structs
package main
 
import "fmt"
 
// Two ordinary structs
type camera struct {
optics, sensor string
}
 
type mobilePhone struct {
sim, firmware string
}
 
// Fields are anonymous because only the type is listed.
// Also called an embedded field.
type cameraPhone struct {
camera
mobilePhone
}
 
func main() {
// Struct literals must still reflect the nested structure
htc := cameraPhone{camera{optics: "zoom"}, mobilePhone{firmware: "3.14"}}
 
// But fields of anonymous structs can be referenced without qualification.
// This provides some effect of the two parent structs being merged, as
// with multiple inheritance in some other programming languages.
htc.sim = "XYZ"
fmt.Println(htc)
}
Output:
(Note sensor field still blank)
{{zoom } {XYZ 3.14}}
// Example of composition of interfaces.
// Types implement interfaces simply by implementing functions.
// The type does not explicitly declare the interfaces it implements.
package main
 
import "fmt"
 
// Two interfaces.
type camera interface {
photo()
}
 
type mobilePhone interface {
call()
}
 
// Compose interfaces. cameraPhone interface now contains whatever
// methods are in camera and mobilePhone.
type cameraPhone interface {
camera
mobilePhone
}
 
// User defined type.
type htc int
 
// Once the htc type has this method defined on it, it automatically satisfies
// the camera interface.
func (htc) photo() {
fmt.Println("snap")
}
 
// And then with this additional method defined, it now satisfies both the
// mobilePhone and cameraPhone interfaces.
func (htc) call() {
fmt.Println("omg!")
}
 
func main() {
// type of i is the composed interface. The assignment only compiles
// because static type htc satisfies the interface cameraPhone.
var i cameraPhone = new(htc)
// interface functions can be called without reference to the
// underlying type.
i.photo()
i.call()
}
 
Output:
snap
omg!

[edit] Haskell

class Camera a
class MobilePhone a
class (Camera a, MobilePhone a) => CameraPhone a

[edit] Icon and Unicon

Icon does not support classes or inheritance. An intermediate language called Idol was developed as proof of concept for extending Icon. This became one of the major addons contributing to Unicon.

 
class Camera (instanceVars)
# methods...
# initializer...
end
 
class Phone (instanceVars)
# methods...
# initializer...
end
 
class CameraPhone : Camera, Phone (instanceVars)
# methods...
# initialiser...
end

[edit] Ioke

Camera = Origin mimic
MobilePhone = Origin mimic
CameraPhone = Camera mimic mimic!(MobilePhone)

[edit] J

coclass 'Camera'
 
create=: verb define
NB. creation-specifics for a camera go here
)
 
destroy=: codestroy
 
NB. additional camera methods go here
 
coclass 'MobilePhone'
 
create=: verb define
NB. creation-specifics for a mobile phone go here
)
 
destroy=: codestroy
 
NB. additional phone methods go here
 
coclass 'CameraPhone'
coinsert 'Camera MobilePhone'
 
create=: verb define
create_Camera_ f. y
create_MobilePhone_ f. y
NB. creation details specific to a camera phone go here
)
 
destroy=: codestroy
 
NB. additional camera-phone methods go here

The adverb Fix (f.) is needed as shown so the superclass constructors get executed in the object, not in the superclass.

[edit] Java

Java does not allow multiple inheritance, but you can "implement" multiple interfaces. All methods in interfaces are abstract (they don't have an implementation). When you implement an interface you need to implement the specified methods.

public interface Camera{
//functions here with no definition...
//ex:
//public void takePicture();
}
public interface MobilePhone{
//functions here with no definition...
//ex:
//public void makeCall();
}
public class CameraPhone implements Camera, MobilePhone{
//functions here...
}

[edit] Lasso

Lasso only allow single inheritance. But it supports the use of multiple traits and trays hand down the methods it has implemented provided that the type fulfills the requirements for the trait. http://lassoguide.com/language/traits.html

 
define trait_camera => trait {
require zoomfactor
 
provide has_zoom() => {
return .zoomfactor > 0
}
 
}
 
define trait_mobilephone => trait {
require brand
 
provide is_smart() => {
return .brand == 'Apple'
}
 
}
 
define cameraphone => type {
 
trait {
import trait_camera, trait_mobilephone
}
 
data public zoomfactor::integer = 0,
public brand::string
 
}
 
local(mydevice = cameraphone)
 
#mydevice -> brand = 'Apple'
#mydevice -> zoomfactor = 0
 
#mydevice -> has_zoom
'<br />'
#mydevice -> is_smart

-> false

true

[edit] Logtalk

Logtalk supports multiple inheritance. There is no "class" keyword in Logtalk; an "object" keyword is used instead (Logtalk objects play the role of classes, meta-classes, instances, or prototypes depending on the relations with other objects).

:- object(camera,
...).
...
:- end_object.
:- object(mobile_phone,
...).
...
:- end_object.
:- object(camera_phone,
specializes(camera, mobile_phone),
...).
...
:- end_object.

[edit] Lua

Lua is prototype-based. A table cannot have more than one metatable, but it can reference more than one in its __index metamethod, by making it a closure.

 
function setmetatables(t,mts) --takes a table and a list of metatables
return setmetatable(t,{__index = function(self, k)
--collisions are resolved in this implementation by simply taking the first one that comes along.
for i, mt in ipairs(mts) do
local member = mt[k]
if member then return member end
end
end})
end
 
camera = {}
mobilephone = {}
cameraphone = setemetatables({},{camera,mobilephone})
 
 

[edit] Nemerle

Like C#, Nemerle only allows pseudo-multiple inheritance through interfaces. In Nemerle, the base class must be listed before any interfaces.

interface ICamera {
// ...
}
 
class MobilePhone {
// ...
}
 
class CameraPhone: MobilePhone, ICamera {
// ...
}

[edit] NetRexx

Like Java, NetRexx doesn't allow true multiple inheritance but instead restricts that capability to interfaces. NetRexx permits the implementation of multiple interfaces. All methods in interfaces are implicitly abstract, thus when you implement an interface you must implement its specified methods.

In this sample the class/interface names are augmented over those required in the task to prevent namespace pollution. The sample also provides a complete working implementation to demonstrate the capability.

/* NetRexx */
options replace format comments java crossref symbols binary
 
class RInheritMultiple public
method main(args = String[]) public static
iPhone = RInheritMultiple_CameraPhone()
if iPhone <= RInheritMultiple_Camera then -
say -
'Object' hashToString(iPhone) '['iPhone.getClass().getSimpleName()']' -
'is a' RInheritMultiple_Camera.class.getSimpleName()
if iPhone <= RInheritMultiple_MobilePhone then -
say -
'Object' hashToString(iPhone) '['iPhone.getClass().getSimpleName()']' -
'is a' RInheritMultiple_MobilePhone.class.getSimpleName()
say iPhone.snap()
say iPhone.call()
return
method hashToString(that = Object) public static
return '@'(Rexx that.hashCode()).d2x().right(8, 0)
 
class RInheritMultiple_Camera private interface
-- properties follow...
shutter = 'click...'
-- method prototypes follow
method snap() public returns Rexx
 
class RInheritMultiple_MobilePhone private interface
-- properties follow...
ringTone = 'ring...'
-- method prototypes follow
method call() public returns Rexx
 
class RInheritMultiple_CameraPhone private -
implements -
RInheritMultiple_Camera, -
RInheritMultiple_MobilePhone -
uses -
RInheritMultiple_Camera, -
RInheritMultiple_MobilePhone
method RInheritMultiple_CameraPhone() public
return
-- method implementations follow
method snap() public
return shutter
method call() public
return ringTone
 
Output:
Object @7F546C85 [RInheritMultiple_CameraPhone] is a RInheritMultiple_Camera
Object @7F546C85 [RInheritMultiple_CameraPhone] is a RInheritMultiple_MobilePhone
click...
ring...

[edit] Objective-C

Like Java, Objective-C does not allow multiple inheritance, but a class can "conform to" multiple protocols. All methods in protocols are abstract (they don't have an implementation). When you conform to a protocol you need to implement the specified methods.

If you simply want to combine the functionality (method implementations) of multiple classes, you can use message forwarding to mimic the functionality of those classes without actually inheriting them, as described in this guide:

@interface Camera : NSObject {
}
@end
 
@implementation Camera
@end
 
@interface MobilePhone : NSObject {
}
@end
 
@implementation MobilePhone
@end
 
@interface CameraPhone : NSObject {
Camera *camera;
MobilePhone *phone;
}
@end
 
@implementation CameraPhone
 
-(instancetype)init {
if ((self = [super init])) {
camera = [[Camera alloc] init];
phone = [[MobilePhone alloc] init];
}
return self;
}
 
-(void)forwardInvocation:(NSInvocation *)anInvocation {
SEL aSelector = [anInvocation selector];
if ([camera respondsToSelector:aSelector])
[anInvocation invokeWithTarget:camera];
else if ([phone respondsToSelector:aSelector])
[anInvocation invokeWithTarget:phone];
else
[self doesNotRecognizeSelector:aSelector];
}
 
-(NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {
return [camera methodSignatureForSelector:aSelector]
 ?: [phone methodSignatureForSelector:aSelector]
 ?: [super methodSignatureForSelector:aSelector];
}
 
-(BOOL)respondsToSelector:(SEL)aSelector {
return [camera respondsToSelector:aSelector]
|| [phone respondsToSelector:aSelector]
|| [super respondsToSelector:aSelector];
}
 
@end

Caveat: the CameraPhone class will still technically not inherit from either the Camera or MobilePhone classes, so testing a CameraPhone object with -isKindOfClass: with the Camera or MobilePhone classes will still fail.

[edit] OCaml

class camera =
object (self)
(*functions go here...*)
end
class mobile_phone =
object (self)
(*functions go here...*)
end
class camera_phone =
object (self)
inherit camera
inherit mobile_phone
(*functions go here...*)
end

[edit] ooRexx

ooRexx classes have a single superclass and can inherit from multiple mixins. Mixins are more that just interfaces. They can contain concrete method implementations and also create instance variables (scoped as private variables to the mixin methods).

 
-- inherited classes must be created as mixinclasses.
::class phone mixinclass object
 
::class camera mixinclass object
 
-- not a direct subclass of either, but inherits both
::class cameraphone inherit phone camera
 
-- could also be
::class cameraphone1 subclass phone inherit camera
 
-- or
 
::class cameraphone2 subclass camera inherit phone
 

[edit] OxygenBasic

 
class Camera
string cbuf
method TakePhoto()
end method
method ViewPhoto()
end method
end class
 
class MobilePhone
string pbuf
method MakeCall()
end method
method TakeCall()
end method
end class
 
class CameraPhone
has Camera,MobilePhone
end class
 
CameraPhone cp
 
cp.ViewPhoto
cp.MakeCall
 

[edit] Oz

class Camera end
 
class MobilePhone end
 
class CameraPhone from Camera MobilePhone end

[edit] Pascal

See Delphi

[edit] Perl

package Camera;
#functions go here...
1;
package MobilePhone;
#functions go here...
1;
package CameraPhone;
use Camera;
use MobilePhone;
@ISA = qw( Camera MobilePhone );
#functions go here...
1;

or

package CameraPhone;
use base qw/Camera MobilePhone/;
#functions go here...

The same using the MooseX::Declare extention:

use MooseX::Declare;
 
class Camera {
# methods ...
}
class MobilePhone {
# methods ...
}
class CameraPhone extends(Camera, MobilePhone) {
# methods ...
}

[edit] Perl 6

Works with: Rakudo version 2012.06
class Camera {}
class MobilePhone {}
class CameraPhone is Camera is MobilePhone {}
 
say CameraPhone.^mro; # undefined type object
say CameraPhone.new.^mro; # instantiated object
Output:
CameraPhone() Camera() MobilePhone() Any() Mu()
CameraPhone() Camera() MobilePhone() Any() Mu()

The .^mro is not an ordinary method call, but a call to the object's metaobject that returns the method resolution order for this type.

[edit] PicoLisp

(class +Camera)
 
(class +MobilePhone)

[edit] Pop11

;;; load object support
lib objectclass;
 
define :class Camera;
 ;;; slots go here
enddefine;
 
define :class MobilePhone;
 ;;; slots go here
enddefine;
 
define :class CameraPhone is Camera, MobilePhone;
 ;;; extra slots go here
enddefine;
 
;;; methods go here

[edit] PureBasic

Using the open-source precompiler SimpleOOP.

Class Camera
EndClass
 
Class Mobil
EndClass
 
Class CameraMobile Extends Camera Extends Mobil
EndClass

[edit] Python

class Camera:
pass #functions go here...
class MobilePhone:
pass #functions go here...
class CameraPhone(Camera, MobilePhone):
pass #functions go here...

[edit] Racket

Racket allows multiple inheritance with interfaces, but not classes. Mixins can be used to achieve some of the benefits of multiple inheritance.

 
#lang racket
 
(define camera<%> (interface ()))
(define mobile-phone<%> (interface ()))
 
(define camera-phone%
(class* object% (camera<%> mobile-phone<%>)
(super-new)
 ;; implement methods here
))
 

[edit] Ruby

Ruby does not have multiple inheritance, but you can mix modules into classes:

module Camera
# define methods here
end
class MobilePhone
# define methods here
end
class CameraPhone < MobilePhone
include Camera
# define methods here
end

[edit] Scala

trait Camera
trait MobilePhone
class CameraPhone extends Camera with MobilePhone

[edit] Sidef

class Camera {};
class MobilePhone {};
class CameraPhone << Camera, MobilePhone {};

[edit] Slate

define: #Camera.
define: #MobilePhone.
define: #CameraPhone &parents: {Camera. MobilePhone}.

[edit] Swift

Like Objective-C, Swift does not allow multiple inheritance. However, you can conform to multiple protocols.

protocol Camera {
 
}
 
protocol Phone {
 
}
 
class CameraPhone: Camera, Phone {
 
}

[edit] Tcl

Works with: Tcl version 8.6
or
Library: TclOO
package require TclOO
 
oo::class create Camera
oo::class create MobilePhone
oo::class create CameraPhone {
superclass Camera MobilePhone
}


[edit] zkl

class Camera{} class MobilePhone{}
class CameraPhone(Camera,MobilePhone){}
CameraPhone.linearizeParents
Output:
Show the class search order
L(Class(CameraPhone),Class(Camera),Class(MobilePhone))
Personal tools
Namespaces

Variants
Actions
Community
Explore
Misc
Toolbox