Abstract type: Difference between revisions

From Rosetta Code
Content added Content deleted
No edit summary
Line 1,060: Line 1,060:
==Abstract Type==
==Abstract Type==


<lang ooRexx> -- Example showing an abstract type in ooRexx
<lang Rexx> -- 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

Revision as of 21:28, 8 June 2012

Task
Abstract type
You are encouraged to solve this task according to the task description, using any language you may know.

Abstract type is a type without instances or without definition.

For example in object-oriented programming using some languages, abstract types can be partial implementations of other types, which are to be derived there-from. An abstract type may provide implementation of some operations and/or components. Abstract types without any implementation are called interfaces. In the languages that do not support multiple inheritance (Ada, Java), classes can, nonetheless, inherit from multiple interfaces. The languages with multiple inheritance (like C++) usually make no distinction between partially implementable abstract types and interfaces. Because the abstract type's implementation is incomplete, OO languages normally prevent instantiation from them (instantiation must derived from one of their descendant classes).

The term abstract datatype also may denote a type, with an implementation provided by the programmer rather than directly by the language (a built-in or an inferred type). Here the word abstract means that the implementation is abstracted away, irrelevant for the user of the type. Such implementation can and should be hidden if the language supports separation of implementation and specification. This hides complexity while allowing the implementation to change without repercussions on the usage. The corresponding software design practice is said to follow the information hiding principle.

It is important not to confuse this abstractness (of implementation) with one of the abstract type. The latter is abstract in the sense that the set of its values is empty. In the sense of implementation abstracted away, all user-defined types are abstract.

In some languages, like for example in Objective Caml which is strongly statically typed, it is also possible to have abstract types that are not OO related and are not an abstractness too. These are pure abstract types without any definition even in the implementation and can be used for example for the type algebra, or for some consistence of the type inference. For example in this area, an abstract type can be used as a phantom type to augment another type as its parameter.

Task: show how an abstract type can be declared in the language. If the language makes a distinction between interfaces and partially implemented types illustrate both.


ABAP

Abstract Class

<lang ABAP>class abs definition abstract.

 public section.
   methods method1 abstract importing iv_value type f exporting ev_ret type i.
 protected section.
   methods method2 abstract importing iv_name type string exporting ev_ret type i.
   methods add importing iv_a type i iv_b type i exporting ev_ret type i.

endclass.

class abs implementation.

 method add.
   ev_ret = iv_a + iv_b.
 endmethod.

endclass.</lang>

Interfaces

