Java Feature Proposal

  • Thread starter christopher diggins
  • Start date
C

christopher diggins

A feature that I find missing in Java is the ability to write
functions in interfaces that can call other functions of the interface.
Given an interface ISomeInteface the only way we can write a general purpose
function to operate on all objects which implement that interface is through
the following style of declaration (in the following code snippets i is an
interface variable of type ISomeInterface) :

SomeStaticClass {
FuBar(ISomeInterface i) { ... }
}

Which when invoked requires the following syntax :

SomeStaticClass.FuBar(i);


What would be more appropriate would be to be able to define interface
functions which allow the more straightforward object-like syntax of :

i.FuBar()

For lack of a better term I refer to these kinds of functions as interface
extensions, in order to distinguish them from interface contract (the set of
functions to be implemented, by an implementor of the interface). One
possible approach for adding this feature is to prefix extension functions
with a keyword modifier, such as in the following notation :

SomeInterface {
extension FuBar() { ... }
}

Another possibility, and my preferred option, is to divide the interface
into two sections :

SomeInterface {
contract
...
extension
FuBar();
}

Would anyone else like this feature?
 
A

Anton Spaans

christopher diggins said:
A feature that I find missing in Java is the ability to write
functions in interfaces that can call other functions of the interface.
Given an interface ISomeInteface the only way we can write a general purpose
function to operate on all objects which implement that interface is through
the following style of declaration (in the following code snippets i is an
interface variable of type ISomeInterface) :

SomeStaticClass {
FuBar(ISomeInterface i) { ... }
}

Which when invoked requires the following syntax :

SomeStaticClass.FuBar(i);


What would be more appropriate would be to be able to define interface
functions which allow the more straightforward object-like syntax of :

i.FuBar()

For lack of a better term I refer to these kinds of functions as interface
extensions, in order to distinguish them from interface contract (the set of
functions to be implemented, by an implementor of the interface). One
possible approach for adding this feature is to prefix extension functions
with a keyword modifier, such as in the following notation :

SomeInterface {
extension FuBar() { ... }
}

Another possibility, and my preferred option, is to divide the interface
into two sections :

SomeInterface {
contract
...
extension
FuBar();
}

Would anyone else like this feature?

I don't understand why you need this feature. This construct will do it in a
similar way:

public interface ISomeInterface
{
public void FuBar();
}

public abstract class ASomeInterface implements ISomeInterface
{
public final void FuBar()
{
... some code ...
}
}

public class SomeInterfaceImplementer extends ASomeInterface
{
...
}

Then you can do this:
ISomeInterface i = new SomeInterfaceImplementer()
i.FuBar();

-- Anton Spaans.
 
L

lcan

Can this be done via abstract class instead of interface, which inetends to
be a pure abstract class?

Regards,
--lc
 
A

Anton Spaans

Anton Spaans said:
set

I don't understand why you need this feature. This construct will do it in a
similar way:

public interface ISomeInterface
{
public void FuBar();
}

public abstract class ASomeInterface implements ISomeInterface
{
public final void FuBar()
{
... some code ...
}
}

public class SomeInterfaceImplementer extends ASomeInterface
{
...
}

Then you can do this:
ISomeInterface i = new SomeInterfaceImplementer()
i.FuBar();

-- Anton Spaans.

Or skip the ISomeInterface all together... Just use the abstract
ASomeInterface:
ASomeInterface i = new SomeInterfaceImplementer();
i.FuBar();
 
C

christopher diggins

Anton Spaans said:
is in

Or skip the ISomeInterface all together... Just use the abstract
ASomeInterface:
ASomeInterface i = new SomeInterfaceImplementer();
i.FuBar();

Your examples though do not generalize to multiple interfaces.
 
A

Anton Spaans

christopher diggins said:
it

Your examples though do not generalize to multiple interfaces.

I agree, but you can not inherit multiple implementations (multiple
'extends' clauses) in Java, only multiple interfaces ('implements' clauses).
With your new proposed construct, you basically would violate that rule
(e.g. a class implementing two interfaces that each 'extend' - using your
new feature - FuBar(). Which of the two FuBar implementations will then be
used?).

