Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Java > Defining a constructor in an Interface

Reply
Thread Tools

Defining a constructor in an Interface

 
 
Chris Berg
Guest
Posts: n/a
 
      06-29-2005
An interface forces the implementor to write the code for all the
(abstract) methods. Fine. But can I also enforce a specific
constructor footprint?

Maybe it sounds silly, but it isn't: I am constructing objects using
reflection, for instance:

String newClassName = "mypackage.MyInterface";
// (actually a run-time parameter, not a constant)
Class[] clss = new Class[]{java.util.Properties.class};
Class clazz = Class.forName(newClassName);
Constructor constr = clazz.getConstructor(clss);
MyInterface myObject = (MyInterface)constr.newInstance(objss);

So, I want to make sure that the new class actually has a constructor
with the given parameter(s).

I don't think I can use a static factory method, 'cause that would
require an actual instance of the class, which I don't have, I just
have it's name. Dilemma!

(PLEASE, ALL! Don't start a long thread with pro's and con's about
reflection, that is NOT the point here!)

Chris

 
Reply With Quote
 
 
 
 
Tjerk Wolterink
Guest
Posts: n/a
 
      06-29-2005
Chris Berg wrote:
> An interface forces the implementor to write the code for all the
> (abstract) methods. Fine. But can I also enforce a specific
> constructor footprint?
>


You cannot instantie interfaces,
interfaces define the methods that an class wich implement theinterface
should implement.

So if you have a instance of class A whos implementing interface B,
then youre sure that A has the methods of B.

An constructor in an interface is just not possible.
I cant explain it 1 2 3.

But what you can do is something like this:

interface MyInterface {
public MyInterface getInstance(ArgTypeA a, ArgtypeB b, etc);
}

class Implementor implements myInterface {
Implementor(ArgTypeA a, ArgtypeB b, etc) {

}

public MyInterface getInstance(ArgTypeA a, ArgtypeB b, etc) {
return new Implementor(a, b, etc);
}
}

hope you get my point

> Maybe it sounds silly, but it isn't: I am constructing objects using
> reflection, for instance:
>
> String newClassName = "mypackage.MyInterface";
> // (actually a run-time parameter, not a constant)
> Class[] clss = new Class[]{java.util.Properties.class};
> Class clazz = Class.forName(newClassName);
> Constructor constr = clazz.getConstructor(clss);
> MyInterface myObject = (MyInterface)constr.newInstance(objss);
>

 
Reply With Quote
 
 
 
 
Chris Smith
Guest
Posts: n/a
 
      06-29-2005
Chris Berg <(E-Mail Removed)> wrote:
> An interface forces the implementor to write the code for all the
> (abstract) methods. Fine. But can I also enforce a specific
> constructor footprint?


No, you can't. At some point, you will need to just document
requirements for creating instances. It's a bit messy, but necessary.

That said, I don't think there's ever a good excuse for requiring a
constructor that takes parameters. If you need to pass data to be used
when creating an object of some dynamically determined class, then you
should provide *two* interfaces:

public interface MyInterface { ... }

public interface MyInterfaceFactory
{
public MyInterface create(int a, String b);
}

(You're right that you can't accomplish your goals with a static factory
method, but an abstract factory is used here instead.)

It's very easy for people to remember that their class needs a default
constructor, but it's far more difficult to remember the exact types and
sequence of parameters that you require. Use of reflection's
Constructor class should be limited to truly dynamic utilities that
don't know what API they should expect from the class.

Every time I've broken that rule, I have ended up regretting it later.

--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
Reply With Quote
 
Tor Iver Wilhelmsen
Guest
Posts: n/a
 
      06-29-2005
Chris Berg <(E-Mail Removed)> writes:

> An interface forces the implementor to write the code for all the
> (abstract) methods. Fine. But can I also enforce a specific
> constructor footprint?


No. A constructor's purpose is to initialize fields; an interface does
not care about firlds only method contracts.

> So, I want to make sure that the new class actually has a constructor
> with the given parameter(s).


No, you want to make sure the object has a no-parameter constructor,
which is the most common way of doing what you want.
 
