Declaring members for Interfaces

V

vamsee.maha

Can anyone tell me reason:

Why the syntax for declaring members in interfaces are declared as
constants.
 
J

Jan Thomä

Can anyone tell me reason:

Why the syntax for declaring members in interfaces are declared as
constants.

Well the usual idea is that you dont need to qualify your constants if you
put them into an interface. Assume this:

class MyConstants {

public static String MY_STRING = "foo";

}

Now if you want to use this in a class of yours:


class MyWindow extends JFrame {

private void buildUI() {
...

field.setText(MyConstants.MY_STRING);
....
}
}

If you declare the constants in an interface:

interface MyConstants {
public static String MY_STRING = "foo";
}

you can do

class MyWindow extends JFrame implements MyConstants {
private void buildUI() {
...

field.setText(MY_STRING);
....
}

}

since you inherited the constants from the interface. Note however, that
this is considered bad style by many people, as you can get into trouble
when you have the same constant name in different interfaces. Also you are
misusing the idea of interfaces for saving some typing, which can be
considered a hack. The preferred way of doing this in Java 1.5 or above is
using static imports:

import static MyConstants.*;
class MyWindow extends JFrame {
private void buildUI() {
...

field.setText(MY_STRING);
....
}

}




Jan
 
V

vamsee.maha

Well the usual idea is that you dont need to qualify your constants if you
put them into an interface. Assume this:

class MyConstants {

 public static String MY_STRING =  "foo";

}

Now if you want to use this in a class of yours:

class MyWindow extends JFrame {

   private void buildUI() {
    ...

     field.setText(MyConstants.MY_STRING);
...
   }

}

If you declare the constants in an interface:

interface MyConstants {
 public static String MY_STRING = "foo";

}

you can do

class MyWindow extends JFrame implements MyConstants {
  private void buildUI() {
    ...

     field.setText(MY_STRING);
...
   }

}

since you inherited the constants from the interface. Note however, that
this is considered bad style by many people, as you can get into trouble
when you have the same constant name in different interfaces. Also you are
misusing the idea of interfaces for saving some typing, which can be
considered a hack. The preferred way of doing this in Java 1.5 or above is
using static imports:

import static MyConstants.*;
class MyWindow extends JFrame {
  private void buildUI() {
    ...

     field.setText(MY_STRING);
...
   }

}

Jan

The explanation says for declaring constants we use members of
interfaces. It also says it may not be best way of declaring
constants. I feel there is one important reason why we declare members
of interfaces as constants
 
T

Thomas Kellerer

(e-mail address removed), 23.04.2008 07:54:
Can anyone tell me reason:

Why the syntax for declaring members in interfaces are declared as
constants.
I assume with "member" you mean "instance variable". As an interface itself can never be instantiated there is no way an interface can have a "member" (just like an interface cannot implement a method).

The only thing an interface can declare (or implement) are static variables (aka constants) and static methods because they are bound to the class, not to an instance.

Thomas
 
R

Roedy Green

Can anyone tell me reason:

Why the syntax for declaring members in interfaces are declared as
constants.

An interface defines what code you need to write, not how you do it.

The constants are there primarily because enums are recent and you
needed a way to create named constant values. They conceptually are
part of the method signatures.

In an abstract class you can specify HOW the implementation is to
work. There you can specify instance variables.

See http://mindprod.com/jgloss/interfacevsabstract.html
 
J

Jan Thomä

The explanation says for declaring constants we use members of
interfaces. It also says it may not be best way of declaring
constants. I feel there is one important reason why we declare members
of interfaces as constants


In fact you should use enums as much as possible because they are a much
better way of declaring constants.


You can also declare interface members to be non-constant but that would
not be of much use as per spec all members of an interface are public
static and final.


JLS 9.3:
Every field declaration in the body of an interface is implicitly public,
static, and final. It is permitted to redundantly specify any or all of
these modifiers for such fields.

This means, there is no way to specify interface fields that are non-final
(== non-constant).

Jan
 
Z

zkr.ryz

Because.... well.. they are constants!

All fields in the interface are public static final by defult. Thus
constant.

Try changing the value of one of them.
 
R

Roedy Green

A constant is a final variable initialized with a compile-time
constant expression.

Hmm. Does the JLS define that? One of my early beefs about Java was
the sloppy way they used the term "constant" for so many different
things, including literals. It would be great if they have nailed
that down clearly.
 