It would then be 'simpler' to allow multiple implementation inheritance
again...
-- Anton Spaans.
 
C

christopher diggins

lcan said:
Can this be done via abstract class instead of interface, which inetends to
be a pure abstract class?

Regards,
--lc

Yes it can, but as I mention in response to Anton Spaans in the other
thread, this doesn't work with regards to multiple implementation.
 
C

christopher diggins

Or skip the ISomeInterface all together... Just use the abstract
I agree, but you can not inherit multiple implementations (multiple
'extends' clauses) in Java, only multiple interfaces ('implements' clauses).
With your new proposed construct, you basically would violate that rule
(e.g. a class implementing two interfaces that each 'extend' - using your
new feature - FuBar(). Which of the two FuBar implementations will then be
used?).

It would then be 'simpler' to allow multiple implementation inheritance
again...
-- Anton Spaans.

I do not agree that it would be simpler to allow multiple inheritance.

Let's go to the beginning : implementing an interface is not the same thing
as inheritance therefore you do not "inherit" an extension. An extension is
a function which operates on an interface by calling those functions as
implemented by the class. Any naming conflict is the same as any naming
conflict with interfaces themselves, simply cast to the correct interface to
make it explicit to the compiler which extension you are calling. There are
no "rules" being violated.
 
B

BarryNL

christopher said:
A feature that I find missing in Java is the ability to write
functions in interfaces that can call other functions of the interface.
Given an interface ISomeInteface the only way we can write a general purpose
function to operate on all objects which implement that interface is through
the following style of declaration (in the following code snippets i is an
interface variable of type ISomeInterface) :

SomeStaticClass {
FuBar(ISomeInterface i) { ... }
}

Which when invoked requires the following syntax :

SomeStaticClass.FuBar(i);


What would be more appropriate would be to be able to define interface
functions which allow the more straightforward object-like syntax of :

i.FuBar()

For lack of a better term I refer to these kinds of functions as interface
extensions, in order to distinguish them from interface contract (the set of
functions to be implemented, by an implementor of the interface). One
possible approach for adding this feature is to prefix extension functions
with a keyword modifier, such as in the following notation :

SomeInterface {
extension FuBar() { ... }
}

Another possibility, and my preferred option, is to divide the interface
into two sections :

SomeInterface {
contract
...
extension
FuBar();
}

Would anyone else like this feature?

Nope. I think it would be quite confusing. Do you have a concrete
example in mind? Everything I can think of where this might be useful is
better served by using an Adapter or Proxy pattern.
 
A

Anton Spaans

christopher diggins said:
I do not agree that it would be simpler to allow multiple inheritance.

Let's go to the beginning : implementing an interface is not the same thing
as inheritance therefore you do not "inherit" an extension. An extension is
a function which operates on an interface by calling those functions as
implemented by the class. Any naming conflict is the same as any naming
conflict with interfaces themselves, simply cast to the correct interface to
make it explicit to the compiler which extension you are calling. There are
no "rules" being violated.

What then about this:
public interface IF1
{

extension
public void FuBar()
{ some impl }
}

public interface IF2
{

extension
public void FuBar()
{ some impl }
}

public class MyClass implements IF1, IF2
{
}

And code using the MyClass class:
MyClass mc = new MyClass();
// which FuBar implementation is called?
// Note that IF1 and IF2 may not always be public, so casting is not
always possible.
mc.FuBar();

-- Anton Spaans
 
C

christopher diggins

BarryNL said:
Nope. I think it would be quite confusing. Do you have a concrete
example in mind? Everything I can think of where this might be useful is
better served by using an Adapter or Proxy pattern.

There is a more concrete example at
http://www.heron-language.com/extensions.html . The patterns you mention
have little, if anything, to do with what I am proposing.
 
C

christopher diggins

What then about this:
public interface IF1
{

extension
public void FuBar()
{ some impl }
}

public interface IF2
{

extension
public void FuBar()
{ some impl }
}

public class MyClass implements IF1, IF2
{
}

