Types and OOP Special type forms

# Interfaces, Enums, and Annotations

Beyond regular classes, Klyn provides interfaces for contracts, enums for symbolic states, and annotations for metadata. These three forms are small but important pieces of the language.

Interfaces

    interface DoSomething:
        public doSomething() as Int
        public abstract doSomethingElse() as Int

        public static version() as Int:
            return 1

Interface methods are abstract by default. Static interface members are also allowed when they make the contract easier to consume.

Enums

    enum Color:
        RED
        GREEN
        BLUE

    enum ColorName:
        RED = "red"
        GREEN = "green"
        BLUE = "blue"

        public readonly property value as String

        public ColorName(value as String):
            this.value = value

Simple enums receive integer values by default. You can also define explicit payload values and properties when the enum needs richer data.

Annotations

    annotation Deprecated:
        pass

    @Deprecated
    class LegacyApi:
        pass

Annotations attach metadata to declarations. They are commonly used for testing, tooling, and API lifecycle markers.

Annotations with Arguments

    annotation TestClass:
        public readonly property category as String = null

        public TestClass(category as String):
            this.category = category

    @TestClass(category="Unit")
    class MathTests:
        pass

Annotation arguments use the same named-argument style you see in ordinary calls.

Fully Qualified Annotation Names

    @klyn.unittest.TestClass
    class DemoTests:
        pass

Qualified annotation names are useful when you want to avoid ambiguity or do not want an extra import for a short file.

Test Timeouts

The standard `@Test` annotation accepts a timeout in milliseconds. A value of `0u` disables the limit. It can be combined with an expected exception.

    import klyn.unittest

    @TestClass
    public class ParserTests:

        @Test(timeout=250)
        public finishesQuickly():
            assert compute() > 0

        @Test(timeout=1000, expected=ValueException)
        public rejectsInvalidInput():
            parseValue("invalid")