Reply With Quote
 
Lee Fesperman
Guest
Posts: n/a
 
      06-30-2005
Chris Berg wrote:
>
> An interface forces the implementor to write the code for all the
> (abstract) methods. Fine. But can I also enforce a specific
> constructor footprint?


No, you can't. Simply, it is incompatible with the nature of an interface. If you want
more details, google for it in c.l.j.p. It has been discussed a number of times in the
past, and I've provided solid reasons why it must not be done.

As others have suggested, require a no-args constructor and define a class initializer
in the interface, like init(...). It really is a better way.

--
Lee Fesperman, FFE Software, Inc. (http://www.firstsql.com)
================================================== ============
* The Ultimate DBMS is here!
* FirstSQL/J Object/Relational DBMS (http://www.firstsql.com)
 
Reply With Quote
 
Hemal Pandya
Guest
Posts: n/a
 
      06-30-2005
Chris Berg wrote:
> An interface forces the implementor to write the code for all the
> (abstract) methods. Fine. But can I also enforce a specific
> constructor footprint?


Footprint, surely not. But you mean signature. You cannot enforce that
either, as others have already pointed out. But since you are using
reflection, you can look for a constructor that has a specific
signature.

>
> Maybe it sounds silly, but it isn't: I am constructing objects using
> reflection, for instance:
>
> String newClassName = "mypackage.MyInterface";
> // (actually a run-time parameter, not a constant)
> Class[] clss = new Class[]{java.util.Properties.class};
> Class clazz = Class.forName(newClassName);
> Constructor constr = clazz.getConstructor(clss);


This will obviously fail if mypackage.MyInterface is indeed an
interface, because interfaces do not have constructors.

> MyInterface myObject = (MyInterface)constr.newInstance(objss);
>
> So, I want to make sure that the new class actually has a constructor
> with the given parameter(s).
>

But perhaps mypackage.MyInterface is not an interface but implements
some other interface, to which you will you intend to cast the
generated object.

This will work as you expect. If MyInterface has a constructor wiwth
desired signatue it will be returned otherwise NoSuchMethodException
will be throws. Of course, you cannot enforce that the constructor will
use the passed parameter in any sensible manner.

OTOH if MyInterface /is/ an interface, you are going to require the
runtime parameter to be the name of an actual class that implements
that interface, as the following example explains:

import java.lang.reflect.*;
import java.util.Properties;

interface Inter {
public static class Impl
{
public static void main(String args[]) throws Exception {
Properties p = new Properties(); p.setProperty("this", "works");
createInter("GoodInter", p);
createInter("BadInter", p);
}
static Inter createInter(String className, Properties params) throws
Exception {
Class[] clss = new Class[]{Properties.class};
Class clazz = Class.forName(className);
Constructor constr = clazz.getConstructor(clss);
Inter myObject = (Inter)constr.newInstance(new Object[]{params});
return myObject;
}
}
}

class GoodInter implements Inter {
public GoodInter(Properties p){
System.out.println("In GoodInter:<init>(Properties)");
p.list(System.out);
}
}


class BadInter implements Inter {
public BadInter(){
System.out.println("In BadInter:<init>()");
}
}

> I don't think I can use a static factory method, 'cause that would
> require an actual instance of the class, which I don't have, I just
> have it's name. Dilemma!
>
> (PLEASE, ALL! Don't start a long thread with pro's and con's about
> reflection, that is NOT the point here!)


hth.

>
> Chris


-hemal

 
Reply With Quote
 
Thomas Weidenfeller
Guest
Posts: n/a
 
      06-30-2005
Chris Smith wrote:
> That said, I don't think there's ever a good excuse for requiring a
> constructor that takes parameters.


Well, such a requirement, or lets better say nice-to-have feature, can
come up when you want to have a 1:1 translation of your design model to
an implementation. I perfectly understand (at least I think so) why
things are as they are, but it would be nice to have it otherwise.

Assume you have modeled some resource reservation system with a
ResourceRequest class and a User class. A ResourceRequest is always
associated with a User requesting a resource in your model. There should
never be a ResourceRequest without one.

To ensure this it would be easy to have a constructor

public ResourceRequest(User user) { }

You would just have to guard for a null argument in the constructor. If
you write a Bean or have other reasons to only have a no-argument public
constructor you make it easier to misuse the ResourceRequest class,
because people can suddenly construct ResourceRequests without an
associated User.

So you have a case where it is required to follow some additional
convention in order to use a class correctly. One more source for
potential bugs. You can of course work around this by providing a
factory for constructing ResourceRequests which enforces the
requirement. But you have to write more code. More code - more potential
bugs.

/Thomas


--
The comp.lang.java.gui FAQ:
ftp://ftp.cs.uu.nl/pub/NEWS.ANSWERS/...g/java/gui/faq
http://www.uni-giessen.de/faq/archiv....java.gui.faq/
 
Reply With Quote
 
Lee Fesperman
Guest
Posts: n/a
 
      06-30-2005
Thomas Weidenfeller wrote:
>
> Chris Smith wrote:
> > That said, I don't think there's ever a good excuse for requiring a
> > constructor that takes parameters.

>
> Well, such a requirement, or lets better say nice-to-have feature, can
> come up when you want to have a 1:1 translation of your design model to
> an implementation. I perfectly understand (at least I think so) why
> things are as they are, but it would be nice to have it otherwise.


Nope, it's still a bad idea. A decent implementation is likely to want additional
arguments to its constructor. It pretty much kills multiple inheritance of interfaces
because of conflicting constructor requirements. If your implementation wishes to extend
another class with specific constructor requirements, you have no recourse.

There is more. Google for previous discussions on this.

--
Lee Fesperman, FFE Software, Inc. (http://www.firstsql.com)
================================================== ============
* The Ultimate DBMS is here!
* FirstSQL/J Object/Relational DBMS (http://www.firstsql.com)
 
Reply With Quote
 
Bent C Dalager
Guest
Posts: n/a
 
      06-30-2005
In article <(E-Mail Removed)>,
Lee Fesperman <(E-Mail Removed)> wrote:
>
>As others have suggested, require a no-args constructor and define a
>class initializer
>in the interface, like init(...). It really is a better way.


I have based my (non-factory-based) immutables on getting all their
state through the ctor, but the question posed indicates that this
isn't always feasible.

Is an init() method considered a viable way to make immutable objects?
While you could write init() in such a way that any calls beyond the
first are ignored, it seems a bit kludgy. If nothing else, clients
could end up using instances that haven't had init() called on them
yet and then their contents _can_ theoretically change at some later
point.

Cheers
Bent D
--
Bent Dalager - http://www.velocityreviews.com/forums/(E-Mail Removed) - http://www.pvv.org/~bcd
powered by emacs
 
Reply With Quote
 
Thomas Weidenfeller
Guest
Posts: n/a
 
      06-30-2005
Lee Fesperman wrote:
> Nope, it's still a bad idea. A decent implementation is likely to want additional
> arguments to its constructor. It pretty much kills multiple inheritance of interfaces
> because of conflicting constructor requirements. If your implementation wishes to extend
> another class with specific constructor requirements, you have no recourse.
>
> There is more. Google for previous discussions on this.


I am not saying it is a good idea. I am just saying that I don't agree
with Chris' claim:

>> That said, I don't think there's ever a good excuse for requiring a
>> constructor that takes parameters.


/Thomas

--
The comp.lang.java.gui FAQ:
ftp://ftp.cs.uu.nl/pub/NEWS.ANSWERS/...g/java/gui/faq
http://www.uni-giessen.de/faq/archiv....java.gui.faq/
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Defining an object constructor that look like [] or {} ...? Sonny Chee Ruby 4 01-17-2009 11:07 AM
A constructor calling another constructor (default constructor)? Generic Usenet Account C++ 10 11-28-2007 04:12 AM
Defining a good interface for a component jarre_karl@yahoo.com Java 0 04-24-2005 07:18 PM
defining or not defining destructors johny smith C++ 8 07-02-2004 08:51 AM
Defining c'tor within interface and abstract class Raffael Vogler Java 8 11-30-2003 11:57 AM



Advertisments