T

Todd

In fact you should use enums as much as possible because they are a much
better way of declaring constants.

With the enum declaration of a constant, you must supply a getter
method or make the field that holds the value of the constant
public (violating encapsulation).

Using a class with a private constructor, public static final fields,
and static import of the class, you get direct access without
namespace pollution.

Shouldn't the overhead of a method invocation be considered as a
'nay' vote for enum_s as a constant repository?

Todd
 
E

EJP

Todd said:
With the enum declaration of a constant, you must supply a getter
method or make the field that holds the value of the constant
public (violating encapsulation).

You mean reimplement Enum.ordinal()? Please.
 
T

Todd

Lew,

This example is from the Sun Tutorial site:

public enum Planet {
MERCURY (3.303e+23, 2.4397e6),
VENUS (4.869e+24, 6.0518e6),
EARTH (5.976e+24, 6.37814e6),
MARS (6.421e+23, 3.3972e6),
JUPITER (1.9e+27, 7.1492e7),
SATURN (5.688e+26, 6.0268e7),
URANUS (8.686e+25, 2.5559e7),
NEPTUNE (1.024e+26, 2.4746e7);

private final double mass; // in kilograms
private final double radius; // in meters
Planet(double mass, double radius) {
this.mass = mass;
this.radius = radius;
}
private double mass() { return mass; }
private double radius() { return radius; }

// universal gravitational constant (m3 kg-1 s-2)
public static final double G = 6.67300E-11;

double surfaceGravity() {
return G * mass / (radius * radius);
}
double surfaceWeight(double otherMass) {
return otherMass * surfaceGravity();
}
public static void main(String[] args) {
double earthWeight = Double.parseDouble(args[0]);
double mass = earthWeight/EARTH.surfaceGravity();
for (Planet p : Planet.values())
System.out.printf("Your weight on %s is %f%n",
p, p.surfaceWeight(mass));
}
}

How do I get the value of mass without a getter from any
of the enumerated items from outside of the enumeration?

I took a walk, but apparently am not seeing the "magic"
you claim. Help me out?

Todd
 
T

Todd

Lew,

This example is from the Sun Tutorial site:

public enum Planet {
MERCURY (3.303e+23, 2.4397e6),
VENUS (4.869e+24, 6.0518e6),
EARTH (5.976e+24, 6.37814e6),
MARS (6.421e+23, 3.3972e6),
JUPITER (1.9e+27, 7.1492e7),
SATURN (5.688e+26, 6.0268e7),
URANUS (8.686e+25, 2.5559e7),
NEPTUNE (1.024e+26, 2.4746e7);

private final double mass; // in kilograms
private final double radius; // in meters
Planet(double mass, double radius) {
this.mass = mass;
this.radius = radius;
}
private double mass() { return mass; }
private double radius() { return radius; }

// universal gravitational constant (m3 kg-1 s-2)
public static final double G = 6.67300E-11;

double surfaceGravity() {
return G * mass / (radius * radius);
}
double surfaceWeight(double otherMass) {
return otherMass * surfaceGravity();
}
public static void main(String[] args) {
double earthWeight = Double.parseDouble(args[0]);
double mass = earthWeight/EARTH.surfaceGravity();
for (Planet p : Planet.values())
System.out.printf("Your weight on %s is %f%n",
p, p.surfaceWeight(mass));
}

}

Since the members of the enumeration (mass, radius)
are directly accessible without getters, even though
private, what use is the private keyword?

I had thought that private worked in an enum as it
does in all other classes, hence my previous question.
Only after some compiling and playing with these examples
did I find that private was meaningless in the enum.
Further, I can change the value of any non-final member
without an accessor. To me, it seems that enums are
rather loose.

My test included the following lines and changed mass to
non-final, but left it private:

System.out.println( Planet.EARTH.mass );
Planet.EARTH.mass = 12;
System.out.println( Planet.EARTH.mass );



Todd
 
M

Mark Space

Todd said:
How do I get the value of mass without a getter from any
of the enumerated items from outside of the enumeration?

I took a walk, but apparently am not seeing the "magic"
you claim. Help me out?


What you quoted is not really a normal use of enums. It's a fancy
example intended to show the ability to customize the use of enums.

What is normal is

