From 639258b866ef62aa20085ec20a1055c9c317d780 Mon Sep 17 00:00:00 2001 From: christoph-ehm <55560021+christoph-ehm@users.noreply.github.com> Date: Mon, 27 Sep 2021 15:16:45 +0200 Subject: [PATCH 1/8] Mention relation of interfaces to member fields In D the interfaces are special abstract classes which forbid non-static function declarations and non-static member field definitions. For good software engineering reasons I didn't add `alias` to the interface example. --- spec/interface.dd | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/spec/interface.dd b/spec/interface.dd index 7a82db0b8b..815dda5854 100644 --- a/spec/interface.dd +++ b/spec/interface.dd @@ -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 a common set of behaviour. It's an abstract class + which doesn't expose implementation details of methods and object state. + Classes which inherit from an interface must implement the functions signatures.) $(GRAMMAR $(GNAME InterfaceDeclaration): @@ -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. ) ------ @@ -78,6 +79,19 @@ interface D static void foo() { } // ok final void abc() { } // ok } +------ + + $(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 function templates in the members. From 5d7830e7ef971afb5ebc93e5e6fd760017da0791 Mon Sep 17 00:00:00 2001 From: christoph-ehm <55560021+christoph-ehm@users.noreply.github.com> Date: Wed, 6 Oct 2021 13:16:11 +0200 Subject: [PATCH 2/8] Update wording in interface explanation, spec/interface.dd --- spec/interface.dd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/interface.dd b/spec/interface.dd index 815dda5854..75fba56c8c 100644 --- a/spec/interface.dd +++ b/spec/interface.dd @@ -4,7 +4,7 @@ $(SPEC_S Interfaces, $(HEADERNAV_TOC) - $(P An $(I Interface) abstracts from a common set of behaviour. It's an abstract class + $(P An $(I Interface) abstracts from common behaviour in terms of an abstract class which doesn't expose implementation details of methods and object state. Classes which inherit from an interface must implement the functions signatures.) From f573d76f8b7bcda220ce3de5f0e938d8b76a3e6e Mon Sep 17 00:00:00 2001 From: christoph-ehm <55560021+christoph-ehm@users.noreply.github.com> Date: Tue, 19 Oct 2021 17:33:09 +0200 Subject: [PATCH 3/8] Add missing apostrophy to spec/interface.dd in the introductory paragraph --- spec/interface.dd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/interface.dd b/spec/interface.dd index 75fba56c8c..89e1e08630 100644 --- a/spec/interface.dd +++ b/spec/interface.dd @@ -6,7 +6,7 @@ $(HEADERNAV_TOC) $(P An $(I Interface) abstracts from common behaviour in terms of an abstract class which doesn't expose implementation details of methods and object state. - Classes which inherit from an interface must implement the functions signatures.) + Classes which inherit from an interface must implement the functions' signatures.) $(GRAMMAR $(GNAME InterfaceDeclaration): From c94a857349f7508dca2af497fef34bd3e1c2f19e Mon Sep 17 00:00:00 2001 From: christoph-ehm <55560021+christoph-ehm@users.noreply.github.com> Date: Tue, 19 Oct 2021 19:14:56 +0200 Subject: [PATCH 4/8] Add further examples to spec/interface.dd Corrected static-override example. Example for behaviour with conflicting symbols. Example for templated non-static member field. --- spec/interface.dd | 62 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 57 insertions(+), 5 deletions(-) diff --git a/spec/interface.dd b/spec/interface.dd index 89e1e08630..f958a83001 100644 --- a/spec/interface.dd +++ b/spec/interface.dd @@ -68,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`. ) ------ @@ -94,14 +93,15 @@ interface D } ------ - $(P Interfaces can have function templates in the members. - All instantiated functions are implicitly `final`. + $(P Interfaces can have templated members. + All instantiated member templates are implicitly `final`. ) --- interface D { void foo(T)() { } // ok, it's implicitly final + T chameleon(T) = T.init; // ok, it's implicitly final } --- @@ -114,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 } ------ @@ -169,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:) From 347f1f68b3063a024724121f3fc605b081d105e1 Mon Sep 17 00:00:00 2001 From: christoph-ehm <55560021+christoph-ehm@users.noreply.github.com> Date: Tue, 19 Oct 2021 19:17:34 +0200 Subject: [PATCH 5/8] templated member -> member template --- spec/interface.dd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/interface.dd b/spec/interface.dd index f958a83001..712bc844b6 100644 --- a/spec/interface.dd +++ b/spec/interface.dd @@ -93,7 +93,7 @@ interface D } ------ - $(P Interfaces can have templated members. + $(P Interfaces can have member templates. All instantiated member templates are implicitly `final`. ) From cf4e9b8f63e59acc01f2a2feedd2e525e4a58c33 Mon Sep 17 00:00:00 2001 From: christoph-ehm <55560021+christoph-ehm@users.noreply.github.com> Date: Tue, 19 Oct 2021 19:20:34 +0200 Subject: [PATCH 6/8] static member fields don't override interface --- spec/interface.dd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/interface.dd b/spec/interface.dd index 712bc844b6..741b1f51f1 100644 --- a/spec/interface.dd +++ b/spec/interface.dd @@ -124,7 +124,7 @@ class C : D 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 + static int bla = 1; // ok, but does not override D.bla } ------ From 822d405e486998290b8a3cec48b634e2c364a199 Mon Sep 17 00:00:00 2001 From: christoph-ehm <55560021+christoph-ehm@users.noreply.github.com> Date: Tue, 19 Oct 2021 19:23:04 +0200 Subject: [PATCH 7/8] change behaviour -> behavior --- spec/interface.dd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/interface.dd b/spec/interface.dd index 741b1f51f1..70a1bbb3a5 100644 --- a/spec/interface.dd +++ b/spec/interface.dd @@ -4,7 +4,7 @@ $(SPEC_S Interfaces, $(HEADERNAV_TOC) - $(P An $(I Interface) abstracts from common behaviour in terms of an abstract class + $(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. Classes which inherit from an interface must implement the functions' signatures.) From 3e3407a4d1c343a62c07ca7110506e21c73e96d5 Mon Sep 17 00:00:00 2001 From: christoph-ehm <55560021+christoph-ehm@users.noreply.github.com> Date: Tue, 19 Oct 2021 19:24:27 +0200 Subject: [PATCH 8/8] Add definition rule for implicitly final members --- spec/interface.dd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/interface.dd b/spec/interface.dd index 70a1bbb3a5..9b0918e076 100644 --- a/spec/interface.dd +++ b/spec/interface.dd @@ -94,7 +94,7 @@ interface D ------ $(P Interfaces can have member templates. - All instantiated member templates are implicitly `final`. + All instantiated member templates are implicitly `final` and therefore must be defined. ) ---