Skip to content

Mention relation of interfaces to member fields #3104

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
82 changes: 74 additions & 8 deletions spec/interface.dd
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ $(SPEC_S Interfaces,

$(HEADERNAV_TOC)

$(P An $(I Interface) describes a list of functions that a class which inherits
from the interface must implement.)
$(P An $(I Interface) abstracts from common behavior in terms of an abstract class
which doesn't expose implementation details of methods and object state.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This and the previous sentence should probably be joined together. The "it's" is a bit jarring.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe: "An Interface abstracts from behaviour in terms of an abstract class which ..."

I originally intended to use simple English but less text is surely reasonable as long as it's comprehensible.

If you have write access to this PR, you are welcome to do the change. I can do this only later on another device.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@maxhaton I integrated your changes with my ones.

Classes which inherit from an interface must implement the functions' signatures.)

$(GRAMMAR
$(GNAME InterfaceDeclaration):
Expand Down Expand Up @@ -39,7 +40,7 @@ $(GNAME BaseInterfaceList):
to that interface.)

$(P Interfaces cannot derive from classes; only from other interfaces.
Classes cannot derive from an interface multiple times.
Classes cannot derive from the same interface multiple times.
)

------
Expand Down Expand Up @@ -67,8 +68,7 @@ D d = new D(); // error, cannot create instance of interface
------


$(P Virtual interface member functions do not have implementations.
Interfaces are expected to implement static or final functions.
$(P Interfaces may provide definitions of members, but such members must be `static`, be templated or functions must be `final`.
)

------
Expand All @@ -80,14 +80,28 @@ interface D
}
------

$(P Interfaces can have function templates in the members.
All instantiated functions are implicitly `final`.
$(P Non-static member fields may not be defined in interfaces.
)

------
interface D
{
static immutable e = 2.71828f; // ok
float f; // error, variable `f` field not allowed in interface
immutable g = 3.81f; // error, variable `g` field not allowed in interface
enum h = 6.626f; // ok, compile-time-static symbols are considered static
}
------

$(P Interfaces can have member templates.
All instantiated member templates are implicitly `final` and therefore must be defined.
)

---
interface D
{
void foo(T)() { } // ok, it's implicitly final
T chameleon(T) = T.init; // ok, it's implicitly final
}
---

Expand All @@ -100,13 +114,17 @@ interface D
void bar();
static void foo() { }
final void abc() { }
static void xyz() { }
static int bla = 0;
}

class C : D
{
void bar() { } // ok
void foo() { } // error, cannot override static D.foo()
static void xyz() { } // ok, but does not override D.xyz()
override static void foo() { } // error, cannot override non-virtual function D.foo()
void abc() { } // error, cannot override final D.abc()
static int bla = 1; // ok, but does not override D.bla
}
------

Expand Down Expand Up @@ -155,6 +173,54 @@ B b = new B();
b.foo(); // returns 2
D d = cast(D) b; // ok since B inherits A's D implementation
d.foo(); // returns 2;
------

$(P Member definitions are only imported from an interface into a class if the symbol does not exist in that class already.)

------
interface D
{
static int foo() { return 3; }
int foo(T)() { return 10; }
}

interface E
{
static int foo(int x) { return 4; }
}

class A : D, E // imports D.foo
{
}

class B : E, D // imports E.foo
{
}

class C : D, E // neither imports D.foo nor E.foo
{
T foo(T : float)(T f) { return f; }
}

...

A a = new A();
a.foo(5); // error
a.foo(); // returns 3
a.foo!double(); // returns 10

B b = new B();
b.foo(5); // returns 4
b.foo(); // error
b.foo!double(); // error

C c = new C();
c.foo(5); // returns 5
c.foo(); // error
c.foo!double(); // error

E e = cast(E) c;
e.foo(5); // returns 4
------

$(P Interfaces can be reimplemented in derived classes:)
Expand Down