enum Planets {EARTH, MARS, VENUS};

and then you have several methods declared for you.

Planets p = Enum.valueOf( Planets, "MARS" );
int i = p.ordinal();
String s = p.toString();
boolean b = p.equals( Enum.valueOf( Planets, "MARS" );

etc.

Your original post said

"With the enum declaration of a constant, you must supply a getter
method or make the field that holds the value of the constant
public (violating encapsulation)."

Well that's not really true in the example I gave, is it? I did not need
to declare any getters and setters. And if I do declare getters and
setters, it's no different from a public class, except with enums I also
get the functionality above, and a bit more besides (EnumMap, EnumSet).

And your other comment about "namespace pollution" is equally off the
beam. I just don't see how it applies to enums at all.
 
T

Todd

You mean reimplement Enum.ordinal()? Please.

EJP,

That works fine for monotonically increasing enums. I just
posted an example from the Sun Tutorial website wherein the
enum is based upon defined data for the enumerated item.

My confusion was that private is not really private in enums
and I thought that with defined values, one would have to
have a getter for a class variable.

So, no, I didn't mean to reimplement Enum.ordinal().
You're welcome.

Todd
 
T

Todd

And your other comment about "namespace pollution" is equally off the
beam. I just don't see how it applies to enums at all.

Mark,

I agree with you completely when using the simplest form of enum.
I was thinking of how one would use it for constants, as was discussed
early in the thread with respect to usage in interfaces.

With an interface, you get namespace pollution when declaring
constants.
If I implied that I felt that was the same with enums, I apologize.

However, if we are to limit ourselves to only using the constructs
in the simplest way and not explore the more complex things that can
be done, how is one to do more than the API has provided?

Todd
 
T

Todd

All,

I did not like the fact that I was able to
access the private members of the Planet
enum in my tests, so I decided to mess with
it more.

The reason I could access the private members
directly was that I placed the Planet enum
as an inner class in my test class. Scope
allowed me to access those private members.

Next, I moved the Planet enum to its own file,
away from my test class. Now, I can not
access the private member directly. So, I
am back to asking: "how do I access a private
member without an accessor?"

So far as I know, without Reflection, you can't.
Which leads me back to stating that there will
need to be an accessor in an enum to get at
non-ordinal values.

Todd
 
L

Lasse Reichstein Nielsen

Todd said:
This example is from the Sun Tutorial site:

public enum Planet {
MERCURY (3.303e+23, 2.4397e6),
VENUS (4.869e+24, 6.0518e6), ....

private final double mass; // in kilograms
private final double radius; // in meters
Planet(double mass, double radius) {
this.mass = mass;
this.radius = radius;
}
private double mass() { return mass; }
private double radius() { return radius; } ....
How do I get the value of mass without a getter from any
of the enumerated items from outside of the enumeration?

You don't. You use the getter called "mass":

double venusMass = Planet.VENUS.mass();

/L
 
T

Todd

Okay. You agree. You can't/don't access
a private method without an accessor. So,
I am back to asking those of you who think
that enums should be used as constant
repositories how one gets at those values?

Lew, you claim that enums just do this for
you. I agree that this is true for ordinal
values. When an enum is used to store
non-ordinal constants - as the Planet example
shows - where is the magic? Maybe you need
to review enums as you admonished me to do.

Somehow, it seems that there is no coherent
thread being followed, or there is selective
memory when it comes to responding to posts.
I am back to stating that a utility class
is better than an enum to declare constants.

Todd

utility class: public class, private constructor,
static members
 
W

Wojtek

Mark Space wrote :
What you quoted is not really a normal use of enums.

Um, normal where?

I happen to use that construct a lot. Rather than just having a fancy
constant, I make store pertinent information in it.

For instance an ordinal is nice, but the value for a given enum's
ordinal is undefined and may chnage between compiles. Hard to use in a
persistent situation (database).

So I use a unique value which I know will not change and that is what I
use for storage.

So why not just a static final int? Because using an enum enforces type
safety.
 
W

Wojtek

Todd wrote :
I am back to stating that a utility class
is better than an enum to declare constants.

An enum gives type safety and lets the compiler do work for you.

A "utility" class with a bunch of static final int or String only
enforces that an int or String be passed into a method.

But with an enum, only THAT enum can be passed in, so the method can be
assured that the value is valid.
 

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
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top