And code using the MyClass class:
MyClass mc = new MyClass();
// which FuBar implementation is called?
// Note that IF1 and IF2 may not always be public, so casting is not
always possible.
mc.FuBar();

-- Anton Spaans

From outside the class, if IF1 (or IF2) is private, then there is no
conflict to be resolved, FuBar() would be only available with regards to the
public interface so the compiler can easily deduce the correct / intended
version of the function.

So from outside the class, the solution is :

IF1(mc).FuBar();
or
IF2(mc).FuBar();

Inside the class, no conflict occurs, so a simple solution is :

IF1(this).FuBar();
or
IF2(this).FuBar();

Slightly wordy, which is good because it exhibits poor design to overuse
names.
 
A

Adam Jenkins

christopher said:
There is a more concrete example at
http://www.heron-language.com/extensions.html . The patterns you mention
have little, if anything, to do with what I am proposing.

Ok, I just read that. As far as I can tell, your
interfaces-with-extensions are exactly equivalent to abstract classes
with a special restriction on the definition of the non-abstract
methods, namely that the definitions may only call methods of the class
they're defined in. By playing semantic games you're calling these
"interfaces" instead of "abstract classes", thereby allowing you to add
multiple-inheritance to Java without calling it that.

Your extra restriction does not get rid of any of the problems with
multiple inheritance. For instance:

interface ISomeInterface1 {
contract void Foo();
extension void DoSomething() { Foo(); }
}

interface ISomeInterface2 {
contract void Bar();
extension void DoSomething() { Bar(); }
}

class SomeClass implements ISomeInterface1, ISomeInterface2
{
public void Foo() { System.out.println("Foo()"); }
public void Bar() { System.out.println("Bar()"); }

public static void main(String[] args) {
SomeClass instance = new SomeClass();
instance.DoSomething();
}
}

What will this program print when run? Which implementation of
DoSomething() will be called? It was precisely to avoid these kinds of
ambiguities, and the complex rules needed to deal with them, that
multiple-inheritance was left out of Java.

Other than the fact that they can't be multiply inherited, abstract
classes can provide the same functionality as you're proposing. Just
consider the abstract methods to be the contract, and the non-abstract
methods to be the extensions.
 
C

christopher diggins

Adam Jenkins said:
christopher said:
There is a more concrete example at
http://www.heron-language.com/extensions.html . The patterns you mention
have little, if anything, to do with what I am proposing.

Ok, I just read that. As far as I can tell, your
interfaces-with-extensions are exactly equivalent to abstract classes
with a special restriction on the definition of the non-abstract
methods, namely that the definitions may only call methods of the class
they're defined in. By playing semantic games you're calling these
"interfaces" instead of "abstract classes", thereby allowing you to add
multiple-inheritance to Java without calling it that.

Your extra restriction does not get rid of any of the problems with
multiple inheritance. For instance:

interface ISomeInterface1 {
contract void Foo();
extension void DoSomething() { Foo(); }
}

interface ISomeInterface2 {
contract void Bar();
extension void DoSomething() { Bar(); }
}

class SomeClass implements ISomeInterface1, ISomeInterface2
{
public void Foo() { System.out.println("Foo()"); }
public void Bar() { System.out.println("Bar()"); }

public static void main(String[] args) {
SomeClass instance = new SomeClass();
instance.DoSomething();
}
}

What will this program print when run? Which implementation of
DoSomething() will be called? It was precisely to avoid these kinds of
ambiguities, and the complex rules needed to deal with them, that
multiple-inheritance was left out of Java.

I responded previously to Anton Spaans with regards to this issues, you need
simply cast to the appropriate interface in order to resolve the naming
conflict (just as you would with any interface naming conflict). This is not
a complicated rule. The extensions proposal does not introduce any new
problems that do not already occur with naming conflicts with multiple
implementation of interfaces.

Interfaces with extensions do not have fields, so there is no chance of
multiple inheritance of fields which was the only big problem of [poorly
used] MI.
Other than the fact that they can't be multiply inherited, abstract
classes can provide the same functionality as you're proposing. Just
consider the abstract methods to be the contract, and the non-abstract
methods to be the extensions.