Interfaces in ABAP are classes with the following restrictions: 1. All methods must be abstract instance methods (Static methods aren't allowed). 2. Variables must be static final. The values may be computed at run time. 3. No static initialiser blockers. No static initialiser helper methods. <lang ABAP>interface inter.

 methods: method1 importing iv_value type f 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.

endinterface.</lang>

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. <lang actionscript>package {

   public interface IInterface
   {
       function method1():void;
       function method2(arg1:Array, arg2:Boolean):uint;
   }

}</lang>

Ada

Interface

Interfaces in Ada may have no components or implemented operation except for ones implemented as null operations. Interfaces can be multiply inherited. <lang ada>type Queue is limited interface; procedure Enqueue (Lounge : in out Queue; Item : in out Element) is abstract; procedure Dequeue (Lounge : in out Queue; Item : in out Element) is abstract;</lang> Interfaces can be declared synchronized or task when intended implementations are to be provided by protected objects or tasks. For example: <lang ada>type Scheduler is task interface; procedure Plan (Manager : in out Scheduler; Activity : in out Job) is abstract;</lang>

Abstract type

Abstract types may provide components and implementation of their operations. Abstract types are singly inherited. <lang ada>with Ada.Finalization; ... type Node is abstract new Ada.Finalization.Limited_Controlled and Queue with record

  Previous : not null access Node'Class := Node'Unchecked_Access;
  Next     : not null access Node'Class := Node'Unchecked_Access;

end record; overriding procedure Finalize (X : in out Node); -- Removes the node from its list if any overriding procedure Dequeue (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</lang> Here Node is an abstract type that is inherited from Limited_Controlled and implements a node of a 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.

Agda

Using records for storing the interface methods and instance arguments (which are similar to Haskell type classes) for overloading:

<lang agda>module AbstractInterfaceExample where

open import Function open import Data.Bool open import Data.String

-- * One-parameter interface for the type `a' with only one method.

record VoiceInterface (a : Set) : Set where

 constructor voice-interface
 field say-method-of : a → String

open VoiceInterface

-- * An overloaded method.

say : {a : Set} → ⦃ _ : VoiceInterface a ⦄ → a → String say ⦃ instance ⦄ = say-method-of instance

-- * Some data types.

data Cat : Set where

 cat : Bool → Cat

crazy! = true plain-cat = false

-- | This cat is crazy? crazy? : Cat → Bool crazy? (cat x) = x

-- | A 'plain' dog. data Dog : Set where

 dog : Dog

-- * Implementation of the interface (and method).

instance-for-cat : VoiceInterface Cat instance-for-cat = voice-interface case where

 case : Cat → String
 case x with crazy? x
 ... | true = "meeeoooowwwww!!!"
 ... | false = "meow!"

instance-for-dog : VoiceInterface Dog instance-for-dog = voice-interface $ const "woof!"

-- * and then: -- -- say dog => "woof!" -- say (cat crazy!) => "meeeoooowwwww!!!" -- say (cat plain-cat) => "meow!" -- </lang>

There is dog and cat is objects of different types for which the interface method is implemented.

Aikido

An abstract class contains functions that have no body defined. You cannot instantiate a class that contains abstract functions.

<lang aikido>class Abs {

       public function method1...
       public function method2...

}</lang> 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. <lang aikido>interface Inter {

   function isFatal : integer
   function operate (para : integer = 0) 
   operator -> (stream, isout)

}</lang>

Argile

Works with: Argile version 1.0.0

<lang Argile>use std

(: abstract class :)

class Abs

  text		name
  AbsIface	iface

class AbsIface

  function(Abs)(int)->int	method

let Abs_Iface = Cdata AbsIface@ {.method = nil}

.: new Abs :. -> Abs {let a = new(Abs); a.iface = Abs_Iface; a}

=: <Abs self>.method <int i> := -> int

  (self.iface.method is nil) ? 0 , (call self.iface.method with self i)

(: implementation :)

class Sub <- Abs { int value }

let Sub_Iface = Cdata AbsIface@ {.method = (code of (nil the Sub).method 0)}

.: new Sub (<int value = -1>) :. -> Sub

  let s = new (Sub)
  s.iface = Sub_Iface
  s.value = value
  s

.: .method <int i> :. -> int {this.value + i}

(: example use :)

.:foobar<Abs a>:. {print a.method 12 ; del a} foobar (new Sub 34) (: prints 46 :) foobar (new Sub) (: prints 11 :) foobar (new Abs) (: prints 0 :)</lang>

AutoHotkey

Works with: AutoHotkey_L

<lang AutoHotkey>color(r, g, b){

  static color
  If !color 
     color := Object("base", Object("R", r, "G", g, "B", b 
                                   ,"GetRGB", "Color_GetRGB"))
  return  Object("base", Color) 

} Color_GetRGB(clr) {

   return "not implemented"

}

waterColor(r, g, b){

  static waterColor
  If !waterColor 
     waterColor := Object("base", color(r, g, b),"GetRGB", "WaterColor_GetRGB")
  return  Object("base", WaterColor) 

}

WaterColor_GetRGB(clr){ return clr.R << 16 | clr.G << 8 | clr.B }

test: blue := color(0, 0, 255) msgbox % blue.GetRGB() ; displays "not implemented" blue := waterColor(0, 0, 255) msgbox % blue.GetRGB() ; displays 255 return </lang>

C

Doing abstract types in C is not particularly trivial as C doesn't really support classes. The following series will show an abstract type, followed by a realizable class that provides the abstract interface, and finally followed by an example of usage.

The header file for the abstract class, interfaceAbs.h <lang c>#ifndef INTERFACE_ABS

  1. define INTERFACE_ABS

typedef struct sAbstractCls *AbsCls;

typedef struct sAbstractMethods {

   int         (*method1)(AbsCls c, int a);
   const char *(*method2)(AbsCls c, int b);
   void        (*method3)(AbsCls c, double d);

} *AbstractMethods, sAbsMethods;

struct sAbstractCls {

   AbstractMethods  klass;
   void     *instData;

};

  1. define ABSTRACT_METHODS( cName, m1, m2, m3 ) \
   static sAbsMethods cName ## _Iface = { &m1, &m2, &m3 }; \
   AbsCls cName ## _Instance( void *clInst) { \
       AbsCls ac = malloc(sizeof(struct sAbstractCls)); \
       if (ac) { \
           ac->klass = &cName ## _Iface; \
           ac->instData = clInst; \
       }\
       return ac; }
  1. define Abs_Method1( c, a) (c)->klass->method1(c, a)
  2. define Abs_Method2( c, b) (c)->klass->method2(c, b)
  3. define Abs_Method3( c, d) (c)->klass->method3(c, d)
  4. define Abs_Free(c) \
 do { if (c) { free((c)->instData); free(c); } } while(0);

  1. endif</lang>

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 here. We don't want it visible. <lang c>#ifndef SILLY_H

  1. define SILLY_H
  2. include intefaceAbs.h

typedef struct sillyStruct *Silly; extern Silly NewSilly( double, const char *); extern AbsCls Silly_Instance(void *);

  1. endif</lang>

Ok. Now it is necessary to provide the implementation of the realizable class. This code should be in silly.c. <lang c>#include "silly.h"

  1. include <string.h>
  2. include <stdlib.h>
  3. include <stdio.h>

struct sillyStruct {

   double  v1;
   char   str[32];

};

Silly NewSilly(double vInit, const char *strInit) {

   Silly sily = malloc(sizeof( struct sillyStruct ));
   sily->v1 = vInit;
   sily->str[0] = '\0';
   strncat(sily->str, strInit, 31);
   return sily;

}

static int MyMethod1( AbsCls c, int a) {

   Silly s = (Silly)(c->instData);
   return a+strlen(s->str);

}

static const char *MyMethod2(AbsCls c, int b) {

   Silly s = (Silly)(c->instData);
   sprintf(s->str, "%d", b);
   return s->str;

}

static void MyMethod3(AbsCls c, double d) {

   Silly s = (Silly)(c->instData);
   printf("InMyMethod3, %f\n",s->v1 * d);

}

ABSTRACT_METHODS( Silly, MyMethod1, MyMethod2, MyMethod3)</lang> 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.

The methods MyMethod1, MyMethod2, and MyMethod3 are called through the abstract class interface and do not need to be visible outside this file. Hence, they are declared static.

Now all's left is some example code that uses all this stuff. <lang c>#include <stdio.h>

  1. include "silly.h"

int main() {

   AbsCls abster = Silly_Instance(NewSilly( 10.1, "Green Tomato"));
   printf("AbsMethod1: %d\n", Abs_Method1(abster, 5));
   printf("AbsMethod2: %s\n", Abs_Method2(abster, 4));
   Abs_Method3(abster, 21.55);
   Abs_Free(abster);
   return 0;

} </lang>

C#

<lang csharp>abstract class Class1 {

  public abstract void method1();
  public int method2()
  {
     return 0;
  }

}</lang>

C++

You can declare a virtual function to not have an implementation (called "pure virtual function") by the following "= 0" syntax after the method declaration. A class containing at least one pure virtual function (or inheriting one and not overriding it) cannot be instantiated. <lang cpp>class Abs { public: virtual int method1(double value) = 0; virtual int add(int a, int b){ return a+b; } };</lang> Because C++ allows multiple inheritance of classes, no distinction is made between interfaces and abstract classes.

Clojure

Using defprotocol, we can define what is essentially an interface.

<lang lisp>(defprotocol Foo (foo [this]))</lang>

Common Lisp

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 kons to which an object belongs if methods for kar and kdr are defined for it. We define a type predicate konsp and a type kons in terms of the type predicate.

<lang lisp>(defgeneric kar (kons)

 (:documentation "Return the kar of a kons."))

(defgeneric kdr (kons)

 (:documentation "Return the kdr of a kons."))

(defun konsp (object &aux (args (list object)))

 "True if there are applicable methods for kar and kdr on object."
 (not (or (endp (compute-applicable-methods #'kar args))
          (endp (compute-applicable-methods #'kdr args)))))

(deftype kons ()

 '(satisfies konsp))</lang>

We can make the built-in types cons and integer konses. We start with cons, using the obvious definitions.

<lang lisp>(defmethod kar ((cons cons))

 (car cons))

(defmethod kdr ((cons cons))

 (cdr cons))

(konsp (cons 1 2))  ; => t (typep (cons 1 2) 'kons) ; => t (kar (cons 1 2))  ; => 1 (kdr (cons 1 2))  ; => 2</lang>

For integers, we'll define the kar of n to be 1 and the kdr of n to be n - 1. This means that for an integer n, n = (+ (kar n) (kdr n)).

<lang lisp>(defmethod kar ((n integer))

 1)

(defmethod kdr ((n integer))

 (if (zerop n) nil
   (1- n)))

(konsp 45)  ; => t (typep 45 'kons)  ; => t (kar 45)  ; => 1 (kdr 45)  ; => 44</lang>

D

<lang d>import std.stdio;

class Foo {

   // abstract methods can have an implementation for
   // use in super calls
   abstract void foo() {
       writeln("Test");
   }

}

interface Bar {

   // interface methods are implicitly abstract and cannot
   // provide default implementations
   void bar();

}

class Baz : Foo, Bar { // super class must come first

   override void foo() {
       writefln("Meep");
       super.foo();
   }
   void bar() {}

}

void main() {}</lang>

Delphi

Abstract Class introduced in Delphi 2006. An abstract class cannot be instantiated and must be derived from in order to be used.

<lang delphi>TSomeClass = class abstract (TObject)

 ...

end;</lang>


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.

<lang delphi>type

 TMyObject = class(TObject)
 public
   procedure AbstractFunction; virtual; abstract; // Your virtual abstract function to overwrite in descendant
   procedure ConcreteFunction; virtual; // Concrete function calling the abstract function
 end;

implementation

procedure TMyObject.ConcreteFunction; begin

 AbstractFunction; // Calling the abstract function

end;</lang>

DWScript

DWScript has both abstract classes and abstract methods.

See Delphi.

E

In E, the implementation of an object is never used to determine type membership (except when dealing with the host platform's objects if it uses such distinctions, such as the JVM), so all types are abstract.

A simple abstract type without enforcement can be created using the interface expression:

<lang e>interface Foo {

   to bar(a :int, b :int)

}</lang>

With enforcement, a separate stamp is created which must be applied to the instances. This is analogous to a Java interface.

<lang e>interface Foo guards FooStamp {

   to bar(a :int, b :int)

}

def x implements FooStamp {

   to bar(a :int, b :int) {
       return a - b
   }

}</lang>

Eiffel

<lang Eiffel> deferred class

   AN_ABSTRACT_CLASS

feature

   a_deferred_feature
       -- a feature whose implementation is left to a descendent
       deferred
       end
   an_effective_feature: STRING
       -- deferred (abstract) classes may still include effective features
       do
           Result := "I am implemented!"
       end

end </lang>

Fantom

<lang fantom> abstract class X {

 Void method1 ()
 {
   echo ("Method 1 in X")
 }
 abstract Void method2 ()

}

class Y : X {

 // Y must override the abstract method in X
 override Void method2 ()
 {
   echo ("Method 2 in Y")
 }

}

class Main {

 public static Void main () 
 {
   y := Y()
   y.method1
   y.method2
 }

} </lang>


F#

A type with only abstract members and without constructors is an interface (when not marked with the AbstractClass attribute). Example: <lang fsharp>type Shape =

 abstract Perimeter: unit -> float
 abstract Area: unit -> float

type Rectangle(width, height) =

 interface Shape with
   member x.Perimeter() = 2.0 * width + 2.0 * height
   member x.Area() = width * height</lang>

A type that leaves some or all members unimplemented, is an abstract class. It has to be marked with the AbstractClass attribute. Example: <lang fsharp>[<AbstractClass>] type Bird() =

 // an abstract (=virtual) method with default impl.
 abstract Move : unit -> unit
 default x.Move() = printfn "flying"
 // a pure virtual method
 abstract Sing: unit -> string

type Blackbird() =

 inherit Bird()
 override x.Sing() = "tra-la-la"

type Ostrich() =

 inherit Bird()
 override x.Move() = printfn "walking"
 override x.Sing() = "hiss hiss!"</lang>

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. <lang genyris>class AbstractStack()

  def .valid?(object) nil

tag AbstractStack some-object # always fails</lang>

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: <lang genyris>class StackInterface()

  def .valid?(object)
     object
        and
           bound? .enstack
           is-instance? .enstack Closure
           bound? .destack
           is-instance? .destack Closure</lang>

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: <lang genyris>class XYZstack(Object)

   def .init()
       var .items ()
   def .enstack(object)
       setq .items (cons object .items)
   def .destack()
       var tmp  (car .items)
       setq .items (cdr .items)
       tmp</lang>

Now we can tag an object that conforms to the Interface: <lang genyris>tag StackInterface (XYZstack(.new))</lang>

Go

Go's interface type is an abstract type. It defines a set of methods that a value must have. <lang go>interface {

   Method1(value float64) int
   SetName(name string)
   GetName() string

}</lang>

A variable of an interface type can hold a value of any type that implements the methods that are specified in the interface. You don't need to explicitly "declare" that the type "implements" the interface or anything like that -- the compatibility is purely structural based on the methods.

Groovy

Translation of: Java

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). <lang groovy>public interface Interface {

   int method1(double value)
   int method2(String name)
   int add(int a, int b)

}</lang>

An abstract class may implement some of its methods and leave others unimplemented. The unimplemented methods and the class itself must be declared "abstract". <lang groovy>public abstract class Abstract1 {

   abstract public int methodA(Date value)
   abstract protected int methodB(String name)
   int add(int a, int b) { a + b }

}</lang>

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. <lang groovy>public abstract class Abstract2 implements Interface {

   int add(int a, int b) { a + b }

}</lang>

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. <lang groovy>public class Concrete1 implements Interface {

   public int method1(double value) { value as int }
   public int method2(String name) { (! name) ? 0 : name.toList().collect { it as char }.sum() }
   public int add(int a, int b) { a + b }

}

public class Concrete2 extends Abstract1 {

   public int methodA(Date value) { value.toCalendar()[Calendar.DAY_OF_YEAR] }
   protected int methodB(String name) { (! name) ? 0 : name.toList().collect { it as char }.sum() }

}

public class Concrete3 extends Abstract2 {

   public int method1(double value) { value as int }
   public int method2(String name) { (! name) ? 0 : name.toList().collect { it as char }.sum() }

}</lang>

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: <lang groovy>def c1 = new Concrete1() assert c1 instanceof Interface println (new Concrete1().method2("Superman"))

def c2 = new Concrete2() assert c2 instanceof Abstract1 println (new Concrete2().methodB("Spiderman"))

def c3 = new Concrete3() assert c3 instanceof Interface assert c3 instanceof Abstract2 println (new Concrete3().method2("Hellboy"))</lang>

Obligatory test output:

843
931
719

Like Java, Groovy does not allow subclasses to inherit from multiple superclasses, even abstract superclasses, but it does let subclasses inherit from multiple interfaces.

Haskell

In Haskell an abstract type is a type class. A type class specifies an interface. One can then define "instances" to provide implementations of the type class for various types.

For example, the built-in type class Eq (the types that can be compared for equality) can be declared as follows: <lang haskell>class Eq a where

  (==) :: a -> a -> Bool
  (/=) :: a -> a -> Bool</lang>

Default implementations of the functions can be provided: <lang haskell>class Eq a where

  (==) :: a -> a -> Bool
  (/=) :: a -> a -> Bool
  x /= y     =  not (x == y)
  x == y     =  not (x /= y)</lang>

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: <lang haskell>func :: (Eq a) => a -> Bool func x = x == x</lang>

Suppose I make a new type <lang haskell>data Foo = Foo {x :: Integer, str :: String}</lang>

One could then provide an implementation ("instance") the type class Eq with this type <lang haskell>instance Eq Foo where

  (Foo x1 str1) == (Foo x2 str2) =
     (x1 == x2) && (str1 == str2)</lang>

And now I can, for example, use the function "func" on two arguments of type Foo.

Icon and Unicon

Unicon does not distinguish between abstract and concrete classes. An abstract class is a class with abstract methods. Icon is not object-oriented.

<lang unicon>class abstraction()

   abstract method compare(l,r) # generates runerr(700, "method compare()")

end</lang>

J

J does not support abstract types, as defined here. In J, types are typically treated as a necessary evil, which should be minimized, disguised, hidden, neglected or ignored wherever practical. (2=1+1 regardless of the type of 1 and the type of 2.) And allowing user defined types would complicate this approach.

Note also: Types are sometimes thought of as being related to function domains. But, in the general case, domains of independently defined functions are independent of each other, and the intersections of these domains may or may not be empty.

That said: it's useful to define a type, in the context of J, as "the set of values which may result from a parenthesized expression". And, if compilation to machine code is supported, it may also be useful to define constraint mechanisms to be used in expressions, so that machine code may be more easily generated.

Java

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 must be public or protected <lang java>public abstract class Abs { abstract public int method1(double value); abstract protected int method2(String name); int add(int a, int b){ return a+b; } }</lang> Interfaces in Java may not implement any methods and all methods are implicitly public and abstract. <lang java>public interface Inter { int method1(double value); int method2(String name); int add(int a, int b); }</lang>

Logtalk

In Logtalk, methods (predicates) must be declared but their definition is not mandatory. Being a logic-based language and making use of the closed-world assumption, invoking a method that is declared but not defined simply fails. If necessary, is trivial to define a method such that it throws an exception. Moreover, Logtalk doesn't define an "abstract" or "virtual" keyword. Instead it uses an operational definition where e.g. a class is considered abstract if it doesn't provide a method for creating new instances.

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". <lang logtalk>

- protocol(datep).
   :- public(today/3).
   :- public(leap_year/1).
   :- public(name_of_day/3).
   :- public(name_of_month/3).
   :- public(days_in_month/3).
- end_protocol.

</lang>

Lua

Lua does not include built-in object oriented paradigms. These features can be added using simple code such as the following: <lang lua>BaseClass = {}

function class ( baseClass )

   local new_class = {}
   local class_mt = { __index = new_class }
   function new_class:new()
       local newinst = {}
       setmetatable( newinst, class_mt )
       return newinst
   end
   if not baseClass then baseClass = BaseClass end
       setmetatable( new_class, { __index = baseClass } )
   return new_class

end

function abstractClass ( self )

   local new_class = {}
   local class_mt = { __index = new_class }
   function new_class:new()
       error("Abstract classes cannot be instantiated")
   end
   if not baseClass then baseClass = BaseClass end
       setmetatable( new_class, { __index = baseClass } )
   return new_class

end

BaseClass.class = class BaseClass.abstractClass = abstractClass</lang> 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: <lang lua>A = class() -- New class A inherits BaseClass by default AA = A:class() -- New class AA inherits from existing class A B = abstractClass() -- New abstract class B BB = B:class() -- BB is not abstract A:new() -- Okay: New class instance AA:new() -- Okay: New class instance B:new() -- Error: B is abstract BB:new() -- Okay: BB is not abstract</lang>

NetRexx

<lang NetRexx>/* NetRexx */ options replace format comments java crossref savelog symbols binary

-- ----------------------------------------------------------------------------- class RCAbstractType public final

method main(args = String[]) public constant

 say '  Testing' RCAbstractType.class.getSimpleName
 say '  Creating an object of type:' Concrete.class.getSimpleName
 conk = Concrete()
 say    'getClassName:'.right(20) conk.getClassName
 say    'getIfaceName:'.right(20) conk.getIfaceName
 say   'mustImplement:'.right(20) conk.mustImplement
 say    'canOverride1:'.right(20) conk.canOverride1
 say    'canOverride2:'.right(20) conk.canOverride2
 say 'callOverridden2:'.right(20) conk.callOverridden2
 return

-- ----------------------------------------------------------------------------- class RCAbstractType.Iface interface

ifaceName = RCAbstractType.Iface.class.getSimpleName

method getIfaceName() public returns String method canOverride1() public returns String method canOverride2() public returns String

-- ----------------------------------------------------------------------------- class RCAbstractType.Abstraction abstract implements RCAbstractType.Iface

properties inheritable

 className = String

method Abstraction() public

 setClassName(this.getClass.getSimpleName)
 return

method mustImplement() public abstract returns String

method getClassName() public returns String

 return className

method setClassName(nm = String) public

 className = nm
 return

method getIfaceName() public returns String

 return RCAbstractType.Iface.ifaceName

method canOverride1() public returns String

 return 'In' RCAbstractType.Abstraction.class.getSimpleName'.canOverride1'

method canOverride2() public returns String

 return 'In' RCAbstractType.Abstraction.class.getSimpleName'.canOverride2'

-- ----------------------------------------------------------------------------- class RCAbstractType.Concrete extends RCAbstractType.Abstraction

method Concrete() public

 super()
 return

method mustImplement() public returns String

 return 'In' RCAbstractType.Concrete.class.getSimpleName'.mustImplement'

method canOverride2() public returns String

 return 'In' RCAbstractType.Concrete.class.getSimpleName'.canOverride2'

method callOverridden2() public returns String

 return super.canOverride2

</lang>

Output
  Testing RCAbstractType
  Creating an object of type: Concrete
       getClassName: Concrete
       getIfaceName: Iface
      mustImplement: In Concrete.mustImplement
       canOverride1: In Abstraction.canOverride1
       canOverride2: In Concrete.canOverride2
    callOverridden2: In Abstraction.canOverride2

NewLISP

<lang NewLISP>; file: abstract.lsp

url
http://rosettacode.org/wiki/Abstract_type
author
oofoe 2012-01-28
Abstract Shape Class

(new Class 'Shape)  ; Derive new class.

(define (Shape:Shape  ; Shape constructor.

        (pen "X"))    ; Default value.
 (list (context)      ; Assemble data packet.
       (list 'pen pen) 
       (list 'size (args))))

(define (Shape:line x) ; Print out row with 'pen' character.

 (dotimes (i x) 
   (print (lookup 'pen (self)))) 
 (println))

(define (Shape:draw))  ; Placeholder, does nothing.

Derived Objects

(new Shape 'Box)

(define (Box:draw)  ; Override base draw method.

 (let ((s (lookup 'size (self))))
   (dotimes (i (s 0)) (:line (self) (s 0)))))

(new Shape 'Rectangle)

(define (Rectangle:draw)

 (let ((size (lookup 'size (self))))
   (dotimes (i (size 1)) (:line (self) (size 0)))))
Demonstration

(:draw (Shape))  ; Nothing happens.

(println "A box:") (:draw (Box "O" 5))  ; Create Box object and call draw method.

(println "\nA rectangle:") (:draw (Rectangle "R" 32 4))

(exit)</lang>

Sample output:

A box:
OOOOO
OOOOO
OOOOO
OOOOO
OOOOO

A rectangle:
RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR
RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR
RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR
RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR

Objeck

<lang objeck> class ClassA {

  method : virtual : public : MethodA() ~ Int;

  method : public : MethodA() ~ Int {
     return 0;
  }

} </lang>

OCaml

Virtual

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:

<lang ocaml>class virtual foo =

 object
   method virtual bar : int
 end</lang>

Abstract Type

In OCaml what we call an abstract type is not OO related, it is only a type defined without definition, for example: <lang ocaml>type t</lang> 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: <lang ocaml>module Foo : sig

 type t

end = struct

 type t = int * int

end</lang>

Pure abstract types in the implementation: <lang ocaml>type u type v type 'a t type ut = u t type vt = v t</lang>

ooRexx

Interface

<lang ooRexx>

 -- Example showing a class that defines an interface in ooRexx
 -- shape is the interface class that defines the methods a shape instance
 -- is expected to implement as abstract methods.  Instances of the shape
 -- class need not directly subclass the interface, but can use multiple
 -- inheritance to mark itself as implementing the interface.
 r=.rectangle~new(5,2)
 say r
 -- check for instance of
 if r~isa(.shape) then say "a" r~name "is a shape"
 say "r~area:" r~area
 say
 c=.circle~new(2)
 say c
 -- check for instance of shape works even if inherited
 if c~isa(.shape) then say "a" c~name "is a shape"
 say "c~area:" c~area
 say
 -- a mixin is still a class and can be instantiated.  The abstract methods
 -- will give an error if invoked
 g=.shape~new
 say g
 say g~name
 say "g~area:" g~area -- invoking abstract method results in a runtime error.
 -- the "MIXINCLASS" tag makes this avaiable for multiple inhertance
 ::class shape MIXINCLASS Object
   ::method area abstract
   ::method name abstract
 -- directly subclassing the the interface
 ::class rectangle subclass shape
   ::method init
     expose length width
     use strict arg length=0, width=0
   ::method area
     expose length width
     return length*width
   ::method name
     return "Rectangle"
 -- inherits the shape methods
 ::class circle subclass object inherit shape
   ::method init
     expose radius
     use strict arg radius=0
   ::method area
     expose radius
     numeric digits 20
     return radius*radius*3.14159265358979323846
   ::method name
     return "Circle"

</lang>

Abstract Type

<lang Rexx> -- Example showing an abstract type in ooRexx

 -- shape is the abstract class that defines the abstract method area   
 -- which is then implemented by its two subclasses, rectangle and circle
 -- name is the method inherited by the subclasses.                    
 -- author:         Rony G. Flatscher, 2012-05-26
 -- changed/edited: Walter Pachl, 2012-05-28 28 
 -- highlighting:   to come 
 r=.rectangle~new(5,2)
 say r
 say r~name
 say "r~area:" r~area
 say
 c=.circle~new(2)
 say c
 say c~name
 say "c~area:" c~area
 say
 g=.shape~new
 say g
 say g~name
 say "g~area:" g~area -- invoking abstract method results in a runtime error.
 ::class shape
   ::method area abstract
   ::method name
     return "self~class~id:" self~class~id


 ::class rectangle subclass shape
   ::method init
     expose length width
     use strict arg length=0, width=0
   ::method area
     expose length width
     return length*width
 ::class circle subclass shape
   ::method init
     expose radius
     use strict arg radius=0
   ::method area
     expose radius
     numeric digits 20
     return radius*radius*3.14159265358979323846</lang>

Oz

Translation of: Python

There are no abstract types as part of the language, but we can do as in Python and raise exceptions:

<lang oz>declare

 class BaseQueue
    attr
       contents:nil
     
    meth init
       raise notImplemented(self init) end
    end
    meth enqueue(Item)
       raise notImplemented(self enqueue) end
    end
    meth dequeue(?Item)
       raise notImplemented(self dequeue) end
    end
    meth printContents
       {ForAll @contents Show}
    end
 end
 Queue = {New BaseQueue init} %% throws</lang>

Pascal and Object Pascal

In ObjectPascal mode FreePascal has classes and abstract methods.

See Delphi

Perl

<lang perl>package AbstractFoo;

use strict;

sub frob { die "abstract" } sub baz { die "abstract" }

sub frob_the_baz {

   my $self = shift;
   $self->frob($self->baz());

}


1;</lang> Perl 6 inspired roles are provided by the Moose library

<lang perl>package AbstractFoo;

use Moose::Role;

requires qw/frob baz/;

sub frob_the_baz {

   my $self = shift;
   $self->frob($self->baz());

}

1;</lang>

Perl 6

Perl 6 supports roles, which are a bit like interfaces, but unlike interfaces in Java they can also contain some implementation.

<lang perl6> use v6;

role A {

   # must be filled in by the class it is composed into
   method abstract() { ... };
   # can be overridden in the class, but that's not mandatory
   method concrete() { say '# 42' };

}

class SomeClass does A {

   method abstract() {
       say "# made concrete in class"
   }

}

my $obj = SomeClass.new; $obj.abstract(); $obj.concrete();

  1. output:
  2. made concrete in class
  3. 42

</lang>

PHP

The following is for PHP 5.

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 <lang php>abstract class Abs { abstract public function method1($value); abstract protected function method2($name); function add($a, $b){ return a + b; } }</lang> Interfaces in PHP may not implement any methods and all methods are public and implicitly abstract. <lang php>interface Inter { public function method1($value); public function method2($name); public function add($a, $b); }</lang>

PicoLisp

<lang PicoLisp># In PicoLisp there is no formal difference between abstract and concrete

  1. classes, just a naming convention where abstract classes start with a
  2. lower case character after the '+' (the naming convention for classes).
  3. This tells the programmer that this class has not sufficient methods
  4. defined to survive on its own.

(class +abstractClass)

(dm someMethod> ()

  (foo)
  (bar) )</lang>

Python

<lang python>class BaseQueue(object):

   """Abstract/Virtual Class 
   """
   def __init__(self):
       self.contents = list()
       raise NotImplementedError
   def Enqueue(self, item):
       raise NotImplementedError
   def Dequeue(self):
       raise NotImplementedError
   def Print_Contents(self):
       for i in self.contents:
           print i,</lang>

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).

In this example we're simply following the Python convention of raising the built-in "NotImplementedError" for each function which must be implemented by our subclasses. This is a "purely virtual" class because all of its methods raise the exception. (It is sufficient for __init__ to do so for any partial virtual abstractions since that still ensures that the exception will be raised if anyone attempts to instantiate the base/abstract class directly rather than one of its concrete (fully implemented) descendents).

The method signatures and the instantiation of a "contents" list shown here can be viewed as documentary hints to anyone inheriting from this class. They won't actually do anything in the derived classes (since these methods must be over-ridden therein).

In this case we've implemented one method (Print_Contents). This would be inherited by any derived classes. It could be over-ridden, of course. If it's not over-ridden it establishes a requirement that all derived classes provide some "contents" attribute which must allow for iteration and printing as shown. Without this method the class would be "purely virtual" or "purely abstract." With its inclusion the class becomes "partially implemented."

Note: This "BaseQueue" example should not be confused with Python's standard library Queue class. That is used as the principle "producer/consumer" communications mechanism among threads (and newer multiprocessing processes).

Starting from Python 2.6, abstract classes can be created using the standard abc module: <lang python>from abc import ABCMeta, abstractmethod

class BaseQueue():

   """Abstract Class 
   """
   __metaclass__ = ABCMeta
   def __init__(self):
       self.contents = list()
   @abstractmethod
   def Enqueue(self, item):
       pass
   @abstractmethod
   def Dequeue(self):
       pass
   def Print_Contents(self):
       for i in self.contents:
           print i,</lang>

Racket

<lang scheme>#lang racket

(define animal-interface (interface () say))

(define cat% (class* object% (animal-interface) (super-new))) ;; error

(define cat% (class* object% (animal-interface)

              (super-new)
              (define/public (say)
                (display "meeeeew!"))))

(define tom (new cat%)) (send tom say)</lang>

REBOL

<lang REBOL>REBOL [ Title: "Abstract Type" Author: oofoe Date: 2009-12-05 URL: http://rosettacode.org/wiki/Abstract_type ]

The "shape" class is an abstract class -- it defines the "pen"
property and "line" method, but "size" and "draw" are undefined and
unimplemented.

shape: make object! [ pen: "X" size: none

line: func [count][loop count [prin self/pen] prin crlf] draw: does [none] ]

The "box" class inherits from "shape" and provides the missing
information for drawing boxes.

box: make shape [ size: 10 draw: does [loop self/size [line self/size]] ]

"rectangle" also inherits from "shape", but handles the
implementation very differently.

rectangle: make shape [ size: 20x10 draw: does [loop self/size/y [line self/size/x]] ]

Unlike some languages discussed, REBOL has absolutely no qualms
about instantiating an "abstract" class -- that's how I created the
derived classes of "rectangle" and "box", after all.

s: make shape [] s/draw ; Nothing happens.

print "A box:" b: make box [pen: "O" size: 5] b/draw

print [crlf "A rectangle:"] r: make rectangle [size: 32x5] r/draw</lang>

Ruby

The Python and Tcl provisos apply to Ruby too. Nevertheless, a

Library: RubyGems

package called abstraction exists where:

<lang ruby>require 'abstraction'

class AbstractQueue

 abstract
 def enqueue(object)
   raise NotImplementedError
 end
 def dequeue
   raise NotImplementedError
 end

end

class ConcreteQueue < AbstractQueue

 def enqueue(object)
   puts "enqueue #{object.inspect}"
 end

end</lang> So:

irb(main):032:0> a = AbstractQueue.new
AbstractClassError: AbstractQueue is an abstract class and cannot be instantiated
        from /usr/lib/ruby/gems/1.8/gems/abstraction-0.0.3/lib/abstraction.rb:10:in `new'
        from (irb):32
        from :0
irb(main):033:0> c = ConcreteQueue.new
=> #<ConcreteQueue:0x7fdea114>
irb(main):034:0> c.enqueue('foo')
enqueue "foo"
=> nil
irb(main):040:0> c.dequeue
NotImplementedError: NotImplementedError
        from (irb):37:in `dequeue'
        from (irb):40
        from :0

Scala

Scala has abstract classes, which are classes that cannot be instantiated. They can contain implementation as well as just interface. Non-abstract classes, on the other hand, cannot contain interfaces without implementation.

Scala also has traits, which may contain implementations or not as needed, without any abstract requirement. On the other hand, traits must be mixed in a class, instead of being directly instantiated. That doesn't matter all that much, as they can be mixed with AnyRef, which is the base parent class of all user-defined classes.

Any element of a trait or class can be made abstract, including types, with a very different meaning that described in this page. Here are some examples:

<lang scala>abstract class X {

 type A
 var B: A
 val C: A
 def D(a: A): A

}

trait Y {

 val x: X

}</lang>

When integrating with Java, traits without implementation appear as interfaces.

Tcl

Works with: Tcl version 8.6

or

Library: TclOO

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... <lang Tcl>oo::class create AbstractQueue {

   method enqueue item {
       error "not implemented"
   }
   method dequeue {} {
       error "not implemented"
   }
   self unexport create new

}</lang>

Visual Basic

Abstract Classes

Visual Basic doesn't support abstract classes or implementation inheritance.

Interfaces

In Visual Basic, every class is also an interface that other classes can implement. It has this feature because it is based on COM.

Visual Basic .NET

Abstract Classes

  • Overridable means subclasses may change the method's implementation. By default, methods in VB cannot be overridden.
  • MustOverride means the subclasses must provide an implementation
  • By convention all abstract classes have one or more Protected constructors.

<lang vbnet>MustInherit Class Base

  Protected Sub New()
  End Sub
  Public Sub StandardMethod()
      'code
  End Sub
  Public Overridable Sub Method_Can_Be_Replaced()
      'code
  End Sub
  Public MustOverride Sub Method_Must_Be_Replaced()

End Class</lang>

Interfaces

Interfaces may contain Functions, Subroutines, Properties, and Events.

<lang vbnet>Interface IBase

  Sub Method_Must_Be_Implemented()

End Interface</lang>