Abstract type: Difference between revisions
Content added Content deleted
(Abstract type in QBasic) |
Thundergnat (talk | contribs) m (syntax highlighting fixup automation) |
||
Line 18: | Line 18: | ||
=={{header|11l}}== |
=={{header|11l}}== |
||
You can declare a virtual function to not have an implementation by using <code>F.virtual.abstract</code> keyword. A type containing at least one abstract virtual function cannot be instantiated. |
You can declare a virtual function to not have an implementation by using <code>F.virtual.abstract</code> keyword. A type containing at least one abstract virtual function cannot be instantiated. |
||
< |
<syntaxhighlight lang=11l>T AbstractQueue |
||
F.virtual.abstract enqueue(Int item) -> N |
F.virtual.abstract enqueue(Int item) -> N |
||
T PrintQueue(AbstractQueue) |
T PrintQueue(AbstractQueue) |
||
F.virtual.assign enqueue(Int item) -> N |
F.virtual.assign enqueue(Int item) -> N |
||
print(item)</ |
print(item)</syntaxhighlight> |
||
=={{header|AArch64 Assembly}}== |
=={{header|AArch64 Assembly}}== |
||
Line 30: | Line 30: | ||
=={{header|ABAP}}== |
=={{header|ABAP}}== |
||
=== Abstract Class === |
=== Abstract Class === |
||
< |
<syntaxhighlight lang=ABAP>class abs definition abstract. |
||
public section. |
public section. |
||
methods method1 abstract importing iv_value type f exporting ev_ret type i. |
methods method1 abstract importing iv_value type f exporting ev_ret type i. |
||
Line 42: | Line 42: | ||
ev_ret = iv_a + iv_b. |
ev_ret = iv_a + iv_b. |
||
endmethod. |
endmethod. |
||
endclass.</ |
endclass.</syntaxhighlight> |
||
=== Interfaces === |
=== Interfaces === |
||
Line 49: | Line 49: | ||
2. Variables must be static final. The values may be computed at run time. |
2. Variables must be static final. The values may be computed at run time. |
||
3. No static initialiser blockers. No static initialiser helper methods. |
3. No static initialiser blockers. No static initialiser helper methods. |
||
< |
<syntaxhighlight lang=ABAP>interface inter. |
||
methods: method1 importing iv_value type f exporting ev_ret type i, |
methods: method1 importing iv_value type f exporting ev_ret type i, |
||
method2 importing iv_name type string exporting ev_ret type i, |
method2 importing iv_name type string exporting ev_ret type i, |
||
add importing iv_a type i iv_b type i exporting ev_ret type i. |
add importing iv_a type i iv_b type i exporting ev_ret type i. |
||
endinterface.</ |
endinterface.</syntaxhighlight> |
||
=={{header|ActionScript}}== |
=={{header|ActionScript}}== |
||
While ActionScript does not support explicit abstract classes, it does have interfaces. Interfaces in ActionScript may not implement any methods and all methods are public and implicitly abstract. Interfaces can extend other interfaces, and interfaces may be multiply inherited. |
While ActionScript does not support explicit abstract classes, it does have interfaces. Interfaces in ActionScript may not implement any methods and all methods are public and implicitly abstract. Interfaces can extend other interfaces, and interfaces may be multiply inherited. |
||
< |
<syntaxhighlight lang=actionscript>package |
||
{ |
{ |
||
public interface IInterface |
public interface IInterface |
||
Line 64: | Line 64: | ||
function method2(arg1:Array, arg2:Boolean):uint; |
function method2(arg1:Array, arg2:Boolean):uint; |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
Abstract types can also be simulated using the built-in <code>flash.utils.getQualifiedClassName()</code> function in the constructor to check that the runtime type is an inhertied class, and throwing exceptions from "abstract" methods which can be overridden by inheritors to disable them. If any inheriting class does not implement an abstract method, the error will not be thrown until the non-implemented method is called. |
Abstract types can also be simulated using the built-in <code>flash.utils.getQualifiedClassName()</code> function in the constructor to check that the runtime type is an inhertied class, and throwing exceptions from "abstract" methods which can be overridden by inheritors to disable them. If any inheriting class does not implement an abstract method, the error will not be thrown until the non-implemented method is called. |
||
< |
<syntaxhighlight lang=ActionScript> |
||
package { |
package { |
||
import flash.utils.getQualifiedClassName; |
import flash.utils.getQualifiedClassName; |
||
Line 90: | Line 90: | ||
} |
} |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
Inheriting this class: |
Inheriting this class: |
||
< |
<syntaxhighlight lang=ActionScript> |
||
package { |
package { |
||
Line 104: | Line 104: | ||
} |
} |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Ada}}== |
=={{header|Ada}}== |
||
===Interface=== |
===Interface=== |
||
Interfaces in [[Ada]] may have no components or implemented operation except for ones implemented as null operations. Interfaces can be multiply inherited. |
Interfaces in [[Ada]] may have no components or implemented operation except for ones implemented as null operations. Interfaces can be multiply inherited. |
||
< |
<syntaxhighlight lang=ada>type Queue is limited interface; |
||
procedure Enqueue (Lounge : in out Queue; Item : in out Element) is abstract; |
procedure Enqueue (Lounge : in out Queue; Item : in out Element) is abstract; |
||
procedure Dequeue (Lounge : in out Queue; Item : in out Element) is abstract;</ |
procedure Dequeue (Lounge : in out Queue; Item : in out Element) is abstract;</syntaxhighlight> |
||
Interfaces can be declared synchronized or task when intended implementations are to be provided by protected objects or [[task]]s. For example: |
Interfaces can be declared synchronized or task when intended implementations are to be provided by protected objects or [[task]]s. For example: |
||
< |
<syntaxhighlight lang=ada>type Scheduler is task interface; |
||
procedure Plan (Manager : in out Scheduler; Activity : in out Job) is abstract;</ |
procedure Plan (Manager : in out Scheduler; Activity : in out Job) is abstract;</syntaxhighlight> |
||
===Abstract type=== |
===Abstract type=== |
||
Abstract types may provide components and implementation of their operations. Abstract types are singly inherited. |
Abstract types may provide components and implementation of their operations. Abstract types are singly inherited. |
||
< |
<syntaxhighlight lang=ada>with Ada.Finalization; |
||
... |
... |
||
type Node is abstract new Ada.Finalization.Limited_Controlled and Queue with record |
type Node is abstract new Ada.Finalization.Limited_Controlled and Queue with record |
||
Line 126: | Line 126: | ||
overriding procedure Dequeue (Lounge : in out Node; Item : in out Element); |
overriding procedure Dequeue (Lounge : in out Node; Item : in out Element); |
||
overriding procedure Enqueue (Lounge : in out Node; Item : in out Element); |
overriding procedure Enqueue (Lounge : in out Node; Item : in out Element); |
||
procedure Process (X : in out Node) is abstract; -- To be implemented</ |
procedure Process (X : in out Node) is abstract; -- To be implemented</syntaxhighlight> |
||
Here Node is an abstract type that is inherited from Limited_Controlled and implements a node of a [[Doubly-Linked List (element) | doubly linked list]]. It also implements the interface of a queue described above, because any node can be considered a head of the queue of linked elements. For the operation Finalize an implementation is provided to ensure that the element of a list is removed from there upon its finalization. The operation itself is inherited from the parent type Limited_Controlled and then overridden. The operations Dequeue and Enqueue of the Queue interface are also implemented. |
Here Node is an abstract type that is inherited from Limited_Controlled and implements a node of a [[Doubly-Linked List (element) | doubly linked list]]. It also implements the interface of a queue described above, because any node can be considered a head of the queue of linked elements. For the operation Finalize an implementation is provided to ensure that the element of a list is removed from there upon its finalization. The operation itself is inherited from the parent type Limited_Controlled and then overridden. The operations Dequeue and Enqueue of the Queue interface are also implemented. |
||
Line 132: | Line 132: | ||
Using [http://wiki.portal.chalmers.se/agda/agda.php?n=ReferenceManual.Records records] for storing the interface methods and [http://wiki.portal.chalmers.se/agda/pmwiki.php?n=ReferenceManual.InstanceArguments instance arguments] (which are [http://wiki.portal.chalmers.se/agda/pmwiki.php?n=ReferenceManual.ModellingTypeClassesWithInstanceArguments similar] to Haskell type classes) for overloading: |
Using [http://wiki.portal.chalmers.se/agda/agda.php?n=ReferenceManual.Records records] for storing the interface methods and [http://wiki.portal.chalmers.se/agda/pmwiki.php?n=ReferenceManual.InstanceArguments instance arguments] (which are [http://wiki.portal.chalmers.se/agda/pmwiki.php?n=ReferenceManual.ModellingTypeClassesWithInstanceArguments similar] to Haskell type classes) for overloading: |
||
< |
<syntaxhighlight lang=agda>module AbstractInterfaceExample where |
||
open import Function |
open import Function |
||
Line 184: | Line 184: | ||
-- say (cat crazy!) => "meeeoooowwwww!!!" |
-- say (cat crazy!) => "meeeoooowwwww!!!" |
||
-- say (cat plain-cat) => "meow!" |
-- say (cat plain-cat) => "meow!" |
||
-- </ |
-- </syntaxhighlight> |
||
There is <code>dog</code> and <code>cat</code> is objects of different types for which the interface method is implemented. |
There is <code>dog</code> and <code>cat</code> is objects of different types for which the interface method is implemented. |
||
Line 191: | Line 191: | ||
An abstract class contains functions that have no body defined. You cannot instantiate a class that contains abstract functions. |
An abstract class contains functions that have no body defined. You cannot instantiate a class that contains abstract functions. |
||
< |
<syntaxhighlight lang=aikido>class Abs { |
||
public function method1... |
public function method1... |
||
public function method2... |
public function method2... |
||
}</ |
}</syntaxhighlight> |
||
Interfaces in Aikido define a set of functions, operators, classes, interfaces, monitors or threads (but no variables) that must be implemented by a class implementing the interface. |
Interfaces in Aikido define a set of functions, operators, classes, interfaces, monitors or threads (but no variables) that must be implemented by a class implementing the interface. |
||
< |
<syntaxhighlight lang=aikido>interface Inter { |
||
function isFatal : integer |
function isFatal : integer |
||
function operate (para : integer = 0) |
function operate (para : integer = 0) |
||
operator -> (stream, isout) |
operator -> (stream, isout) |
||
}</ |
}</syntaxhighlight> |
||
=={{header|AmigaE}}== |
=={{header|AmigaE}}== |
||
In AmigaE, abstract methods are supported but interfaces are not. |
In AmigaE, abstract methods are supported but interfaces are not. |
||
< |
<syntaxhighlight lang=amigae> |
||
OBJECT fruit |
OBJECT fruit |
||
ENDOBJECT |
ENDOBJECT |
||
Line 226: | Line 226: | ||
FORALL({x},[NEW a, NEW o],`x.color()) |
FORALL({x},[NEW a, NEW o],`x.color()) |
||
ENDPROC |
ENDPROC |
||
</syntaxhighlight> |
|||
</lang> |
|||
prints to the console: |
prints to the console: |
||
Line 232: | Line 232: | ||
=={{header|Apex}}== |
=={{header|Apex}}== |
||
< |
<syntaxhighlight lang=apex> |
||
// Interface |
// Interface |
||
public interface PurchaseOrder { |
public interface PurchaseOrder { |
||
Line 256: | Line 256: | ||
public override Integer abstractMethod() { return 5; } |
public override Integer abstractMethod() { return 5; } |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Argile}}== |
=={{header|Argile}}== |
||
{{works with|Argile|1.0.0}} |
{{works with|Argile|1.0.0}} |
||
< |
<syntaxhighlight lang=Argile>use std |
||
(: abstract class :) |
(: abstract class :) |
||
Line 297: | Line 297: | ||
foobar (new Sub 34) (: prints 46 :) |
foobar (new Sub 34) (: prints 46 :) |
||
foobar (new Sub) (: prints 11 :) |
foobar (new Sub) (: prints 11 :) |
||
foobar (new Abs) (: prints 0 :)</ |
foobar (new Abs) (: prints 0 :)</syntaxhighlight> |
||
Line 304: | Line 304: | ||
=={{header|AutoHotkey}}== |
=={{header|AutoHotkey}}== |
||
{{works with | AutoHotkey_L}} |
{{works with | AutoHotkey_L}} |
||
< |
<syntaxhighlight lang=AutoHotkey>color(r, g, b){ |
||
static color |
static color |
||
If !color |
If !color |
||
Line 332: | Line 332: | ||
msgbox % blue.GetRGB() ; displays 255 |
msgbox % blue.GetRGB() ; displays 255 |
||
return |
return |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|BASIC}}== |
=={{header|BASIC}}== |
||
Line 338: | Line 338: | ||
{{works with|BBC BASIC for Windows}} |
{{works with|BBC BASIC for Windows}} |
||
BBC BASIC is a procedural language with no built-in OO features. The CLASSLIB library implements simple Object Classes with multiple inheritance; an abstract class may be created without any instantiation, the sole purpose of which is for other classes to inherit from it. At least one member or method must be declared, but no error will be generated if there is no implementation: |
BBC BASIC is a procedural language with no built-in OO features. The CLASSLIB library implements simple Object Classes with multiple inheritance; an abstract class may be created without any instantiation, the sole purpose of which is for other classes to inherit from it. At least one member or method must be declared, but no error will be generated if there is no implementation: |
||
< |
<syntaxhighlight lang=bbcbasic> INSTALL @lib$+"CLASSLIB" |
||
REM Declare a class with no implementation: |
REM Declare a class with no implementation: |
||
Line 356: | Line 356: | ||
REM Test by calling the method: |
REM Test by calling the method: |
||
PROC(instance.method)</ |
PROC(instance.method)</syntaxhighlight> |
||
==={{header|QB64}}=== |
==={{header|QB64}}=== |
||
QB64, along with QBasic and QuickBasic (without extension), is not Object-Oriented; however, the following addresses issues raised in the description of the problem as well as the problem itself: |
QB64, along with QBasic and QuickBasic (without extension), is not Object-Oriented; however, the following addresses issues raised in the description of the problem as well as the problem itself: |
||
< |
<syntaxhighlight lang=QB64>'Keep in mind that this code DOES NOT follow appropriate coding structure, but is used for easiest explanation. That |
||
'said, the following is both legal and executable. |
'said, the following is both legal and executable. |
||
Line 409: | Line 409: | ||
'an Integer or a String, being a use of type "c"'s element "d" or "e". |
'an Integer or a String, being a use of type "c"'s element "d" or "e". |
||
Print j.g.e |
Print j.g.e |
||
System </ |
System </syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>15 |
<pre>15 |
||
Line 423: | Line 423: | ||
{{works with|QuickBasic|4.5}} |
{{works with|QuickBasic|4.5}} |
||
{{trans|QB64}} |
{{trans|QB64}} |
||
< |
<syntaxhighlight lang=qbasic>a = 15 |
||
TYPE c |
TYPE c |
||
Line 448: | Line 448: | ||
PRINT i.g.e |
PRINT i.g.e |
||
PRINT g.e |
PRINT g.e |
||
PRINT j.g.e</ |
PRINT j.g.e</syntaxhighlight> |
||
Line 455: | Line 455: | ||
The header file for the abstract class, interfaceAbs.h |
The header file for the abstract class, interfaceAbs.h |
||
< |
<syntaxhighlight lang=c>#ifndef INTERFACE_ABS |
||
#define INTERFACE_ABS |
#define INTERFACE_ABS |
||
Line 487: | Line 487: | ||
do { if (c) { free((c)->instData); free(c); } } while(0); |
do { if (c) { free((c)->instData); free(c); } } while(0); |
||
#endif</ |
#endif</syntaxhighlight> |
||
That will define the abstract class. The next section declares a public interface for a class providing the interface of the abstract class. This class is Silly and |
That will define the abstract class. The next section declares a public interface for a class providing the interface of the abstract class. This class is Silly and |
||
the code is in file silly.h. Note the actual structure of the class is not provided |
the code is in file silly.h. Note the actual structure of the class is not provided |
||
here. We don't want it visible. |
here. We don't want it visible. |
||
< |
<syntaxhighlight lang=c>#ifndef SILLY_H |
||
#define SILLY_H |
#define SILLY_H |
||
#include "intefaceAbs.h" |
#include "intefaceAbs.h" |
||
Line 500: | Line 500: | ||
extern AbsCls Silly_Instance(void *); |
extern AbsCls Silly_Instance(void *); |
||
#endif</ |
#endif</syntaxhighlight> |
||
Ok. Now it is necessary to provide the implementation of the realizable class. |
Ok. Now it is necessary to provide the implementation of the realizable class. |
||
This code should be in silly.c. |
This code should be in silly.c. |
||
< |
<syntaxhighlight lang=c>#include "silly.h" |
||
#include <string.h> |
#include <string.h> |
||
#include <stdio.h> |
#include <stdio.h> |
||
Line 543: | Line 543: | ||
} |
} |
||
ABSTRACT_METHODS( Silly, MyMethod1, MyMethod2, MyMethod3)</ |
ABSTRACT_METHODS( Silly, MyMethod1, MyMethod2, MyMethod3)</syntaxhighlight> |
||
That last macro, ABSTRACT_METHODS may need a little explanation. First note that macros do a string substitution of the parameter values into the arguments of the defined macro, with a little hitch. In the macro definition the ' ## ' expression is special. Here cName ## _Iface gets converted to Silly_Iface, as 'Silly' replaces cName. So the macro call declares an instance of the class record, and defines a constructor named Silly_Instance, which takes a Silly structure as an arguments |
That last macro, ABSTRACT_METHODS may need a little explanation. First note that macros do a string substitution of the parameter values into the arguments of the defined macro, with a little hitch. In the macro definition the ' ## ' expression is special. Here cName ## _Iface gets converted to Silly_Iface, as 'Silly' replaces cName. So the macro call declares an instance of the class record, and defines a constructor named Silly_Instance, which takes a Silly structure as an arguments |
||
and uses the class record it previously set up as well. |
and uses the class record it previously set up as well. |
||
Line 550: | Line 550: | ||
Now all's left is some example code that uses all this stuff. |
Now all's left is some example code that uses all this stuff. |
||
< |
<syntaxhighlight lang=c>#include <stdio.h> |
||
#include "silly.h" |
#include "silly.h" |
||
Line 563: | Line 563: | ||
return 0; |
return 0; |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|C sharp|C#}}== |
=={{header|C sharp|C#}}== |
||
< |
<syntaxhighlight lang=csharp>abstract class Class1 |
||
{ |
{ |
||
public abstract void method1(); |
public abstract void method1(); |
||
Line 574: | Line 574: | ||
return 0; |
return 0; |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
=={{header|C++}}== |
=={{header|C++}}== |
||
You can declare a virtual function to not have an implementation (called "pure virtual function") by the following "<tt>= 0</tt>" syntax after the method declaration. A class containing at least one pure virtual function (or inheriting one and not overriding it) cannot be instantiated. |
You can declare a virtual function to not have an implementation (called "pure virtual function") by the following "<tt>= 0</tt>" syntax after the method declaration. A class containing at least one pure virtual function (or inheriting one and not overriding it) cannot be instantiated. |
||
< |
<syntaxhighlight lang=cpp>class Abs { |
||
public: |
public: |
||
virtual int method1(double value) = 0; |
virtual int method1(double value) = 0; |
||
Line 584: | Line 584: | ||
return a+b; |
return a+b; |
||
} |
} |
||
};</ |
};</syntaxhighlight> |
||
Because C++ allows multiple inheritance of classes, no distinction is made between interfaces and abstract classes. |
Because C++ allows multiple inheritance of classes, no distinction is made between interfaces and abstract classes. |
||
Line 591: | Line 591: | ||
In Caché, abstract and data type classes cannot be instantiated directly - there must be a 'concrete subclass' that extends them as well as the '%RegisteredObject' class in order to instantiate an object, see example below. |
In Caché, abstract and data type classes cannot be instantiated directly - there must be a 'concrete subclass' that extends them as well as the '%RegisteredObject' class in order to instantiate an object, see example below. |
||
< |
<syntaxhighlight lang=cos>Class Abstract.Class.Shape [ Abstract ] |
||
{ |
{ |
||
Parameter SHAPE = 1; |
Parameter SHAPE = 1; |
||
Line 605: | Line 605: | ||
Write ..%ClassName()_$Case(..%Extends(..%PackageName()_".Shape"), 1: " is a ", : " is not a ")_"shape" |
Write ..%ClassName()_$Case(..%Extends(..%PackageName()_".Shape"), 1: " is a ", : " is not a ")_"shape" |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
Data type classes differ because they cannot contain properties, see example below. |
Data type classes differ because they cannot contain properties, see example below. |
||
< |
<syntaxhighlight lang=cos>Class Abstract.DataType.Shape [ ClassType = datatype ] |
||
{ |
{ |
||
Parameter SHAPE = 1; |
Parameter SHAPE = 1; |
||
Line 622: | Line 622: | ||
Write ..%ClassName()_$Case(..%Extends(..%PackageName()_".Shape"), 1: " is a ", : " is not a ")_"shape" |
Write ..%ClassName()_$Case(..%Extends(..%PackageName()_".Shape"), 1: " is a ", : " is not a ")_"shape" |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
Both class types can contain implementation code. Caché allows multiple inheritance of classes, so no distinction is made between abstract classes and interfaces. |
Both class types can contain implementation code. Caché allows multiple inheritance of classes, so no distinction is made between abstract classes and interfaces. |
||
Line 641: | Line 641: | ||
Using defprotocol, we can define what is essentially an interface. |
Using defprotocol, we can define what is essentially an interface. |
||
< |
<syntaxhighlight lang=lisp>(defprotocol Foo (foo [this]))</syntaxhighlight> |
||
=={{header|COBOL}}== |
=={{header|COBOL}}== |
||
===Interface=== |
===Interface=== |
||
{{trans|F#}} |
{{trans|F#}} |
||
< |
<syntaxhighlight lang=cobol> INTERFACE-ID. Shape. |
||
PROCEDURE DIVISION. |
PROCEDURE DIVISION. |
||
Line 703: | Line 703: | ||
END OBJECT. |
END OBJECT. |
||
END CLASS Rectangle.</ |
END CLASS Rectangle.</syntaxhighlight> |
||
=={{header|Common Lisp}}== |
=={{header|Common Lisp}}== |
||
Line 709: | Line 709: | ||
In Common Lisp, classes do not implement methods, but methods specialized for particular kinds of arguments may be defined for generic functions. Since we can programmatically determine whether methods are defined for a list of arguments, we can simulate a kind of abstract type. We define an abstract type <code>kons</code> to which an object belongs if methods for <code>kar</code> and <code>kdr</code> are defined for it. We define a type predicate <code>konsp</code> and a type <code>kons</code> in terms of the type predicate. |
In Common Lisp, classes do not implement methods, but methods specialized for particular kinds of arguments may be defined for generic functions. Since we can programmatically determine whether methods are defined for a list of arguments, we can simulate a kind of abstract type. We define an abstract type <code>kons</code> to which an object belongs if methods for <code>kar</code> and <code>kdr</code> are defined for it. We define a type predicate <code>konsp</code> and a type <code>kons</code> in terms of the type predicate. |
||
< |
<syntaxhighlight lang=lisp>(defgeneric kar (kons) |
||
(:documentation "Return the kar of a kons.")) |
(:documentation "Return the kar of a kons.")) |
||
Line 721: | Line 721: | ||
(deftype kons () |
(deftype kons () |
||
'(satisfies konsp))</ |
'(satisfies konsp))</syntaxhighlight> |
||
We can make the built-in types <code>cons</code> and <code>integer</code> <code>kons</code>es. We start with <code>cons</code>, using the obvious definitions. |
We can make the built-in types <code>cons</code> and <code>integer</code> <code>kons</code>es. We start with <code>cons</code>, using the obvious definitions. |
||
< |
<syntaxhighlight lang=lisp>(defmethod kar ((cons cons)) |
||
(car cons)) |
(car cons)) |
||
Line 734: | Line 734: | ||
(typep (cons 1 2) 'kons) ; => t |
(typep (cons 1 2) 'kons) ; => t |
||
(kar (cons 1 2)) ; => 1 |
(kar (cons 1 2)) ; => 1 |
||
(kdr (cons 1 2)) ; => 2</ |
(kdr (cons 1 2)) ; => 2</syntaxhighlight> |
||
For integers, we'll define the <code>kar</code> of <var>n</var> to be <var>1</var> and the <code>kdr</code> of <var>n</var> to be <var>n - 1</var>. This means that for an integer <var>n</var>, <var>n</var> = <code>(+ (kar <var>n</var>) (kdr <var>n</var>))</code>. |
For integers, we'll define the <code>kar</code> of <var>n</var> to be <var>1</var> and the <code>kdr</code> of <var>n</var> to be <var>n - 1</var>. This means that for an integer <var>n</var>, <var>n</var> = <code>(+ (kar <var>n</var>) (kdr <var>n</var>))</code>. |
||
< |
<syntaxhighlight lang=lisp>(defmethod kar ((n integer)) |
||
1) |
1) |
||
Line 748: | Line 748: | ||
(typep 45 'kons) ; => t |
(typep 45 'kons) ; => t |
||
(kar 45) ; => 1 |
(kar 45) ; => 1 |
||
(kdr 45) ; => 44</ |
(kdr 45) ; => 44</syntaxhighlight> |
||
=={{header|Component Pascal}}== |
=={{header|Component Pascal}}== |
||
< |
<syntaxhighlight lang=oberon2> |
||
(* Abstract type *) |
(* Abstract type *) |
||
Object = POINTER TO ABSTRACT RECORD END; |
Object = POINTER TO ABSTRACT RECORD END; |
||
Line 763: | Line 763: | ||
x,y: REAL |
x,y: REAL |
||
END; |
END; |
||
</syntaxhighlight> |
|||
</lang> |
|||
... |
... |
||
< |
<syntaxhighlight lang=oberon2> |
||
(* Abstract method of Object *) |
(* Abstract method of Object *) |
||
PROCEDURE (dn: Object) Show*, NEW, ABSTRACT; |
PROCEDURE (dn: Object) Show*, NEW, ABSTRACT; |
||
Line 781: | Line 781: | ||
StdLog.Real(p.y);StdLog.String(");");StdLog.Ln |
StdLog.Real(p.y);StdLog.String(");");StdLog.Ln |
||
END Show; |
END Show; |
||
</syntaxhighlight> |
|||
</lang> |
|||
For usage see tasks Stacks. |
For usage see tasks Stacks. |
||
=={{header|Crystal}}== |
=={{header|Crystal}}== |
||
< |
<syntaxhighlight lang=ruby>abstract class Animal # only abstract class can have abstract methods |
||
abstract def move |
abstract def move |
||
abstract def think |
abstract def think |
||
Line 825: | Line 825: | ||
# Animal.new # => can't instantiate abstract class |
# Animal.new # => can't instantiate abstract class |
||
he = Human.new("Andrew") # ok |
he = Human.new("Andrew") # ok |
||
he.process</ |
he.process</syntaxhighlight> |
||
Note that "class" can be replaced with "struct" in the above example, because Crystal also supports abstract structs and their inheritance. |
Note that "class" can be replaced with "struct" in the above example, because Crystal also supports abstract structs and their inheritance. |
||
=={{header|D}}== |
=={{header|D}}== |
||
< |
<syntaxhighlight lang=d>import std.stdio; |
||
class Foo { |
class Foo { |
||
Line 855: | Line 855: | ||
} |
} |
||
void main() {}</ |
void main() {}</syntaxhighlight> |
||
=={{header|Delphi}}== |
=={{header|Delphi}}== |
||
Abstract Class introduced in Delphi 2006. An abstract class cannot be instantiated and must be derived from in order to be used. |
Abstract Class introduced in Delphi 2006. An abstract class cannot be instantiated and must be derived from in order to be used. |
||
< |
<syntaxhighlight lang=delphi>TSomeClass = class abstract (TObject) |
||
... |
... |
||
end;</ |
end;</syntaxhighlight> |
||
Abstract Methods can only be implemented in derived classes. A concrete class that contains abstract methods can be instantiated. A warning will be generated at compile time, and an EAbstractError exception will thrown if the method is called at run time. |
Abstract Methods can only be implemented in derived classes. A concrete class that contains abstract methods can be instantiated. A warning will be generated at compile time, and an EAbstractError exception will thrown if the method is called at run time. |
||
< |
<syntaxhighlight lang=delphi>type |
||
TMyObject = class(TObject) |
TMyObject = class(TObject) |
||
public |
public |
||
Line 879: | Line 879: | ||
begin |
begin |
||
AbstractFunction; // Calling the abstract function |
AbstractFunction; // Calling the abstract function |
||
end;</ |
end;</syntaxhighlight> |
||
=={{header|DWScript}}== |
=={{header|DWScript}}== |
||
Line 893: | Line 893: | ||
A simple abstract type without enforcement can be created using the interface expression: |
A simple abstract type without enforcement can be created using the interface expression: |
||
< |
<syntaxhighlight lang=e>interface Foo { |
||
to bar(a :int, b :int) |
to bar(a :int, b :int) |
||
}</ |
}</syntaxhighlight> |
||
With enforcement, a separate ''stamp'' is created which must be applied to the instances. This is analogous to a Java interface. |
With enforcement, a separate ''stamp'' is created which must be applied to the instances. This is analogous to a Java interface. |
||
< |
<syntaxhighlight lang=e>interface Foo guards FooStamp { |
||
to bar(a :int, b :int) |
to bar(a :int, b :int) |
||
} |
} |
||
Line 907: | Line 907: | ||
return a - b |
return a - b |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Eiffel}}== |
=={{header|Eiffel}}== |
||
< |
<syntaxhighlight lang=Eiffel> |
||
deferred class |
deferred class |
||
AN_ABSTRACT_CLASS |
AN_ABSTRACT_CLASS |
||
Line 929: | Line 929: | ||
end |
end |
||
</syntaxhighlight> |
|||
</lang> |
|||
A more expressive view of an Abstract type in Eiffel: |
A more expressive view of an Abstract type in Eiffel: |
||
< |
<syntaxhighlight lang=eiffel> |
||
note |
note |
||
title: "Prototype Person" |
title: "Prototype Person" |
||
Line 994: | Line 994: | ||
end |
end |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Elena}}== |
=={{header|Elena}}== |
||
< |
<syntaxhighlight lang=elena>abstract class Bike |
||
{ |
{ |
||
abstract run(); |
abstract run(); |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|F Sharp|F#}}== |
=={{header|F Sharp|F#}}== |
||
A type with only abstract members and without constructors is an '''interface''' (when not marked with the <code>AbstractClass</code> attribute). Example: |
A type with only abstract members and without constructors is an '''interface''' (when not marked with the <code>AbstractClass</code> attribute). Example: |
||
< |
<syntaxhighlight lang=fsharp>type Shape = |
||
abstract Perimeter: unit -> float |
abstract Perimeter: unit -> float |
||
abstract Area: unit -> float |
abstract Area: unit -> float |
||
Line 1,012: | Line 1,012: | ||
interface Shape with |
interface Shape with |
||
member x.Perimeter() = 2.0 * width + 2.0 * height |
member x.Perimeter() = 2.0 * width + 2.0 * height |
||
member x.Area() = width * height</ |
member x.Area() = width * height</syntaxhighlight> |
||
A type that leaves some or all members unimplemented, is an '''abstract class'''. It has to be marked with the <code>AbstractClass</code> attribute. Example: |
A type that leaves some or all members unimplemented, is an '''abstract class'''. It has to be marked with the <code>AbstractClass</code> attribute. Example: |
||
< |
<syntaxhighlight lang= fsharp>[<AbstractClass>] |
||
type Bird() = |
type Bird() = |
||
// an abstract (=virtual) method with default impl. |
// an abstract (=virtual) method with default impl. |
||
Line 1,030: | Line 1,030: | ||
inherit Bird() |
inherit Bird() |
||
override x.Move() = printfn "walking" |
override x.Move() = printfn "walking" |
||
override x.Sing() = "hiss hiss!"</ |
override x.Sing() = "hiss hiss!"</syntaxhighlight> |
||
=={{header|Fantom}}== |
=={{header|Fantom}}== |
||
< |
<syntaxhighlight lang=fantom> |
||
abstract class X |
abstract class X |
||
{ |
{ |
||
Line 1,062: | Line 1,062: | ||
} |
} |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Forth}}== |
=={{header|Forth}}== |
||
Line 1,068: | Line 1,068: | ||
{{trans|Fantom}} |
{{trans|Fantom}} |
||
There are numerous, mutually incompatible object oriented frameworks for Forth. This one works with the FOOS preprocessor extension of [[4tH]]. |
There are numerous, mutually incompatible object oriented frameworks for Forth. This one works with the FOOS preprocessor extension of [[4tH]]. |
||
< |
<syntaxhighlight lang=forth>include 4pp/lib/foos.4pp |
||
:: X() |
:: X() |
||
Line 1,092: | Line 1,092: | ||
; |
; |
||
Main</ |
Main</syntaxhighlight> |
||
Works with any ANS Forth |
Works with any ANS Forth |
||
Line 1,098: | Line 1,098: | ||
Needs the FMS-SI (single inheritance) library code located here: |
Needs the FMS-SI (single inheritance) library code located here: |
||
http://soton.mpeforth.com/flag/fms/index.html |
http://soton.mpeforth.com/flag/fms/index.html |
||
< |
<syntaxhighlight lang=forth>include FMS-SI.f |
||
The FMS object extension uses duck typing and so has no need for abstract types. |
The FMS object extension uses duck typing and so has no need for abstract types. |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Fortran}}== |
=={{header|Fortran}}== |
||
Simple abstract derived type (i.e. abstract class) in Fortran 2008 |
Simple abstract derived type (i.e. abstract class) in Fortran 2008 |
||
< |
<syntaxhighlight lang=fortran> |
||
! abstract derived type |
! abstract derived type |
||
type, abstract :: TFigure |
type, abstract :: TFigure |
||
Line 1,122: | Line 1,122: | ||
end function calculate_area |
end function calculate_area |
||
end interface |
end interface |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|FreeBASIC}}== |
=={{header|FreeBASIC}}== |
||
Line 1,129: | Line 1,129: | ||
However, you can effectively create an abstract type by declaring all its methods to be abstract, so that they do not require a body in the declaring type itself. Such methods can then be overridden and implemented by its derived types. For example :- |
However, you can effectively create an abstract type by declaring all its methods to be abstract, so that they do not require a body in the declaring type itself. Such methods can then be overridden and implemented by its derived types. For example :- |
||
< |
<syntaxhighlight lang=freebasic>' FB 1.05.0 Win64 |
||
Type Animal Extends Object |
Type Animal Extends Object |
||
Line 1,171: | Line 1,171: | ||
Print |
Print |
||
Print "Press any key to quit program" |
Print "Press any key to quit program" |
||
Sleep</ |
Sleep</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,181: | Line 1,181: | ||
=={{header|Genyris}}== |
=={{header|Genyris}}== |
||
In Genyris by default there are no constructors. In effect all classes are Abstract until they are used to tag (describe) an object. This in keeping with the language's roots in Description Logic. To prevent the class ever being associated with an instance it suffices to force the validator to fail. |
In Genyris by default there are no constructors. In effect all classes are Abstract until they are used to tag (describe) an object. This in keeping with the language's roots in Description Logic. To prevent the class ever being associated with an instance it suffices to force the validator to fail. |
||
< |
<syntaxhighlight lang=genyris>class AbstractStack() |
||
def .valid?(object) nil |
def .valid?(object) nil |
||
tag AbstractStack some-object # always fails</ |
tag AbstractStack some-object # always fails</syntaxhighlight> |
||
However this is not much use if we want to use an abstract class to define an '''interface'''. Here is a quasi-abstract class which can be used to tag objects if they conform to the class's membership expectations. In this case it wants two methods, ''.enstack'' and ''.destack'': |
However this is not much use if we want to use an abstract class to define an '''interface'''. Here is a quasi-abstract class which can be used to tag objects if they conform to the class's membership expectations. In this case it wants two methods, ''.enstack'' and ''.destack'': |
||
< |
<syntaxhighlight lang=genyris>class StackInterface() |
||
def .valid?(object) |
def .valid?(object) |
||
object |
object |
||
Line 1,194: | Line 1,194: | ||
is-instance? .enstack Closure |
is-instance? .enstack Closure |
||
bound? .destack |
bound? .destack |
||
is-instance? .destack Closure</ |
is-instance? .destack Closure</syntaxhighlight> |
||
So if ever we find an object which conforms to the validator it can be tagged. Here's a 'traditional' class definition using the Object class which ''does'' provide a constructor: |
So if ever we find an object which conforms to the validator it can be tagged. Here's a 'traditional' class definition using the Object class which ''does'' provide a constructor: |
||
< |
<syntaxhighlight lang=genyris>class XYZstack(Object) |
||
def .init() |
def .init() |
||
var .items () |
var .items () |
||
Line 1,205: | Line 1,205: | ||
var tmp (car .items) |
var tmp (car .items) |
||
setq .items (cdr .items) |
setq .items (cdr .items) |
||
tmp</ |
tmp</syntaxhighlight> |
||
Now we can tag an object that conforms to the Interface: |
Now we can tag an object that conforms to the Interface: |
||
< |
<syntaxhighlight lang=genyris>tag StackInterface (XYZstack(.new))</syntaxhighlight> |
||
=={{header|Go}}== |
=={{header|Go}}== |
||
Line 1,216: | Line 1,216: | ||
In the following example, the Dog and Cat types both satisfy the Beast interface because they each have the specified methods. The ''bprint'' function can print details for any Beast. |
In the following example, the Dog and Cat types both satisfy the Beast interface because they each have the specified methods. The ''bprint'' function can print details for any Beast. |
||
< |
<syntaxhighlight lang=go>package main |
||
import "fmt" |
import "fmt" |
||
Line 1,257: | Line 1,257: | ||
bprint(d) |
bprint(d) |
||
bprint(c) |
bprint(c) |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,269: | Line 1,269: | ||
As in [[Java]], methods that are declared but not implemented are called "abstract" methods. An interface is a class-level typing construct that can only contain abstract method declarations (well, and constants, but pay no attention to those). |
As in [[Java]], methods that are declared but not implemented are called "abstract" methods. An interface is a class-level typing construct that can only contain abstract method declarations (well, and constants, but pay no attention to those). |
||
< |
<syntaxhighlight lang=groovy>public interface Interface { |
||
int method1(double value) |
int method1(double value) |
||
int method2(String name) |
int method2(String name) |
||
int add(int a, int b) |
int add(int a, int b) |
||
}</ |
}</syntaxhighlight> |
||
An abstract class may implement some of its methods and leave others unimplemented. The unimplemented methods and the class itself must be declared "abstract". |
An abstract class may implement some of its methods and leave others unimplemented. The unimplemented methods and the class itself must be declared "abstract". |
||
< |
<syntaxhighlight lang=groovy>public abstract class Abstract1 { |
||
abstract public int methodA(Date value) |
abstract public int methodA(Date value) |
||
abstract protected int methodB(String name) |
abstract protected int methodB(String name) |
||
int add(int a, int b) { a + b } |
int add(int a, int b) { a + b } |
||
}</ |
}</syntaxhighlight> |
||
An abstract class may also be used to partially implement an interface. Here class "Abstract2" implements the "add" method from the inherited "Interface", but leaves the other two methods, "method1" and "method2", unimplemented. Abstract methods that an abstract class inherits from an interface or another abstract class do not have to be redeclared. |
An abstract class may also be used to partially implement an interface. Here class "Abstract2" implements the "add" method from the inherited "Interface", but leaves the other two methods, "method1" and "method2", unimplemented. Abstract methods that an abstract class inherits from an interface or another abstract class do not have to be redeclared. |
||
< |
<syntaxhighlight lang=groovy>public abstract class Abstract2 implements Interface { |
||
int add(int a, int b) { a + b } |
int add(int a, int b) { a + b } |
||
}</ |
}</syntaxhighlight> |
||
Interfaces and abstract classes cannot be instantiated directly. There must be a "concrete subclass" that contains a complete implementation in order to instantiate an object. |
Interfaces and abstract classes cannot be instantiated directly. There must be a "concrete subclass" that contains a complete implementation in order to instantiate an object. |
||
< |
<syntaxhighlight lang=groovy>public class Concrete1 implements Interface { |
||
public int method1(double value) { value as int } |
public int method1(double value) { value as int } |
||
public int method2(String name) { (! name) ? 0 : name.toList().collect { it as char }.sum() } |
public int method2(String name) { (! name) ? 0 : name.toList().collect { it as char }.sum() } |
||
Line 1,302: | Line 1,302: | ||
public int method1(double value) { value as int } |
public int method1(double value) { value as int } |
||
public int method2(String name) { (! name) ? 0 : name.toList().collect { it as char }.sum() } |
public int method2(String name) { (! name) ? 0 : name.toList().collect { it as char }.sum() } |
||
}</ |
}</syntaxhighlight> |
||
Notice that there are no extra descriptive keywords on the interface method declarations. Interface methods are assumed to be both abstract and public. |
Notice that there are no extra descriptive keywords on the interface method declarations. Interface methods are assumed to be both abstract and public. |
||
Obligatory test: |
Obligatory test: |
||
< |
<syntaxhighlight lang=groovy>def c1 = new Concrete1() |
||
assert c1 instanceof Interface |
assert c1 instanceof Interface |
||
println (new Concrete1().method2("Superman")) |
println (new Concrete1().method2("Superman")) |
||
Line 1,318: | Line 1,318: | ||
assert c3 instanceof Interface |
assert c3 instanceof Interface |
||
assert c3 instanceof Abstract2 |
assert c3 instanceof Abstract2 |
||
println (new Concrete3().method2("Hellboy"))</ |
println (new Concrete3().method2("Hellboy"))</syntaxhighlight> |
||
Obligatory test output: |
Obligatory test output: |
||
Line 1,332: | Line 1,332: | ||
For example, the built-in type class Eq (the types that can be compared for equality) can be declared as follows: |
For example, the built-in type class Eq (the types that can be compared for equality) can be declared as follows: |
||
< |
<syntaxhighlight lang=haskell>class Eq a where |
||
(==) :: a -> a -> Bool |
(==) :: a -> a -> Bool |
||
(/=) :: a -> a -> Bool</ |
(/=) :: a -> a -> Bool</syntaxhighlight> |
||
Default implementations of the functions can be provided: |
Default implementations of the functions can be provided: |
||
< |
<syntaxhighlight lang=haskell>class Eq a where |
||
(==) :: a -> a -> Bool |
(==) :: a -> a -> Bool |
||
(/=) :: a -> a -> Bool |
(/=) :: a -> a -> Bool |
||
x /= y = not (x == y) |
x /= y = not (x == y) |
||
x == y = not (x /= y)</ |
x == y = not (x /= y)</syntaxhighlight> |
||
Here default implementations of each of the operators is circularly defined in terms of the other, for convenience of the programmer; so the programmer only needs to implement one of them for it to work. |
Here default implementations of each of the operators is circularly defined in terms of the other, for convenience of the programmer; so the programmer only needs to implement one of them for it to work. |
||
Consider the following function which uses the operator == of the type class Eq from above. The arguments to == above were of the unknown type "a", which is of class Eq, so the type of the expression below now must include this restriction: |
Consider the following function which uses the operator == of the type class Eq from above. The arguments to == above were of the unknown type "a", which is of class Eq, so the type of the expression below now must include this restriction: |
||
< |
<syntaxhighlight lang=haskell>func :: (Eq a) => a -> Bool |
||
func x = x == x</ |
func x = x == x</syntaxhighlight> |
||
Suppose I make a new type |
Suppose I make a new type |
||
< |
<syntaxhighlight lang=haskell>data Foo = Foo {x :: Integer, str :: String}</syntaxhighlight> |
||
One could then provide an implementation ("instance") the type class Eq with this type |
One could then provide an implementation ("instance") the type class Eq with this type |
||
< |
<syntaxhighlight lang=haskell>instance Eq Foo where |
||
(Foo x1 str1) == (Foo x2 str2) = |
(Foo x1 str1) == (Foo x2 str2) = |
||
(x1 == x2) && (str1 == str2)</ |
(x1 == x2) && (str1 == str2)</syntaxhighlight> |
||
And now I can, for example, use the function "func" on two arguments of type Foo. |
And now I can, for example, use the function "func" on two arguments of type Foo. |
||
Line 1,362: | Line 1,362: | ||
An abstract class is a class with abstract methods. Icon is not object-oriented. |
An abstract class is a class with abstract methods. Icon is not object-oriented. |
||
< |
<syntaxhighlight lang=unicon>class abstraction() |
||
abstract method compare(l,r) # generates runerr(700, "method compare()") |
abstract method compare(l,r) # generates runerr(700, "method compare()") |
||
end</ |
end</syntaxhighlight> |
||
=={{header|J}}== |
=={{header|J}}== |
||
Line 1,380: | Line 1,380: | ||
Methods that don't have an implementation are called abstract methods in Java. A class that contains an abstract method or inherits one but did not override it must be an abstract class; but an abstract class does not need to contain any abstract methods. An abstract class cannot be instantiated. If a method is abstract, it cannot be private. |
Methods that don't have an implementation are called abstract methods in Java. A class that contains an abstract method or inherits one but did not override it must be an abstract class; but an abstract class does not need to contain any abstract methods. An abstract class cannot be instantiated. If a method is abstract, it cannot be private. |
||
< |
<syntaxhighlight lang=java>public abstract class Abs { |
||
public abstract int method1(double value); |
public abstract int method1(double value); |
||
protected abstract int method2(String name); |
protected abstract int method2(String name); |
||
Line 1,386: | Line 1,386: | ||
return a + b; |
return a + b; |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
Before Java 8, interfaces could not implement any methods and all methods were implicitly public and abstract. |
Before Java 8, interfaces could not implement any methods and all methods were implicitly public and abstract. |
||
< |
<syntaxhighlight lang=java>public interface Inter { |
||
int method1(double value); |
int method1(double value); |
||
int method2(String name); |
int method2(String name); |
||
int add(int a, int b); |
int add(int a, int b); |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Julia}}== |
=={{header|Julia}}== |
||
Line 1,398: | Line 1,398: | ||
Usage: |
Usage: |
||
< |
<syntaxhighlight lang=julia>abstract type «name» end |
||
abstract type «name» <: «supertype» end</ |
abstract type «name» <: «supertype» end</syntaxhighlight> |
||
Examples: |
Examples: |
||
< |
<syntaxhighlight lang=julia>abstract type Number end |
||
abstract type Real <: Number end |
abstract type Real <: Number end |
||
abstract type FloatingPoint <: Real end |
abstract type FloatingPoint <: Real end |
||
abstract type Integer <: Real end |
abstract type Integer <: Real end |
||
abstract type Signed <: Integer end |
abstract type Signed <: Integer end |
||
abstract type Unsigned <: Integer end</ |
abstract type Unsigned <: Integer end</syntaxhighlight> |
||
See more [http://docs.julialang.org/en/latest/manual/types/#abstract-types] |
See more [http://docs.julialang.org/en/latest/manual/types/#abstract-types] |
||
Line 1,415: | Line 1,415: | ||
Here's a very simple (and silly) example of both: |
Here's a very simple (and silly) example of both: |
||
< |
<syntaxhighlight lang=scala>// version 1.1 |
||
interface Announcer { |
interface Announcer { |
||
Line 1,469: | Line 1,469: | ||
announceName() // inherits Announcer's implementation |
announceName() // inherits Announcer's implementation |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,484: | Line 1,484: | ||
=={{header|Lasso}}== |
=={{header|Lasso}}== |
||
Instead of abstract classes or interfaces, Lasso uses a [http://lassoguide.com/language/types.html trait system]. |
Instead of abstract classes or interfaces, Lasso uses a [http://lassoguide.com/language/types.html trait system]. |
||
< |
<syntaxhighlight lang=lasso>define abstract_trait => trait { |
||
require get(index::integer) |
require get(index::integer) |
||
Line 1,504: | Line 1,504: | ||
#test->second + "\n" |
#test->second + "\n" |
||
#test->third + "\n" |
#test->third + "\n" |
||
#test->fourth + "\n"</ |
#test->fourth + "\n"</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,519: | Line 1,519: | ||
In some movie script: |
In some movie script: |
||
< |
<syntaxhighlight lang=lingo>on extendAbstractClass (instance, abstractClass) |
||
-- 'raw' instance of abstract class is made parent ("ancestor") of the |
-- 'raw' instance of abstract class is made parent ("ancestor") of the |
||
-- passed instance, i.e. the passed instance extends the abstract class |
-- passed instance, i.e. the passed instance extends the abstract class |
||
instance.setProp(#ancestor, abstractClass.rawNew()) |
instance.setProp(#ancestor, abstractClass.rawNew()) |
||
end</ |
end</syntaxhighlight> |
||
Parent script "AbstractClass": |
Parent script "AbstractClass": |
||
< |
<syntaxhighlight lang=lingo>-- instantiation of abstract class by calling its constructor fails |
||
on new (me) |
on new (me) |
||
-- optional: show error message as alert |
-- optional: show error message as alert |
||
Line 1,537: | Line 1,537: | ||
put me.ringtone |
put me.ringtone |
||
end repeat |
end repeat |
||
end</ |
end</syntaxhighlight> |
||
Parent script "MyClass" |
Parent script "MyClass" |
||
< |
<syntaxhighlight lang=lingo>property ringtone |
||
on new (me) |
on new (me) |
||
Line 1,550: | Line 1,550: | ||
on foo (me) |
on foo (me) |
||
put "FOO" |
put "FOO" |
||
end</ |
end</syntaxhighlight> |
||
Usage: |
Usage: |
||
< |
<syntaxhighlight lang=lingo>obj = script("MyClass").new() |
||
obj.ring(3) |
obj.ring(3) |
||
-- "Bell" |
-- "Bell" |
||
Line 1,562: | Line 1,562: | ||
test = script("AbstractClass").new() |
test = script("AbstractClass").new() |
||
put test |
put test |
||
-- <Void></ |
-- <Void></syntaxhighlight> |
||
=== Interfaces === |
=== Interfaces === |
||
In some movie script: |
In some movie script: |
||
< |
<syntaxhighlight lang=lingo>on implementsInterface (instance, interfaceClass) |
||
interfaceFuncs = interfaceClass.handlers() |
interfaceFuncs = interfaceClass.handlers() |
||
funcs = instance.handlers() |
funcs = instance.handlers() |
||
Line 1,578: | Line 1,578: | ||
end repeat |
end repeat |
||
return TRUE |
return TRUE |
||
end</ |
end</syntaxhighlight> |
||
Parent script "InterfaceClass": |
Parent script "InterfaceClass": |
||
(Note: in Lingo closing function definitions with "end" is optional, so this a valid definition of 3 empty functions) |
(Note: in Lingo closing function definitions with "end" is optional, so this a valid definition of 3 empty functions) |
||
< |
<syntaxhighlight lang=lingo>on foo |
||
on bar |
on bar |
||
on foobar</ |
on foobar</syntaxhighlight> |
||
Parent script "MyClass": |
Parent script "MyClass": |
||
< |
<syntaxhighlight lang=lingo>on new (me) |
||
-- if this class doesn't implement all functions of the |
-- if this class doesn't implement all functions of the |
||
-- interface class, instantiation fails |
-- interface class, instantiation fails |
||
Line 1,606: | Line 1,606: | ||
on foobar (me) |
on foobar (me) |
||
put "FOOBAR" |
put "FOOBAR" |
||
end</ |
end</syntaxhighlight> |
||
Usage: |
Usage: |
||
< |
<syntaxhighlight lang=lingo>obj = script("MyClass").new() |
||
put obj -- would show <Void> if interface is not fully implemented |
put obj -- would show <Void> if interface is not fully implemented |
||
-- <offspring "MyClass" 2 171868></ |
-- <offspring "MyClass" 2 171868></syntaxhighlight> |
||
=={{header|Logtalk}}== |
=={{header|Logtalk}}== |
||
Line 1,617: | Line 1,617: | ||
Logtalk supports the definition of interfaces (protocols), which can contain public, protected, and private declarations of methods (predicates). In addition, an object can qualify an implements relation with an interface (protocol) using the keywords "public", "protected", and "private". |
Logtalk supports the definition of interfaces (protocols), which can contain public, protected, and private declarations of methods (predicates). In addition, an object can qualify an implements relation with an interface (protocol) using the keywords "public", "protected", and "private". |
||
< |
<syntaxhighlight lang=logtalk> |
||
:- protocol(datep). |
:- protocol(datep). |
||
Line 1,627: | Line 1,627: | ||
:- end_protocol. |
:- end_protocol. |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Lua}}== |
=={{header|Lua}}== |
||
Lua does not include built-in object oriented paradigms. These features can be added using simple code such as the following: |
Lua does not include built-in object oriented paradigms. These features can be added using simple code such as the following: |
||
< |
<syntaxhighlight lang=lua>BaseClass = {} |
||
function class ( baseClass ) |
function class ( baseClass ) |
||
Line 1,664: | Line 1,664: | ||
BaseClass.class = class |
BaseClass.class = class |
||
BaseClass.abstractClass = abstractClass</ |
BaseClass.abstractClass = abstractClass</syntaxhighlight> |
||
The 'class' function produces a new class from an existing parent class (BaseClass is default). From this class other classes or instances can be created. If a class is created through the 'abstractClass' function, however, the resulting class will throw an error if one attempts to instantiate it. Example: |
The 'class' function produces a new class from an existing parent class (BaseClass is default). From this class other classes or instances can be created. If a class is created through the 'abstractClass' function, however, the resulting class will throw an error if one attempts to instantiate it. Example: |
||
< |
<syntaxhighlight lang=lua>A = class() -- New class A inherits BaseClass by default |
||
AA = A:class() -- New class AA inherits from existing class A |
AA = A:class() -- New class AA inherits from existing class A |
||
B = abstractClass() -- New abstract class B |
B = abstractClass() -- New abstract class B |
||
Line 1,673: | Line 1,673: | ||
AA:new() -- Okay: New class instance |
AA:new() -- Okay: New class instance |
||
B:new() -- Error: B is abstract |
B:new() -- Error: B is abstract |
||
BB:new() -- Okay: BB is not abstract</ |
BB:new() -- Okay: BB is not abstract</syntaxhighlight> |
||
=={{header|M2000 Interpreter}}== |
=={{header|M2000 Interpreter}}== |
||
M2000 not use interfaces, but can combine groups (used as objects), and because we can alter definitions, we can make an Abstract group by implement modules and functions with a call to Error "not implement yet" |
M2000 not use interfaces, but can combine groups (used as objects), and because we can alter definitions, we can make an Abstract group by implement modules and functions with a call to Error "not implement yet" |
||
< |
<syntaxhighlight lang=M2000 Interpreter>Class BaseState { |
||
Private: |
Private: |
||
x as double=1212, z1 as currency=1000, k$="ok" |
x as double=1212, z1 as currency=1000, k$="ok" |
||
Line 1,739: | Line 1,739: | ||
\\ we can use For Object {} and a dot before members to get access |
\\ we can use For Object {} and a dot before members to get access |
||
Print .z=1050.12, ExpType$(.z), Type$(.z) ' true, Currency, Group |
Print .z=1050.12, ExpType$(.z), Type$(.z) ' true, Currency, Group |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Mathematica}}/{{header|Wolfram Language}}== |
=={{header|Mathematica}}/{{header|Wolfram Language}}== |
||
Line 1,745: | Line 1,745: | ||
Mathematica is a symbolic language and as such does not support traditional object oriented design patterns. However, it is quite easy to define pseudo-interfaces that depend on an object implementing a set of functions: |
Mathematica is a symbolic language and as such does not support traditional object oriented design patterns. However, it is quite easy to define pseudo-interfaces that depend on an object implementing a set of functions: |
||
< |
<syntaxhighlight lang=Mathematica> |
||
(* Define an interface, Foo, which requires that the functions Foo, Bar, and Baz be defined *) |
(* Define an interface, Foo, which requires that the functions Foo, Bar, and Baz be defined *) |
||
InterfaceFooQ[obj_] := ValueQ[Foo[obj]] && ValueQ[Bar[obj]] && ValueQ[Baz[obj]]; |
InterfaceFooQ[obj_] := ValueQ[Foo[obj]] && ValueQ[Bar[obj]] && ValueQ[Baz[obj]]; |
||
Line 1,772: | Line 1,772: | ||
(* And finally a non-specific string *) |
(* And finally a non-specific string *) |
||
PrintFoo["foobarbaz"] |
PrintFoo["foobarbaz"] |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 1,792: | Line 1,792: | ||
=={{header|MATLAB}}== |
=={{header|MATLAB}}== |
||
; Abstract Class |
; Abstract Class |
||
< |
<syntaxhighlight lang=MATLAB>classdef (Abstract) AbsClass |
||
... |
... |
||
end</ |
end</syntaxhighlight> |
||
For classes that declare the Abstract class attribute: |
For classes that declare the Abstract class attribute: |
||
* Concrete subclasses must redefine any properties or methods that are declared as abstract. |
* Concrete subclasses must redefine any properties or methods that are declared as abstract. |
||
Line 1,800: | Line 1,800: | ||
When you define any abstract methods or properties, MATLAB® automatically sets the class Abstract attribute to true. |
When you define any abstract methods or properties, MATLAB® automatically sets the class Abstract attribute to true. |
||
; Abstract Methods |
; Abstract Methods |
||
< |
<syntaxhighlight lang=MATLAB>methods (Abstract) |
||
abstMethod(obj) |
abstMethod(obj) |
||
end</ |
end</syntaxhighlight> |
||
For methods that declare the Abstract method attribute: |
For methods that declare the Abstract method attribute: |
||
* Do not use a function...end block to define an abstract method, use only the method signature. |
* Do not use a function...end block to define an abstract method, use only the method signature. |
||
Line 1,808: | Line 1,808: | ||
* Concrete subclasses are not required to support the same number of input and output arguments and do not need to use the same argument names. However, subclasses generally use the same signature when implementing their version of the method. |
* Concrete subclasses are not required to support the same number of input and output arguments and do not need to use the same argument names. However, subclasses generally use the same signature when implementing their version of the method. |
||
; Abstract Properties |
; Abstract Properties |
||
< |
<syntaxhighlight lang=MATLAB>properties (Abstract) |
||
AbsProp |
AbsProp |
||
end</ |
end</syntaxhighlight> |
||
For properties that declare the Abstract property attribute: |
For properties that declare the Abstract property attribute: |
||
* Concrete subclasses must redefine abstract properties without the Abstract attribute. |
* Concrete subclasses must redefine abstract properties without the Abstract attribute. |
||
Line 1,832: | Line 1,832: | ||
these features by default for all tpyes. |
these features by default for all tpyes. |
||
< |
<syntaxhighlight lang=Mercury>:- module eq. |
||
:- interface. |
:- interface. |
||
Line 1,857: | Line 1,857: | ||
A == B :- (A^x = B^x, A^str = B^str), |
A == B :- (A^x = B^x, A^str = B^str), |
||
A \= B :- not A == B |
A \= B :- not A == B |
||
].</ |
].</syntaxhighlight> |
||
=={{header|Nemerle}}== |
=={{header|Nemerle}}== |
||
< |
<syntaxhighlight lang=Nemerle>using System.Console; |
||
namespace RosettaCode |
namespace RosettaCode |
||
Line 1,897: | Line 1,897: | ||
} |
} |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
=={{header|NetRexx}}== |
=={{header|NetRexx}}== |
||
< |
<syntaxhighlight lang=NetRexx>/* NetRexx */ |
||
options replace format comments java crossref symbols binary |
options replace format comments java crossref symbols binary |
||
Line 1,972: | Line 1,972: | ||
method callOverridden2() public returns String |
method callOverridden2() public returns String |
||
return super.canOverride2 |
return super.canOverride2 |
||
</syntaxhighlight> |
|||
</lang> |
|||
;Output |
;Output |
||
<pre> |
<pre> |
||
Line 1,987: | Line 1,987: | ||
=={{header|newLISP}}== |
=={{header|newLISP}}== |
||
< |
<syntaxhighlight lang=newLISP>; file: abstract.lsp |
||
; url: http://rosettacode.org/wiki/Abstract_type |
; url: http://rosettacode.org/wiki/Abstract_type |
||
; author: oofoe 2012-01-28 |
; author: oofoe 2012-01-28 |
||
Line 2,032: | Line 2,032: | ||
(:draw (Rectangle "R" 32 4)) |
(:draw (Rectangle "R" 32 4)) |
||
(exit)</ |
(exit)</syntaxhighlight> |
||
Sample output: |
Sample output: |
||
Line 2,052: | Line 2,052: | ||
=={{header|Nim}}== |
=={{header|Nim}}== |
||
In Nim type classes can be seen as an abstract type. Type classes specify interfaces, which can be instantiated by concrete types. |
In Nim type classes can be seen as an abstract type. Type classes specify interfaces, which can be instantiated by concrete types. |
||
< |
<syntaxhighlight lang=nim>type |
||
Comparable = concept x, y |
Comparable = concept x, y |
||
(x < y) is bool |
(x < y) is bool |
||
Line 2,063: | Line 2,063: | ||
for value in s: |
for value in s: |
||
value is T</ |
value is T</syntaxhighlight> |
||
=={{header|Nit}}== |
=={{header|Nit}}== |
||
Line 2,069: | Line 2,069: | ||
Source: [https://github.com/nitlang/nit/blob/master/examples/rosettacode/abstract_type.nit the official Nit’s repository] |
Source: [https://github.com/nitlang/nit/blob/master/examples/rosettacode/abstract_type.nit the official Nit’s repository] |
||
< |
<syntaxhighlight lang=nit># Task: abstract type |
||
# |
# |
||
# Methods without implementation are annotated `abstract`. |
# Methods without implementation are annotated `abstract`. |
||
Line 2,086: | Line 2,086: | ||
fun method2: Int do return 1 |
fun method2: Int do return 1 |
||
var attr: Int |
var attr: Int |
||
end</ |
end</syntaxhighlight> |
||
=={{header|Oberon-2}}== |
=={{header|Oberon-2}}== |
||
{{Works with|oo2c Version 2}} |
{{Works with|oo2c Version 2}} |
||
< |
<syntaxhighlight lang=oberon2> |
||
TYPE |
TYPE |
||
Animal = POINTER TO AnimalDesc; |
Animal = POINTER TO AnimalDesc; |
||
Line 2,098: | Line 2,098: | ||
Cat = POINTER TO CatDesc; |
Cat = POINTER TO CatDesc; |
||
CatDesc = RECORD (AnimalDesc) END; |
CatDesc = RECORD (AnimalDesc) END; |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Objeck}}== |
=={{header|Objeck}}== |
||
< |
<syntaxhighlight lang=objeck> |
||
class ClassA { |
class ClassA { |
||
method : virtual : public : MethodA() ~ Int; |
method : virtual : public : MethodA() ~ Int; |
||
Line 2,109: | Line 2,109: | ||
} |
} |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|OCaml}}== |
=={{header|OCaml}}== |
||
Line 2,117: | Line 2,117: | ||
The equivalent of what is called abstract type in the other OO examples of this page is just called '''virtual''' in Objective Caml to define '''virtual methods''' and '''virtual classes''': |
The equivalent of what is called abstract type in the other OO examples of this page is just called '''virtual''' in Objective Caml to define '''virtual methods''' and '''virtual classes''': |
||
< |
<syntaxhighlight lang=ocaml>class virtual foo = |
||
object |
object |
||
method virtual bar : int |
method virtual bar : int |
||
end</ |
end</syntaxhighlight> |
||
===Abstract Type=== |
===Abstract Type=== |
||
In OCaml what we call an abstract type is not OO related, it is only a type defined without definition, for example: |
In OCaml what we call an abstract type is not OO related, it is only a type defined without definition, for example: |
||
<lang |
<syntaxhighlight lang=ocaml>type t</syntaxhighlight> |
||
it is used for example to hide an implementation from the interface of a module or for type algebra. |
it is used for example to hide an implementation from the interface of a module or for type algebra. |
||
Example of abstracting a type in an interface: |
Example of abstracting a type in an interface: |
||
< |
<syntaxhighlight lang=ocaml>module Foo : sig |
||
type t |
type t |
||
end = struct |
end = struct |
||
type t = int * int |
type t = int * int |
||
end</ |
end</syntaxhighlight> |
||
Pure abstract types in the implementation: |
Pure abstract types in the implementation: |
||
< |
<syntaxhighlight lang=ocaml>type u |
||
type v |
type v |
||
type 'a t |
type 'a t |
||
type ut = u t |
type ut = u t |
||
type vt = v t</ |
type vt = v t</syntaxhighlight> |
||
=={{header|Oforth}}== |
=={{header|Oforth}}== |
||
Line 2,150: | Line 2,150: | ||
Unlike interfaces, properties can include method implementations and attributes (see lang/Comparable.of for instance). |
Unlike interfaces, properties can include method implementations and attributes (see lang/Comparable.of for instance). |
||
< |
<syntaxhighlight lang=Oforth>Property new: Spherical(r) |
||
Spherical method: radius @r ; |
Spherical method: radius @r ; |
||
Spherical method: setRadius := r ; |
Spherical method: setRadius := r ; |
||
Line 2,162: | Line 2,162: | ||
Object Class new: Planete(name) |
Object Class new: Planete(name) |
||
Planete is: Spherical |
Planete is: Spherical |
||
Planete method: initialize(n, r) n := name self setRadius(r) ;</ |
Planete method: initialize(n, r) n := name self setRadius(r) ;</syntaxhighlight> |
||
Usage : |
Usage : |
||
< |
<syntaxhighlight lang=Oforth>: testProperty |
||
| b p | |
| b p | |
||
Ballon new($red, 0.1) ->b |
Ballon new($red, 0.1) ->b |
||
Line 2,176: | Line 2,176: | ||
System.Out "Earth perimeter is : " << p perimeter << cr |
System.Out "Earth perimeter is : " << p perimeter << cr |
||
System.Out "Earth surface is : " << p surface << cr |
System.Out "Earth surface is : " << p surface << cr |
||
;</ |
;</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 2,191: | Line 2,191: | ||
===Interface=== |
===Interface=== |
||
< |
<syntaxhighlight lang=ooRexx> -- Example showing a class that defines an interface in ooRexx |
||
-- shape is the interface class that defines the methods a shape instance |
-- shape is the interface class that defines the methods a shape instance |
||
-- is expected to implement as abstract methods. Instances of the shape |
-- is expected to implement as abstract methods. Instances of the shape |
||
Line 2,250: | Line 2,250: | ||
::method name |
::method name |
||
return "Circle"</ |
return "Circle"</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>a RECTANGLE |
<pre>a RECTANGLE |
||
Line 2,266: | Line 2,266: | ||
===Abstract Type=== |
===Abstract Type=== |
||
< |
<syntaxhighlight lang=ooRexx> -- Example showing an abstract type in ooRexx |
||
-- shape is the abstract class that defines the abstract method area |
-- shape is the abstract class that defines the abstract method area |
||
-- which is then implemented by its two subclasses, rectangle and circle |
-- which is then implemented by its two subclasses, rectangle and circle |
||
Line 2,316: | Line 2,316: | ||
expose radius |
expose radius |
||
numeric digits 20 |
numeric digits 20 |
||
return radius*radius*3.14159265358979323846</ |
return radius*radius*3.14159265358979323846</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>a RECTANGLE |
<pre>a RECTANGLE |
||
Line 2,366: | Line 2,366: | ||
There are no abstract types as part of the language, but we can do as in Python and raise exceptions: |
There are no abstract types as part of the language, but we can do as in Python and raise exceptions: |
||
< |
<syntaxhighlight lang=oz>declare |
||
class BaseQueue |
class BaseQueue |
||
attr |
attr |
||
Line 2,388: | Line 2,388: | ||
end |
end |
||
Queue = {New BaseQueue init} %% throws</ |
Queue = {New BaseQueue init} %% throws</syntaxhighlight> |
||
=={{header|PARI/GP}}== |
=={{header|PARI/GP}}== |
||
Line 2,400: | Line 2,400: | ||
=={{header|Perl}}== |
=={{header|Perl}}== |
||
< |
<syntaxhighlight lang=perl>package AbstractFoo; |
||
use strict; |
use strict; |
||
Line 2,413: | Line 2,413: | ||
1;</ |
1;</syntaxhighlight> |
||
Since Perl 5.12, the Yadda Yadda operator (...) dies with an Unimplemented error, |
Since Perl 5.12, the Yadda Yadda operator (...) dies with an Unimplemented error, |
||
< |
<syntaxhighlight lang=perl> |
||
package AbstractFoo; |
package AbstractFoo; |
||
Line 2,430: | Line 2,430: | ||
1; |
1; |
||
</syntaxhighlight> |
|||
</lang> |
|||
Raku inspired roles are provided by the [http://search.cpan.org/perldoc?Moose Moose] library |
Raku inspired roles are provided by the [http://search.cpan.org/perldoc?Moose Moose] library |
||
< |
<syntaxhighlight lang=perl>package AbstractFoo; |
||
use Moose::Role; |
use Moose::Role; |
||
Line 2,444: | Line 2,444: | ||
} |
} |
||
1;</ |
1;</syntaxhighlight> |
||
Roles are also provided in a more lightweight form with [http://search.cpan.org/perldoc?Role::Tiny Role::Tiny] library |
Roles are also provided in a more lightweight form with [http://search.cpan.org/perldoc?Role::Tiny Role::Tiny] library |
||
< |
<syntaxhighlight lang=perl>package AbstractFoo; |
||
use Role::Tiny; |
use Role::Tiny; |
||
Line 2,458: | Line 2,458: | ||
} |
} |
||
1;</ |
1;</syntaxhighlight> |
||
=={{header|Phix}}== |
=={{header|Phix}}== |
||
Line 2,465: | Line 2,465: | ||
You can also have explicitly abstract classes (and/or abstract methods). Needs 0.8.1+ |
You can also have explicitly abstract classes (and/or abstract methods). Needs 0.8.1+ |
||
<!--< |
<!--<syntaxhighlight lang=Phix>--> |
||
<span style="color: #008080;">abstract</span> <span style="color: #008080;">class</span> <span style="color: #000000;">job</span> |
<span style="color: #008080;">abstract</span> <span style="color: #008080;">class</span> <span style="color: #000000;">job</span> |
||
<span style="color: #004080;">integer</span> <span style="color: #000000;">id</span> |
<span style="color: #004080;">integer</span> <span style="color: #000000;">id</span> |
||
Line 2,479: | Line 2,479: | ||
<span style="color: #000000;">errand</span> <span style="color: #000000;">e</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">new</span><span style="color: #0000FF;">({</span><span style="color: #000000;">2</span><span style="color: #0000FF;">})</span> |
<span style="color: #000000;">errand</span> <span style="color: #000000;">e</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">new</span><span style="color: #0000FF;">({</span><span style="color: #000000;">2</span><span style="color: #0000FF;">})</span> |
||
<span style="color: #000000;">e</span><span style="color: #0000FF;">.</span><span style="color: #000000;">show</span><span style="color: #0000FF;">()</span> |
<span style="color: #000000;">e</span><span style="color: #0000FF;">.</span><span style="color: #000000;">show</span><span style="color: #0000FF;">()</span> |
||
<!--</ |
<!--</syntaxhighlight>--> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 2,489: | Line 2,489: | ||
Methods that don't have an implementation are called abstract methods in PHP. A class that contains an abstract method or inherits one but did not override it must be an abstract class; but an abstract class does not need to contain any abstract methods. An abstract class cannot be instantiated. If a method is abstract, it must be public or protected |
Methods that don't have an implementation are called abstract methods in PHP. A class that contains an abstract method or inherits one but did not override it must be an abstract class; but an abstract class does not need to contain any abstract methods. An abstract class cannot be instantiated. If a method is abstract, it must be public or protected |
||
< |
<syntaxhighlight lang=php>abstract class Abs { |
||
abstract public function method1($value); |
abstract public function method1($value); |
||
abstract protected function method2($name); |
abstract protected function method2($name); |
||
Line 2,495: | Line 2,495: | ||
return a + b; |
return a + b; |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
Interfaces in PHP may not implement any methods and all methods are public and implicitly abstract. |
Interfaces in PHP may not implement any methods and all methods are public and implicitly abstract. |
||
< |
<syntaxhighlight lang=php>interface Inter { |
||
public function method1($value); |
public function method1($value); |
||
public function method2($name); |
public function method2($name); |
||
public function add($a, $b); |
public function add($a, $b); |
||
}</ |
}</syntaxhighlight> |
||
=={{header|PicoLisp}}== |
=={{header|PicoLisp}}== |
||
< |
<syntaxhighlight lang=PicoLisp># In PicoLisp there is no formal difference between abstract and concrete classes. |
||
# There is just a naming convention where abstract classes start with a |
# There is just a naming convention where abstract classes start with a |
||
# lower-case character after the '+' (the naming convention for classes). |
# lower-case character after the '+' (the naming convention for classes). |
||
Line 2,514: | Line 2,514: | ||
(dm someMethod> () |
(dm someMethod> () |
||
(foo) |
(foo) |
||
(bar) )</ |
(bar) )</syntaxhighlight> |
||
=={{header|PowerShell}}== |
=={{header|PowerShell}}== |
||
< |
<syntaxhighlight lang=PowerShell> |
||
#Requires -Version 5.0 |
#Requires -Version 5.0 |
||
Line 2,610: | Line 2,610: | ||
} |
} |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
Create a new player: |
Create a new player: |
||
< |
<syntaxhighlight lang=PowerShell> |
||
$player1 = [Player]::new("sam bradford", "philadelphia eagles", "qb", 7) |
$player1 = [Player]::new("sam bradford", "philadelphia eagles", "qb", 7) |
||
$player1 |
$player1 |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{Out}} |
{{Out}} |
||
<pre> |
<pre> |
||
Line 2,623: | Line 2,623: | ||
</pre> |
</pre> |
||
Trade the player: |
Trade the player: |
||
< |
<syntaxhighlight lang=PowerShell> |
||
$player1.Trade("minnesota vikings", 8) |
$player1.Trade("minnesota vikings", 8) |
||
$player1 |
$player1 |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{Out}} |
{{Out}} |
||
<pre> |
<pre> |
||
Line 2,634: | Line 2,634: | ||
</pre> |
</pre> |
||
Create a new player: |
Create a new player: |
||
< |
<syntaxhighlight lang=PowerShell> |
||
$player2 = [Player]::new("demarco murray", "philadelphia eagles", "rb", 29) |
$player2 = [Player]::new("demarco murray", "philadelphia eagles", "rb", 29) |
||
$player2 |
$player2 |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{Out}} |
{{Out}} |
||
<pre> |
<pre> |
||
Line 2,645: | Line 2,645: | ||
</pre> |
</pre> |
||
Trade the player: |
Trade the player: |
||
< |
<syntaxhighlight lang=PowerShell> |
||
$player2.Trade("tennessee titans") |
$player2.Trade("tennessee titans") |
||
$player2 |
$player2 |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{Out}} |
{{Out}} |
||
<pre> |
<pre> |
||
Line 2,658: | Line 2,658: | ||
=={{header|Python}}== |
=={{header|Python}}== |
||
< |
<syntaxhighlight lang=python>class BaseQueue(object): |
||
"""Abstract/Virtual Class |
"""Abstract/Virtual Class |
||
""" |
""" |
||
Line 2,670: | Line 2,670: | ||
def Print_Contents(self): |
def Print_Contents(self): |
||
for i in self.contents: |
for i in self.contents: |
||
print i,</ |
print i,</syntaxhighlight> |
||
Python allows multiple inheritance and it's more common to implement "mix-in" classes rather than abstract interfaces. (Mix-in classes can implement functionality as well define interfaces). |
Python allows multiple inheritance and it's more common to implement "mix-in" classes rather than abstract interfaces. (Mix-in classes can implement functionality as well define interfaces). |
||
Line 2,683: | Line 2,683: | ||
Starting from Python 2.6, abstract classes can be created using the standard abc module: |
Starting from Python 2.6, abstract classes can be created using the standard abc module: |
||
< |
<syntaxhighlight lang=python>from abc import ABCMeta, abstractmethod |
||
class BaseQueue(): |
class BaseQueue(): |
||
Line 2,703: | Line 2,703: | ||
def Print_Contents(self): |
def Print_Contents(self): |
||
for i in self.contents: |
for i in self.contents: |
||
print i,</ |
print i,</syntaxhighlight> |
||
=={{header|Racket}}== |
=={{header|Racket}}== |
||
< |
<syntaxhighlight lang=racket> |
||
#lang racket |
#lang racket |
||
Line 2,721: | Line 2,721: | ||
(define tom (new cat%)) |
(define tom (new cat%)) |
||
(send tom say) |
(send tom say) |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Raku}}== |
=={{header|Raku}}== |
||
Line 2,729: | Line 2,729: | ||
Raku supports roles, which are a bit like interfaces, but unlike interfaces in Java they can also contain some implementation. |
Raku supports roles, which are a bit like interfaces, but unlike interfaces in Java they can also contain some implementation. |
||
< |
<syntaxhighlight lang=perl6> |
||
use v6; |
use v6; |
||
Line 2,753: | Line 2,753: | ||
# made concrete in class |
# made concrete in class |
||
# 42 |
# 42 |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|REBOL}}== |
=={{header|REBOL}}== |
||
< |
<syntaxhighlight lang=REBOL>REBOL [ |
||
Title: "Abstract Type" |
Title: "Abstract Type" |
||
URL: http://rosettacode.org/wiki/Abstract_type |
URL: http://rosettacode.org/wiki/Abstract_type |
||
Line 2,799: | Line 2,799: | ||
print [crlf "A rectangle:"] |
print [crlf "A rectangle:"] |
||
r: make rectangle [size: 32x5] r/draw</ |
r: make rectangle [size: 32x5] r/draw</syntaxhighlight> |
||
=={{header|Red}}== |
=={{header|Red}}== |
||
< |
<syntaxhighlight lang=Red>Red [ |
||
Title: "Abstract Type" |
Title: "Abstract Type" |
||
Original-Author: oofoe |
Original-Author: oofoe |
||
Line 2,846: | Line 2,846: | ||
print [newline "A rectangle:"] |
print [newline "A rectangle:"] |
||
r: make rectangle [size: 32x5] r/draw</ |
r: make rectangle [size: 32x5] r/draw</syntaxhighlight> |
||
=={{header|ReScript}}== |
=={{header|ReScript}}== |
||
Here is an abstract type definition: |
Here is an abstract type definition: |
||
<lang |
<syntaxhighlight lang=ReScript>type t</syntaxhighlight> |
||
=={{header|REXX}}== |
=={{header|REXX}}== |
||
Line 2,861: | Line 2,861: | ||
The Python and Tcl provisos apply to Ruby too. Nevertheless, a {{libheader|RubyGems}} package called [http://github.com/Peeja/abstraction/tree/master abstraction] exists where: |
The Python and Tcl provisos apply to Ruby too. Nevertheless, a {{libheader|RubyGems}} package called [http://github.com/Peeja/abstraction/tree/master abstraction] exists where: |
||
< |
<syntaxhighlight lang=ruby>require 'abstraction' |
||
class AbstractQueue |
class AbstractQueue |
||
Line 2,877: | Line 2,877: | ||
puts "enqueue #{object.inspect}" |
puts "enqueue #{object.inspect}" |
||
end |
end |
||
end</ |
end</syntaxhighlight> |
||
So: |
So: |
||
<pre>irb(main):032:0> a = AbstractQueue.new |
<pre>irb(main):032:0> a = AbstractQueue.new |
||
Line 2,899: | Line 2,899: | ||
Rust doesn't have traditional object oriented concepts such as classes, instead it uses a concept called traits. Traits are similar to abstract classes in the sense that they define an interface a struct must conform to. A trait can be defined as such: |
Rust doesn't have traditional object oriented concepts such as classes, instead it uses a concept called traits. Traits are similar to abstract classes in the sense that they define an interface a struct must conform to. A trait can be defined as such: |
||
< |
<syntaxhighlight lang=rust>trait Shape { |
||
fn area(self) -> i32; |
fn area(self) -> i32; |
||
}</ |
}</syntaxhighlight> |
||
The trait can then be implemented on a struct. |
The trait can then be implemented on a struct. |
||
< |
<syntaxhighlight lang=rust>struct Square { |
||
side_length: i32 |
side_length: i32 |
||
} |
} |
||
Line 2,913: | Line 2,913: | ||
self.side_length * self.side_length |
self.side_length * self.side_length |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
Note, traits can also have a default implementation: |
Note, traits can also have a default implementation: |
||
< |
<syntaxhighlight lang=rust>trait Shape { |
||
fn area(self) -> i32; |
fn area(self) -> i32; |
||
Line 2,923: | Line 2,923: | ||
true |
true |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Scala}}== |
=={{header|Scala}}== |
||
Line 2,939: | Line 2,939: | ||
different meaning that described in this page. Here are some examples: |
different meaning that described in this page. Here are some examples: |
||
< |
<syntaxhighlight lang=scala>abstract class X { |
||
type A |
type A |
||
var B: A |
var B: A |
||
Line 2,948: | Line 2,948: | ||
trait Y { |
trait Y { |
||
val x: X |
val x: X |
||
}</ |
}</syntaxhighlight> |
||
When integrating with Java, traits without implementation appear as interfaces. |
When integrating with Java, traits without implementation appear as interfaces. |
||
Line 2,961: | Line 2,961: | ||
A function is automaticall attached to the interface, when it has an parameter of the interface type. |
A function is automaticall attached to the interface, when it has an parameter of the interface type. |
||
< |
<syntaxhighlight lang=seed7> |
||
const type: myInterf is sub object interface; |
const type: myInterf is sub object interface; |
||
Line 2,967: | Line 2,967: | ||
const func integer: method2 (in myInterf: interf, in string: name) is DYNAMIC; |
const func integer: method2 (in myInterf: interf, in string: name) is DYNAMIC; |
||
const func integer: add (in myInterf: interf, in integer: a, in integer: b) is DYNAMIC; |
const func integer: add (in myInterf: interf, in integer: a, in integer: b) is DYNAMIC; |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Sidef}}== |
=={{header|Sidef}}== |
||
{{trans|Raku}} |
{{trans|Raku}} |
||
< |
<syntaxhighlight lang=ruby>class A { |
||
# must be filled in by the class which will inherit it |
# must be filled in by the class which will inherit it |
||
method abstract() { die 'Unimplemented' }; |
method abstract() { die 'Unimplemented' }; |
||
Line 2,987: | Line 2,987: | ||
var obj = SomeClass.new; |
var obj = SomeClass.new; |
||
obj.abstract(); # made concrete in class |
obj.abstract(); # made concrete in class |
||
obj.concrete(); # 42</ |
obj.concrete(); # 42</syntaxhighlight> |
||
=={{header|Simula}}== |
=={{header|Simula}}== |
||
Abtract Datatypes are declared using the VIRTUAL keyword. |
Abtract Datatypes are declared using the VIRTUAL keyword. |
||
For example, we need the following two procedures hash and equalto for a hash map implementation. |
For example, we need the following two procedures hash and equalto for a hash map implementation. |
||
< |
<syntaxhighlight lang=simula> |
||
! ABSTRACT HASH KEY TYPE ; |
! ABSTRACT HASH KEY TYPE ; |
||
LISTVAL CLASS HASHKEY; |
LISTVAL CLASS HASHKEY; |
||
Line 3,002: | Line 3,002: | ||
BEGIN |
BEGIN |
||
END HASHKEY; |
END HASHKEY; |
||
</syntaxhighlight> |
|||
</lang> |
|||
A concrete implementation can be derived as follows: |
A concrete implementation can be derived as follows: |
||
< |
<syntaxhighlight lang=simula> |
||
! COMMON HASH KEY TYPE IS TEXT ; |
! COMMON HASH KEY TYPE IS TEXT ; |
||
HASHKEY CLASS TEXTHASHKEY(T); VALUE T; TEXT T; |
HASHKEY CLASS TEXTHASHKEY(T); VALUE T; TEXT T; |
||
Line 3,025: | Line 3,025: | ||
EQUALTO := T = K QUA TEXTHASHKEY.T; |
EQUALTO := T = K QUA TEXTHASHKEY.T; |
||
END TEXTHASHKEY; |
END TEXTHASHKEY; |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Smalltalk}}== |
=={{header|Smalltalk}}== |
||
A class is declared abtract by responding to the query <tt>isAbstract</tt> with true, and defining the required protocol for subclasses to raise an error notification. Optionally, instance creation can be blocked (but seldom done, as you will hit a subclassResponsibility anyway soon). Typically, the IDE provides menu functions to generate these definitions automatically (eg. "Insert Abstract Class" in the refactoring submenu of the class browser): |
A class is declared abtract by responding to the query <tt>isAbstract</tt> with true, and defining the required protocol for subclasses to raise an error notification. Optionally, instance creation can be blocked (but seldom done, as you will hit a subclassResponsibility anyway soon). Typically, the IDE provides menu functions to generate these definitions automatically (eg. "Insert Abstract Class" in the refactoring submenu of the class browser): |
||
< |
<syntaxhighlight lang=smalltalk>someClass class >> isAbstract |
||
^ true |
^ true |
||
Line 3,039: | Line 3,039: | ||
someClass >> method1 |
someClass >> method1 |
||
^ self subclassResponsibility |
^ self subclassResponsibility |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Standard ML}}== |
=={{header|Standard ML}}== |
||
Line 3,051: | Line 3,051: | ||
Here is an example signature for a queue data structure: |
Here is an example signature for a queue data structure: |
||
< |
<syntaxhighlight lang=sml>signature QUEUE = sig |
||
type 'a queue |
type 'a queue |
||
val empty : 'a queue |
val empty : 'a queue |
||
val enqueue : 'a -> 'a queue -> 'a queue |
val enqueue : 'a -> 'a queue -> 'a queue |
||
val dequeue : 'a queue -> ('a * 'a queue) option |
val dequeue : 'a queue -> ('a * 'a queue) option |
||
end</ |
end</syntaxhighlight> |
||
Because we did not specify an implementation for <tt>'a queue</tt>, the type |
Because we did not specify an implementation for <tt>'a queue</tt>, the type |
||
will be abstract if we use opaque ascription. Instead we could create a version of the signature which specifies the type, |
will be abstract if we use opaque ascription. Instead we could create a version of the signature which specifies the type, |
||
in which case it will never be abstract: |
in which case it will never be abstract: |
||
< |
<syntaxhighlight lang=sml>signature LIST_QUEUE = sig |
||
type 'a queue = 'a list |
type 'a queue = 'a list |
||
val empty : 'a queue |
val empty : 'a queue |
||
val enqueue : 'a -> 'a queue -> 'a queue |
val enqueue : 'a -> 'a queue -> 'a queue |
||
val dequeue : 'a queue -> ('a * 'a queue) option |
val dequeue : 'a queue -> ('a * 'a queue) option |
||
end</ |
end</syntaxhighlight> |
||
Then say we have a structure ListQueue which implements queues as lists. If we write <tt>ListQueue :> QUEUE</tt> |
Then say we have a structure ListQueue which implements queues as lists. If we write <tt>ListQueue :> QUEUE</tt> |
||
Line 3,075: | Line 3,075: | ||
While in general Tcl does not use abstract classes at all (and has no need at all for interfaces due to supporting multiple inheritance and mixins), an equivalent effect can be had by concealing the construction methods on the class instance; instances are only created by subclassing the class first (or by mixing it in). In this example, the methods are also error-returning stubs... |
While in general Tcl does not use abstract classes at all (and has no need at all for interfaces due to supporting multiple inheritance and mixins), an equivalent effect can be had by concealing the construction methods on the class instance; instances are only created by subclassing the class first (or by mixing it in). In this example, the methods are also error-returning stubs... |
||
< |
<syntaxhighlight lang=Tcl>oo::class create AbstractQueue { |
||
method enqueue item { |
method enqueue item { |
||
error "not implemented" |
error "not implemented" |
||
Line 3,083: | Line 3,083: | ||
} |
} |
||
self unexport create new |
self unexport create new |
||
}</ |
}</syntaxhighlight> |
||
{{omit from|TorqueScript}} |
{{omit from|TorqueScript}} |
||
=={{header|Vala}}== |
=={{header|Vala}}== |
||
< |
<syntaxhighlight lang=vala>public abstract class Animal : Object { |
||
public void eat() { |
public void eat() { |
||
print("Chomp! Chomp!\n"); |
print("Chomp! Chomp!\n"); |
||
Line 3,116: | Line 3,116: | ||
scott.talk(); |
scott.talk(); |
||
scott.eat(); |
scott.eat(); |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 3,143: | Line 3,143: | ||
* By convention all abstract classes have one or more Protected constructors. |
* By convention all abstract classes have one or more Protected constructors. |
||
< |
<syntaxhighlight lang=vbnet>MustInherit Class Base |
||
Protected Sub New() |
Protected Sub New() |
||
Line 3,159: | Line 3,159: | ||
Public MustOverride Sub Method_Must_Be_Replaced() |
Public MustOverride Sub Method_Must_Be_Replaced() |
||
End Class</ |
End Class</syntaxhighlight> |
||
=== Interfaces === |
=== Interfaces === |
||
Line 3,165: | Line 3,165: | ||
Interfaces may contain Functions, Subroutines, Properties, and Events. |
Interfaces may contain Functions, Subroutines, Properties, and Events. |
||
< |
<syntaxhighlight lang=vbnet>Interface IBase |
||
Sub Method_Must_Be_Implemented() |
Sub Method_Must_Be_Implemented() |
||
End Interface</ |
End Interface</syntaxhighlight> |
||
=={{header|Vlang}}== |
=={{header|Vlang}}== |
||
Line 3,177: | Line 3,177: | ||
In the following example, the Dog and Cat types both satisfy the Beast interface because they each have the specified methods. The ''bprint'' function can print details for any Beast. |
In the following example, the Dog and Cat types both satisfy the Beast interface because they each have the specified methods. The ''bprint'' function can print details for any Beast. |
||
< |
<syntaxhighlight lang=vlang>interface Beast { |
||
kind() string |
kind() string |
||
name() string |
name() string |
||
Line 3,214: | Line 3,214: | ||
bprint(d) |
bprint(d) |
||
bprint(c) |
bprint(c) |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 3,226: | Line 3,226: | ||
The Go example, when rewritten in Wren, looks like this. |
The Go example, when rewritten in Wren, looks like this. |
||
< |
<syntaxhighlight lang=ecmascript>import "/fmt" for Fmt |
||
class Beast{ |
class Beast{ |
||
Line 3,258: | Line 3,258: | ||
var c = Cat.new("siamese", "Sammy") |
var c = Cat.new("siamese", "Sammy") |
||
d.print() |
d.print() |
||
c.print()</ |
c.print()</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 3,268: | Line 3,268: | ||
=={{header|zkl}}== |
=={{header|zkl}}== |
||
In zkl, nothing is ever abstract, objects are always runnable. However, it is easy to define "meta" objects, objects that define an interface/api for a "class" of objects. For example, it is desirable for "stream" objects (such as File, List, etc) to share semantics so that code doesn't need to know what the source object really is. |
In zkl, nothing is ever abstract, objects are always runnable. However, it is easy to define "meta" objects, objects that define an interface/api for a "class" of objects. For example, it is desirable for "stream" objects (such as File, List, etc) to share semantics so that code doesn't need to know what the source object really is. |
||
< |
<syntaxhighlight lang=zkl>class Stream{ // Mostly virtural base class |
||
var [proxy protected] |
var [proxy protected] |
||
isBroken = fcn { _broken.isSet() }, |
isBroken = fcn { _broken.isSet() }, |
||
Line 3,288: | Line 3,288: | ||
fcn writeln(x) { return(self.topdog); } |
fcn writeln(x) { return(self.topdog); } |
||
fcn walker { return((0).walker(*,wap((self.topdog.read.fpM(""))))); } |
fcn walker { return((0).walker(*,wap((self.topdog.read.fpM(""))))); } |
||
}</ |
}</syntaxhighlight> |
||
*The topdog property is the "youngest" child in the inheritance tree (root if you view the tree upside down), it allows a "parent" (or super) to access or pass control to, the actual instance. |
*The topdog property is the "youngest" child in the inheritance tree (root if you view the tree upside down), it allows a "parent" (or super) to access or pass control to, the actual instance. |
||
*If you wish to "force" method implementation, you can have a meta method throw an NotImplementedError. This is run time thing, not compile time. |
*If you wish to "force" method implementation, you can have a meta method throw an NotImplementedError. This is run time thing, not compile time. |
||
And now for a "real" object: |
And now for a "real" object: |
||
< |
<syntaxhighlight lang=zkl>class DevNull(Stream){ |
||
var [const] fileName = "DevNull"; // compatibility with File |
var [const] fileName = "DevNull"; // compatibility with File |
||
fcn init { Stream.init() } |
fcn init { Stream.init() } |
||
fcn write(x) { return(0); } |
fcn write(x) { return(0); } |
||
}</ |
}</syntaxhighlight> |
||