Yes abstract base classes could be used similarly except that you can't have
multiple inheritance of ABC's, and an abstract class can have fields. An
abstract base class can also partially implement the contract of another
abstract base class.

I also wish to point out that by your argument all interfaces in general can
be replaced entirely by abstract base classes.

Thanks for your comments,
 
D

Dale King

christopher diggins said:
Adam Jenkins said:
christopher said:
Would anyone else like this feature?

Nope. I think it would be quite confusing. Do you have a concrete
example in mind? Everything I can think of where this might be useful is
better served by using an Adapter or Proxy pattern.


There is a more concrete example at
http://www.heron-language.com/extensions.html . The patterns you mention
have little, if anything, to do with what I am proposing.

Ok, I just read that. As far as I can tell, your
interfaces-with-extensions are exactly equivalent to abstract classes
with a special restriction on the definition of the non-abstract
methods, namely that the definitions may only call methods of the class
they're defined in. By playing semantic games you're calling these
"interfaces" instead of "abstract classes", thereby allowing you to add
multiple-inheritance to Java without calling it that.

Your extra restriction does not get rid of any of the problems with
multiple inheritance. For instance:

interface ISomeInterface1 {
contract void Foo();
extension void DoSomething() { Foo(); }
}

interface ISomeInterface2 {
contract void Bar();
extension void DoSomething() { Bar(); }
}

class SomeClass implements ISomeInterface1, ISomeInterface2
{
public void Foo() { System.out.println("Foo()"); }
public void Bar() { System.out.println("Bar()"); }

public static void main(String[] args) {
SomeClass instance = new SomeClass();
instance.DoSomething();
}
}

What will this program print when run? Which implementation of
DoSomething() will be called? It was precisely to avoid these kinds of
ambiguities, and the complex rules needed to deal with them, that
multiple-inheritance was left out of Java.

I responded previously to Anton Spaans with regards to this issues, you need
simply cast to the appropriate interface in order to resolve the naming
conflict (just as you would with any interface naming conflict). This is not
a complicated rule. The extensions proposal does not introduce any new
problems that do not already occur with naming conflicts with multiple
implementation of interfaces.

No, you do not use casting with interface naming conflicts. With interfaces
there really isn't a conflict as there can be only one implementation. In
your case you have two method implementations with the same signature. You
have to come up with some rule to disambiguate just as you can with MI, but
you essentially have multiple inheritance of implementation.
Interfaces with extensions do not have fields, so there is no chance of
multiple inheritance of fields which was the only big problem of [poorly
used] MI.

No, MI of method implementations is just as big of a problem. In your case
you are making a weak form of multiple inheritance where it is not as bad
because you have no state to deal with, but it is still multiple inheritance
and still has the same problems.
 
C

christopher diggins

I responded previously to Anton Spaans with regards to this issues, you
need

No, you do not use casting with interface naming conflicts. With interfaces
there really isn't a conflict as there can be only one implementation. In
your case you have two method implementations with the same signature. You
have to come up with some rule to disambiguate just as you can with MI, but
you essentially have multiple inheritance of implementation.

I stand corrected. But what is wrong about the solution I propose to resolve
the conflict? AFAICT it is straightforward.
Interfaces with extensions do not have fields, so there is no chance of
multiple inheritance of fields which was the only big problem of [poorly
used] MI.

No, MI of method implementations is just as big of a problem. In your case
you are making a weak form of multiple inheritance where it is not as bad
because you have no state to deal with, but it is still multiple inheritance
and still has the same problems.

So then what are those problems, and how bad are they (considering the
proposed interface cast resolution solution above)?
 
L

Lee Fesperman

christopher said:
Let's go to the beginning : implementing an interface is not the same thing
as inheritance therefore you do not "inherit" an extension. An extension is
a function which operates on an interface by calling those functions as
implemented by the class. Any naming conflict is the same as any naming
conflict with interfaces themselves, simply cast to the correct interface to
make it explicit to the compiler which extension you are calling. There are
no "rules" being violated.

Are you saying that the 'cast' will be required in that case, otherwise it is a compile
error?

Also, are you saying that you can't override an extension method in an implementing
class or even in an extending interface?
 
