Must you `override` when implementing an interface?
'override' is not allowed when implementing an interface method.
We want to distinguish between overriding (redefining the behavior of a method) and implementing (satisfying specific type constraints of a method). We could have an 'implements' attribute to mark methods doing the latter, but that seems like overkill since you'll get a "method not implemented" error or type error if you don't get the name and type of the implementing method right.
Sound reasonable?
The question came up in the context of documenting methods,
distinguishing methods that are being defined in the class (and are
not part of an interface). In that sense, an implement
attribute
would have some of the benefit of override
in catching type-ohs:
the compiler could signal an error if you define a method as
implementing an interface and there is no matching interface.
The question came up in the context of documenting methods, distinguishing methods that are being defined in the class (and are not part of an interface). In that sense, an
implement
attribute would have some of the benefit ofoverride
in catching type-ohs: the compiler could signal an error if you define a method as implementing an interface and there is no matching interface.
It already does. In AS3/draft-ES4 it is a static error if any of the inherited interface methods is not implemented in the inheriting class, unlike in Java. Partially implemented (or abstract) classes don't exist in ES4.
On 2007-03-26, at 14:11 EDT, Jeff Dyer wrote:
The question came up in the context of documenting methods, distinguishing methods that are being defined in the class (and are not part of an interface). In that sense, an
implement
attribute would have some of the benefit ofoverride
in catching type-ohs: the compiler could signal an error if you define a method as implementing an interface and there is no matching interface.It already does. In AS3/draft-ES4 it is a static error if any of the inherited interface methods is not implemented in the inheriting
class, unlike in Java. Partially implemented (or abstract) classes don't
exist in ES4.
I'm considering the case where I define a method that I think is part
of an interface but it is not:
interface A { function x (); }
class B implements A { function x () {...}; function y () {...}; }
function (a:A) { a.y(); }
Possibly unlikely, and yes, you get an error at the call site, but if
I had to say:
class B implements A { implement function x () {...}; implement function y () {...}; }
The compiler could warn me that there is no interface method y
in
the interfaces implemented by B. Perhaps useful in an IDE or where
separate compilation is going on? I'm comparing that to the override
case where I declare a method as being an override but there is no
such method in the super chain.
From: P T Withington [mailto:ptw at pobox.com]
The question came up in the context of documenting methods, distinguishing methods that are being defined in the class (and are not part of an interface). In that sense, an
implement
attribute would have some of the benefit ofoverride
in catching type-ohs: the compiler could signal an error if you define a method as implementing an interface and there is no matching interface.It already does. In AS3/draft-ES4 it is a static error if any of the inherited interface methods is not implemented in the inheriting class, unlike in Java. Partially implemented (or abstract) classes don't exist in ES4.
I'm considering the case where I define a method that I think is part of an interface but it is not:
interface A { function x (); }
class B implements A { function x () {...}; function y () {...}; }
function (a:A) { a.y(); }
Possibly unlikely, and yes, you get an error at the call site, but if I had to say:
class B implements A { implement function x () {...}; implement function y () {...}; }
The compiler could warn me that there is no interface method
y
in the interfaces implemented by B. Perhaps useful in an IDE or where separate compilation is going on? I'm comparing that to the override case where I declare a method as being an override but there is no such method in the super chain.
This only solves part of the problem. What if B also implements an interface 'Z' that has a 'y' method? The program is still exposed to the same kinds of errors. I actually prefer a system where you have to declare the interface in which the implementing method was introduced. For example,
interface A { function x (); }
class B implements A { A function x () {...}; A function y () {...}; // oops error, no y in A }
But that proposal did not get traction in TG1. I could try to resuscitate it if there are new, compelling real world use cases.
The point is to avoid name confusion (ambiguity and misnaming) when implementing multiple interfaces. As it is, any 'public' method will implement an inherited interface method with the name and compatible signature.
Use cases anyone?
No specific use-cases, but I love the idea. I think we have briefly discussed this before, in an AS3 context...
But I think there would be some complications around having a method be part of multiple interfaces (unless a method could be declared in multiple namespaces).
Could there also be a complication with the necessity of having to have the namespace automatically opened within any scope that references a variable typed as either the interface or implementing class?
Peter
From: peterjoel at gmail.com [mailto:peterjoel at gmail.com] On Behalf Of Peter
But I think there would be some complications around having a method be part of multiple interfaces (unless a method could be declared in multiple namespaces).
In this case, we would do as we do today and use 'public' to mean implements all unimplemented, matching methods with the same identifier.
Could there also be a complication with the necessity of having to have the namespace automatically opened within any scope that references a variable typed as either the interface or implementing class?
Our thinking early in the development of AS3 was to open only an interface's namespace when,
-
referencing through a property annotated with that interface or through an interface or class that inherits from that interface, and
-
inside the body of a method that implements a method of that interface
interface I { function m() } interface J { function m() } class A implements I, J { I function m() { n() } // calls I::n I function n() { }
J function m() { n() } // calls J::n J function n() { } }var a : A = new A a.m() // error: ambiguous reference a.I::m() // calls I::m a.J::m() // calls J::m
var i : I = a var j : J = a i.m() // calls I::m j.m() // calls J::m
Ihe big idea here is that an interface describes a view of an object. To use that view you need to ask for it, either with a type annotation or a namespace qualified identifier. "use namespace I" is not allowed, nor was any other way of opening an interface namespace.
This is not what happened though. Some users were not comfortable with the "interface as namespace" idea and wanted to be able to implement interface methods to be in the 'public' namespace so they could be accessed through any ordinary reference without namespace qualification.
So our next step was to say that you can implement interface methods with methods in the 'public' namespace. References through the interface would see them as an interface method, and other references could see them as a public method. This sounded pretty promising, but it was starting to get complicated. Interface methods could be in two namespaces (a first in our naming scheme), and the logic for determining which interface methods get implemented by which public method declarations when you have multiple base interfaces and a base class that implements some of those interface methods (I'll spare you the details for now) was getting hairy.
Out of time and energy we rolled the design of interfaces in AS3 back to a simpler and I think future proof system where interface methods are implemented by compatible public methods. Such methods might implement any number of interface methods inherited by its class. This might lead to conflicts that can only be resolved in the interfaces, but oh well.
I'm writing all of this in case it of general interest, and also because most of the TG1 workers haven't heard it all, and just in case we made a mistake with AS3, and should press on to a more expressive interface system for ES4.
Thoughts?
On 2007-03-26, at 19:22 EDT, Jeff Dyer wrote:
Some users were not comfortable with the "interface as namespace" idea
Count me in: that's too magic. I would rather see an alias mechanism
(as in Schärli's Traits) or explicit namespaces (with rename on
import, as in Dylan modules) for resolving conflicting methods.
A reader asks,
From the spec, I see:
Taken together, I would conclude that the instance method must also
be declared with the
override
attribute. Is that the intent?