Anonymous user
Abstract type: Difference between revisions
→{{header|Standard ML}}
Thundergnat (talk | contribs) m (Automated syntax highlighting fixup (second round - minor fixes)) |
imported>Regattaguru |
||
(15 intermediate revisions by 7 users not shown) | |||
Line 643:
===Interface===
{{trans|F#}}
<syntaxhighlight lang="cobol">
INTERFACE-ID. Shape.
PROCEDURE DIVISION.
IDENTIFICATION DIVISION.
METHOD-ID. perimeter.
DATA DIVISION.
Line 654 ⟶ 656:
END METHOD perimeter.
IDENTIFICATION DIVISION.
METHOD-ID. shape-area.
DATA DIVISION.
Line 664 ⟶ 667:
IDENTIFICATION DIVISION.
CLASS-ID. Rectangle.
Line 671 ⟶ 675:
INTERFACE Shape.
IDENTIFICATION DIVISION.
OBJECT IMPLEMENTS Shape.
DATA DIVISION.
Line 679 ⟶ 684:
PROCEDURE DIVISION.
IDENTIFICATION DIVISION.
METHOD-ID. perimeter.
DATA DIVISION.
Line 684 ⟶ 690:
01 ret USAGE FLOAT-LONG.
PROCEDURE DIVISION RETURNING ret.
COMPUTE
GOBACK.
END METHOD perimeter.
IDENTIFICATION DIVISION.
METHOD-ID. shape-area.
DATA DIVISION.
Line 694 ⟶ 702:
01 ret USAGE FLOAT-LONG.
PROCEDURE DIVISION RETURNING ret.
COMPUTE
GOBACK.
END METHOD shape-area.
END OBJECT.
Line 999 ⟶ 1,009:
}
</syntaxhighlight>
=={{header|EMal}}==
{{trans|Go}}
<syntaxhighlight lang="emal">
^|EMal does not support abstract types with partial implementations,
|but can use interfaces.
|^
type Beast
interface
fun getKind = text by block do end
fun getName = text by block do end
fun getCry = text by block do end
end
type Dog implements Beast
model
text kind
text name
fun getKind = text by block do return me.kind end
fun getName = text by block do return me.name end
fun getCry = text by block do return "Woof" end
end
type Cat implements Beast
model
text kind
text name
fun getKind = text by block do return me.kind end
fun getName = text by block do return me.name end
fun getCry = text by block do return "Meow" end
end
type AbstractType
^|Beast b = Beast() # interface instantiation is not allowed|^
fun bprint = void by Beast b
writeLine(b.getName() + ", who's a " + b.getKind() + ", cries: " + b.getCry() + ".")
end
^|instantiation works because a positional variadic constructor
|has been auto generated
|^
var d = Dog("labrador", "Max")
Cat c = Cat("siamese", "Sammy")
bprint(d)
bprint(c)
</syntaxhighlight>
{{out}}
<pre>
Max, who's a labrador, cries: Woof.
Sammy, who's a siamese, cries: Meow.
</pre>
=={{header|F Sharp|F#}}==
Line 1,375 ⟶ 1,432:
=={{header|Java}}==
Java has an <code>interface</code> and an <code>abstract class</code>. Neither of which can be instantiated, and require some sort of implementation or abstraction.<br />
For an <code>interface</code>, only the <code>private</code> and <code>default</code> access modifiers are allowed, which also implies they require code.<br />
A <code>private</code> method cannot be overridden by a sub-class, and a <code>default</code> method, optionally, can.<br />
A method with no access modifier is inherently <code>public</code>, must not contain code, and requires implementation by its sub-class.<br />
Member fields are allowed, although are effectively <code>public</code>, <code>final</code>, and <code>static</code>, thus requiring a value.<br />
Here is an example of an <code>interface</code>.
<syntaxhighlight lang="java">
interface Example {
String stringA = "rosetta";
String stringB = "code";
private String methodA() {
return stringA + " " + stringB;
}
default int methodB(int value) {
return value + 100;
}
int
}
</syntaxhighlight>
And here is an example of its implementing class.
<syntaxhighlight lang="java">
class ExampleImpl implements Example {
public int methodB(int value) {
return value + 200;
}
public int methodC(int valueA, int valueB) {
return valueA + valueB;
}
}
</syntaxhighlight>
The <code>abstract class</code> is very generalized, and for the most part is just a <code>class</code> that allows for un-implemented methods.<br />
The <code>default</code> access modifier is not used here, as it applies only to an <code>interface</code>.<br />
Additionally, if a method is marked <code>abstract</code>, then the <code>private</code> access modifier is not allowed, as the concept does not apply.<br />
Here is an example of an <code>abstract class</code>.<br />
If the class contains <code>abstract</code> methods then the class definition must also have the <code>abstract</code> keyword.
<syntaxhighlight lang="java">
abstract class Example {
String stringA = "rosetta";
String stringB = "code";
private String methodA() {
return stringA + " " + stringB;
}
protected int methodB(int value) {
return value + 100;
}
public abstract int methodC(int valueA, int valueB);
}
</syntaxhighlight>
Here is an example of a class which <code>extends</code> an <code>abstract class</code>.
<syntaxhighlight lang="java">
class ExampleImpl extends Example {
public int methodC(int valueA, int valueB) {
return valueA + valueB;
}
}
</syntaxhighlight>
=={{header|jq}}==
jq does not support abstract types but has a namespace-based module system which can be used
to support an "abstract type" approach of programming, as
illustrated here using an extension of the Beast/Cat/Dog example.
The following is tailored to the C implementation of jq but could also be adapted for the Go implementation.
<syntaxhighlight lang=jq>
def Beast::new($kind; $name): {
superclass: "Beast",
class: null,
$kind,
$name,
cry: "unspecified"
};
def Ape::new($kind; $name):
Beast::new($kind; $name)
| .class = "Ape"
| .cry = "Hoot";
def Cat::new($kind; $name):
Beast::new($kind; $name)
| .class = "Cat"
| .cry = "Meow";
def Dog::new($kind; $name):
Beast::new($kind; $name)
| .class = "Dog"
| .cry = "Woof";
def print:
def a($noun):
$noun
| if .[0:1] | test("[aeio]") then "an \(.)" else "a \(.)" end;
if .class == null
then "\(.name) is \(a(.kind)), which is an unknown type of \(.superclass)."
else "\(.name) is \(a(.kind)), a type of \(.class), and cries: \(.cry)."
end;
Beast::new("sasquatch"; "Bigfoot"),
Ape::new("chimpanzee"; "Nim Chimsky"),
Dog::new("labrador"; "Max"),
Cat::new("siamese"; "Sammy")
| print
</syntaxhighlight>
{{output}}
<pre>
Bigfoot is a sasquatch, which is an unknown type of Beast.
Nim Chimsky is a chimpanzee, a type of Ape, and cries: Hoot.
Max is a labrador, a type of Dog, and cries: Woof.
Sammy is a siamese, a type of Cat, and cries: Meow.
</pre>
=={{header|Julia}}==
Line 3,023 ⟶ 3,183:
END TEXTHASHKEY;
</syntaxhighlight>
=={{header|Skew}}==
{{works with|skewc|0.9.19}}
In Skew, interfaces must be explicitly implemented with `::`.
<syntaxhighlight lang="skew">
@entry
def main {
var rgb = Rgb.new(0, 255, 255)
var hex = Hex.new("00ffff")
var color Color
color = hex
color.print
color = rgb
color.print
(hex as Color).print
}
interface Color {
def toString string
def print {
dynamic.console.log(self.toString)
}
}
class Rgb :: Color {
var r int, g int, b int
def toString string { return "rgb(\(r), \(g), \(b))" }
}
class Hex :: Color {
var code string
def toString string { return "#\(code)" }
}
</syntaxhighlight>
=={{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):
Line 3,043 ⟶ 3,243:
The act of giving a signature to a module is called ascription. There are two type of ascription:
Transparent (written <tt>:</tt>) and opaque (written <tt>:></tt>). If a structure is ascribed transparently,
none of the types are abstract. If it is ascribed opaquely, all types are abstract by default, but can be specified
explicitly in the signature, in which case they are not abstract.
Line 3,067 ⟶ 3,267:
Then say we have a structure ListQueue which implements queues as lists. If we write <tt>ListQueue :> QUEUE</tt>
then the queue type will be abstract, but if we write <tt>ListQueue : QUEUE</tt> or <tt>ListQueue : LIST_QUEUE</tt> it won't.
=={{header|Swift}}==
Swift uses Protocols to provide abstract type features. See [https://docs.swift.org/swift-book/documentation/the-swift-programming-language/protocols/ the docs]
A trivial example showing required properties and methods, and the means of providing a default implementation.
<syntaxhighlight lang="sml">
protocol Pet {
var name: String { get set }
var favouriteToy: String { get set }
func feed() -> Bool
func stroke() -> Void
}
extension Pet {
// Default implementation must be in an extension, not in the declaration above
func stroke() {
print("default purr")
}
}
struct Dog: Pet {
var name: String
var favouriteToy: String
// Required implementation
func feed() -> Bool {
print("more please")
return false
}
// If this were not implemented, the default from the extension above
// would be called.
func stroke() {
print("roll over")
}
}
</syntaxhighlight>
=={{header|Tcl}}==
Line 3,165 ⟶ 3,406:
End Interface</syntaxhighlight>
=={{header|V (Vlang)}}==
{{trans|go}}
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.
Line 3,173 ⟶ 3,414:
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="v (vlang)">interface Beast {
kind() string
name() string
Line 3,222 ⟶ 3,463:
The Go example, when rewritten in Wren, looks like this.
<syntaxhighlight lang="
class Beast{
|