A

Adam Jenkins

christopher said:
christopher said:
There is a more concrete example at
http://www.heron-language.com/extensions.html . The patterns you mention
have little, if anything, to do with what I am proposing.

Ok, I just read that. As far as I can tell, your
interfaces-with-extensions are exactly equivalent to abstract classes
with a special restriction on the definition of the non-abstract
methods, namely that the definitions may only call methods of the class
they're defined in. By playing semantic games you're calling these
"interfaces" instead of "abstract classes", thereby allowing you to add
multiple-inheritance to Java without calling it that.

Your extra restriction does not get rid of any of the problems with
multiple inheritance. For instance:

interface ISomeInterface1 {
contract void Foo();
extension void DoSomething() { Foo(); }
}

interface ISomeInterface2 {
contract void Bar();
extension void DoSomething() { Bar(); }
}

class SomeClass implements ISomeInterface1, ISomeInterface2
{
public void Foo() { System.out.println("Foo()"); }
public void Bar() { System.out.println("Bar()"); }

public static void main(String[] args) {
SomeClass instance = new SomeClass();
instance.DoSomething();
}
}

What will this program print when run? Which implementation of
DoSomething() will be called? It was precisely to avoid these kinds of
ambiguities, and the complex rules needed to deal with them, that
multiple-inheritance was left out of Java.


I responded previously to Anton Spaans with regards to this issues, you need
simply cast to the appropriate interface in order to resolve the naming
conflict (just as you would with any interface naming conflict). This is not
a complicated rule. The extensions proposal does not introduce any new
problems that do not already occur with naming conflicts with multiple
implementation of interfaces.

No, there is no naming conflict with Java interfaces, since they contain
no implementations. In the current Java spec, it's not possible for a
class to inherit multiple conflicting implementations of a method. It's
only when the "interface" can contain methods with implementations, that
the need to resolve any conflict arises. So your proposal does in fact
introduce a new set of conflicts that need to be explicitly resolved.
Here's an example of what I mean:

interface ISomeInterface1 {
void foo();
}

interface ISomeInterface2 {
void foo();
}

class SomeClass implements ISomeInterface1, ISomeInterface2 {
public void foo() { System.out.println("foo()"); }

public static void main(String[] args) {
SomeClass instance = new SomeClass();
instance.foo();
}
}

In this case, it's just an academic question to ask whether
ISomeInterface1.foo() or ISomeInterface2.foo() is called, since there's
no implementation of either. The actual method implementation being
called is SomeClass.foo(), so there's no reason to cast "instance" to
ISomeInterface1 or ISomeInterface2.

Also, the fact that there is a way to manually resolve the conflict in
your proposal doesn't remove the need for language rules to handle the
cases where you don't manually disambiguate the call. And yes, I
already know it's possible to come up with the rules; I used C++ for
years before I learned Java so I'm quite familiar with multiple
inheritance, and I think I have some understanding of its pros and cons.
Interfaces with extensions do not have fields, so there is no chance of
multiple inheritance of fields which was the only big problem of [poorly
used] MI.

I don't see why multiple inheritance of fields is any more of a problem
than multiple inheritance of methods; they seem to be about equivalent
problems to me, with similar solutions.
Yes abstract base classes could be used similarly except that you can't have
multiple inheritance of ABC's, and an abstract class can have fields. An
abstract base class can also partially implement the contract of another
abstract base class.

I also wish to point out that by your argument all interfaces in general can
be replaced entirely by abstract base classes.

But I'm not the one suggesting making it possible to have method
implementations in interfaces, you are. I think that the most important
difference between abstract classes and interfaces is that interfaces
cannot contain method implementations, which allows them to be multiply
inherited without introducing most of the problems of MI. I think that
*your* proposal is the one that makes interfaces similar enough to
abstract classes that you could just use abstract classes instead. I
don't see any really substantial differences between your proposed
interfaces and current Java abstract classes, except that your
"interfaces" can be multiply inherited. The other differences seem
minor in comparison.

Adam
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,431
Messages
2,571,678
Members
48,796
Latest member
Greg L.

Latest Threads

Top