Inheritance/Multiple: Difference between revisions
m (omit JavaScript) |
m (Fixed lang tags.) |
||
Line 10: | Line 10: | ||
=={{header|Ada}}== |
=={{header|Ada}}== |
||
Ada 2005 has added interfaces, allowing a limited form of multiple inheritance. |
Ada 2005 has added interfaces, allowing a limited form of multiple inheritance. |
||
<lang ada> |
<lang ada>package Multiple_Interfaces is |
||
package Multiple_Interfaces is |
|||
type Camera is tagged null record; |
type Camera is tagged null record; |
||
type Mobile_Phone is limited Interface; |
type Mobile_Phone is limited Interface; |
||
type Camera_Phone is new Camera and Mobile_Phone with null record; |
type Camera_Phone is new Camera and Mobile_Phone with null record; |
||
end Multiple_Interfaces; |
end Multiple_Interfaces;</lang> |
||
⚫ | |||
=={{header|C++}}== |
=={{header|C++}}== |
||
<lang cpp> |
<lang cpp>class Camera |
||
class Camera |
|||
{ |
{ |
||
// ... |
// ... |
||
Line 35: | Line 32: | ||
{ |
{ |
||
// ... |
// ... |
||
}; |
};</lang> |
||
</lang> |
|||
=={{header|Common Lisp}}== |
=={{header|Common Lisp}}== |
||
<lang |
<lang lisp>(defclass camera () ()) |
||
(defclass mobile-phone () ()) |
(defclass mobile-phone () ()) |
||
(defclass camera-phone (camera mobile-phone) ())</lang> |
(defclass camera-phone (camera mobile-phone) ())</lang> |
||
=={{header|D}}== |
=={{header|D}}== |
||
<lang d> |
<lang d>interface Camera { |
||
interface Camera { |
|||
/+ member function prototypes go here +/ |
/+ member function prototypes go here +/ |
||
} |
} |
||
Line 54: | Line 49: | ||
class CameraPhone: Camera,MobilePhone { |
class CameraPhone: Camera,MobilePhone { |
||
/+ member function implementations for Camera, MobilePhone, and CameraPhone go here +/ |
/+ member function implementations for Camera, MobilePhone, and CameraPhone go here +/ |
||
⚫ | |||
} |
|||
</lang> |
|||
=={{header|E}}== |
=={{header|E}}== |
||
Line 118: | Line 112: | ||
? def p := makeCameraPhone(p) |
? def p := makeCameraPhone(p) |
||
> [p.takesPictures(), p.makesCalls(), p.internalMemory()] |
> [p.takesPictures(), p.makesCalls(), p.internalMemory()] |
||
# value: [true, true, 33619968] |
# value: [true, true, 33619968]</lang> |
||
</lang> |
|||
=={{header|J}}== |
=={{header|J}}== |
||
<lang j>coclass 'Camera' |
|||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
destroy=: verb define |
|||
destroy=: codestroy |
|||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
codestroy <nowiki>''</nowiki> |
|||
⚫ | |||
⚫ | |||
The adverb Fix (f.) is needed as shown so the superclass constructors get executed in the object, not in the superclass. |
The adverb Fix (f.) is needed as shown so the superclass constructors get executed in the object, not in the superclass. |
||
Line 176: | Line 169: | ||
=={{header|Logtalk}}== |
=={{header|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). |
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). |
||
⚫ | |||
<pre> |
|||
⚫ | |||
...). |
...). |
||
... |
... |
||
:- end_object. |
:- end_object.</lang> |
||
</pre> |
|||
⚫ | |||
<pre> |
|||
⚫ | |||
...). |
...). |
||
... |
... |
||
:- end_object. |
:- end_object.</lang> |
||
</pre> |
|||
⚫ | |||
<pre> |
|||
⚫ | |||
specializes(camera, mobile_phone), |
specializes(camera, mobile_phone), |
||
...). |
...). |
||
... |
... |
||
:- end_object. |
:- end_object.</lang> |
||
</pre> |
|||
=={{header|OCaml}}== |
=={{header|OCaml}}== |
||
Line 234: | Line 221: | ||
<lang perl>package CameraPhone; |
<lang perl>package CameraPhone; |
||
use base qw/Camera MobilePhone/; |
use base qw/Camera MobilePhone/; |
||
#functions go here... |
#functions go here...</lang> |
||
</lang> |
|||
=={{header|Pop11}}== |
=={{header|Pop11}}== |
||
⚫ | |||
<pre> |
|||
⚫ | |||
lib objectclass; |
lib objectclass; |
||
Line 254: | Line 239: | ||
enddefine; |
enddefine; |
||
;;; methods go here |
;;; methods go here</lang> |
||
</pre> |
|||
=={{header|Python}}== |
=={{header|Python}}== |
||
Line 282: | Line 266: | ||
=={{header|Slate}}== |
=={{header|Slate}}== |
||
<lang slate> |
<lang slate>define: #Camera. |
||
define: #Camera. |
|||
define: #MobilePhone. |
define: #MobilePhone. |
||
define: #CameraPhone &parents: {Camera. MobilePhone}. |
define: #CameraPhone &parents: {Camera. MobilePhone}.</lang> |
||
</lang> |
|||
=={{header|Tcl}}== |
=={{header|Tcl}}== |
Revision as of 12:04, 21 November 2009
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.
Ada
Ada 2005 has added interfaces, allowing a limited form of multiple inheritance. <lang ada>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;</lang>
C++
<lang cpp>class Camera {
// ...
};
class MobilePhone {
// ...
};
class CameraPhone:
public Camera, public MobilePhone
{
// ...
};</lang>
Common Lisp
<lang lisp>(defclass camera () ()) (defclass mobile-phone () ()) (defclass camera-phone (camera mobile-phone) ())</lang>
D
<lang d>interface Camera { /+ member function prototypes go here +/ } interface MobilePhone { /+ member function prototypes go here +/ } class CameraPhone: Camera,MobilePhone { /+ member function implementations for Camera, MobilePhone, and CameraPhone go here +/ }</lang>
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.
<lang e>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
}</lang>
The task example:
<lang e>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 } }
}</lang >
And testing that it works as intended:
<lang e> ? def p := makeCameraPhone(p) > [p.takesPictures(), p.makesCalls(), p.internalMemory()]
- value: [true, true, 33619968]</lang>
J
<lang 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=: verb define
codestroy ''
)
NB. additional camera-phone methods go here</lang> The adverb Fix (f.) is needed as shown so the superclass constructors get executed in the object, not in the superclass.
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. <lang java>public interface Camera{
//functions here with no definition... //ex: //public void takePicture();
}</lang> <lang java>public interface MobilePhone{
//functions here with no definition... //ex: //public void makeCall();
}</lang> <lang java>public class CameraPhone implements Camera, MobilePhone{
//functions here...
}</lang>
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). <lang logtalk>:- object(camera,
...). ...
- - end_object.</lang>
<lang logtalk>:- object(mobile_phone,
...). ...
- - end_object.</lang>
<lang logtalk>:- object(camera_phone,
specializes(camera, mobile_phone), ...). ...
- - end_object.</lang>
OCaml
<lang ocaml>class camera =
object (self) (*functions go here...*) end</lang>
<lang ocaml>class mobile_phone =
object (self) (*functions go here...*) end</lang>
<lang ocaml>class camera_phone =
object (self) inherit camera inherit mobile_phone (*functions go here...*) end</lang>
Perl
<lang perl>package Camera;
- functions go here...
1;</lang>
<lang perl>package MobilePhone;
- functions go here...
1;</lang>
<lang perl>package CameraPhone; use Camera; use MobilePhone; @ISA = qw( Camera MobilePhone );
- functions go here...
1;</lang>
or
<lang perl>package CameraPhone; use base qw/Camera MobilePhone/;
- functions go here...</lang>
Pop11
<lang 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</lang>
Python
<lang python>class Camera:
pass #functions go here...</lang>
<lang python>class MobilePhone:
pass #functions go here...</lang>
<lang python>class CameraPhone(Camera, MobilePhone):
pass #functions go here...</lang>
Ruby
Ruby does not have multiple inheritance, but you can mix modules into classes: <lang ruby>module Camera
# define methods here
end class MobilePhone
# define methods here
end class CameraPhone < MobilePhone
include Camera # define methods here
end</lang>
Slate
<lang slate>define: #Camera. define: #MobilePhone. define: #CameraPhone &parents: {Camera. MobilePhone}.</lang>
Tcl
Requires Tcl 8.6 or Tcl 8.5+TclOO <lang Tcl>oo::class create Camera oo::class create MobilePhone oo::class create CameraPhone {
superclass Camera MobilePhone
}</lang>