Class Declaration
Quite as in C++,
but default member access specifier is public.
// Manual container; normally you'd just use Int[].
class MyArrayOfInt {
func append(Int value)
func clear()
const operator[Int i] -> const Int&
operator[Int i] -> Int&
const func size() -> Int
const func capacity() -> Int
const func isEmpty() -> Bool
protected:
Int[0]+ numbers = NullPtr
Int size = 0
Int capacity = 0
}
Default inheritance access specifier is also public:
class MySubClass : PublicBaseClass {
...
}
class MySubClass : protected ProtectedBaseClass {
...
}
Multiple inheritance of classes is still allowed, but not recommended. Use interfaces instead.
Interfaces
interface Seekable {
func seek(Int offset)
func getPosition() -> Int
}
instead of (but still possible)
class Seekable {
virtual ~Seekable() = default
virtual func seek(Int offset) = 0
virtual func getPosition() -> Int = 0
}
Interfaces have
- no member variables (“data members”, “fields”),
- TODO maybe allow
const static,
- TODO maybe allow
- no constructors, and
- all methods are automatically
publicandvirtual,- optionally with default implementation.
Multiple Interfaces
A class can implement several interfaces:
class File : Stream, Seekable, Closeable {
...
}
No Diamond Problem for State
Because interfaces have no member variables, a class can never inherit the same data member twice. The classic C++ “diamond problem” — duplicated base-class state — therefore cannot occur, and no virtual inheritance is needed to merge base subobjects:
interface A {
func name() -> String
}
interface B : A {
...
}
interface C : A {
...
}
// `A` is reached via both `B` and `C`, but there is only ever one
// object, with no duplicated state.
class D : B, C {
func name() -> String { return "D" }
}
Ambiguous Default Implementations
The only ambiguity that can remain is a method for which two interfaces provide a (different) default implementation. The compiler then requires the class to resolve it explicitly by overriding the method. A specific interface’s default can still be called via Interface::method():
interface Greeter {
func greet() -> String { return "Hello from Greeter" }
}
interface Logger {
func greet() -> String { return "Hello from Logger" }
}
class Service : Greeter, Logger {
// Required, as it would otherwise be ambiguous.
override func greet() -> String {
return Greeter::greet() // explicitly pick one
}
}
No struct
structNot using , as it would be just too similar to structclass (especially in Cilia) with no real benefit. Keep as a reserved keyword for future use.
Cilia’s roots are more in C++ and OOP than in plain C. Not using either (Pascal, Ada).record
this-Reference
In member functions this is a reference to the instance/object (not a pointer).
class Latin1String {
func toLower() -> Latin1String& {
for i in 0..<size {
this[i].lowercase()
}
return this
}
}
Getting the pointer via &this.