1

I am designing a program for converting distances between units and have been given code to test this. I don't understand how to write my method so that is can be called by a constant. The following code is given:

System.out.println(DistanceUnit.METER.toMetric(100));
  System.out.println(DistanceUnit.METER.fromMetric(100));
  System.out.println(DistanceUnit.FOOT.toMetric(100));
  System.out.println(DistanceUnit.FOOT.fromMetric(100));
  System.out.println(DistanceUnit.PLANCK.toMetric(100));
  System.out.println(DistanceUnit.PLANCK.fromMetric(100));;
  System.out.println(DistanceUnit.PARSEC.toMetric(100));
  System.out.println(DistanceUnit.PARSEC.fromMetric(100));

So I have defined the constants above according to the instructions in the assignment but how do I create the methods fromMetric and toMetric so that they can be called by the constants from DistanceUnits?

  • 3
    This looks like an `enum`, not constants. – bcsb1001 Feb 08 '18 at 19:24
  • 2
    Welcome to Stack Overflow! Please take the [tour], look around, and read through the [help], in particular [*How do I ask a good question?*](/help/how-to-ask) Assignments aren't usually arbitrary; your instructor, tutorial, or course will have covered the necessary topics to make it possible for you to do this. **Review your course materials, class notes, etc.,** and try to do the work. *If* you run into a *specific* problem, research it thoroughly, [search thoroughly here](/help/searching), and if you're still stuck post your code and a description of the problem. People will be glad to help. – T.J. Crowder Feb 08 '18 at 19:25
  • Might be enums, might just be instances of a (non-enum) class. – T.J. Crowder Feb 08 '18 at 19:26
  • 2
    *(Trying to figure out what `METER.fromMetric` and `METER.toMetric` would do...)* – T.J. Crowder Feb 08 '18 at 19:27
  • Yeah I get that. But the assignment clearly states that I am to create a class called DiatanceUnit and that it should contain a constructor DistanceUnit(double metersPerUnit) and the the constants PLANCK, METER, FOOT and PARSEC and have been given a table with values to use for them – Niklas Westerberg Feb 08 '18 at 19:28
  • I don't know if I've posed the question in a poor manner. But my issue is that I don't get how I am supposed to write a method like: public double toMetric(double input) { return "constant that called the mathod" * input; } – Niklas Westerberg Feb 08 '18 at 19:33
  • Whereas I concur that `DistanceUnit` looks like an enum, more generally, you can invoke methods only on objects, so `DistanceUnit.METER` must be objects. That is not inherently inconsistent with Java code conventions. (And Java enum values are objects, and they can have arbitrary methods.) – John Bollinger Feb 08 '18 at 19:33
  • @NiklasWesterberg The thing is that your *constants* like `METER` are not supposed to be primitives, they are **not** `double`. Instead they all are objects. And objects can have methods. And probably all those objects have a member variable that defines the scale of the unit which is then used in the given method. Take a look at the answer of @tsolakp, it is a full code example. – Zabuzard Feb 08 '18 at 20:22

3 Answers3

3

Keep in mind: methods exists on classes. Yes, you can define methods on interfaces, too - but the point is: you can invoke methods only on objects, or on classes (when they are static).

In that sense, you have to first figure the type of your CONSTANT. In other words: you first have to understand that "CONSTANT" simply refers to some object that has a certain name.

And from there: you already defined somehow the type of that object named CONSTANT. And when you want to invoke methods on objects of that type, you have to add them to that type.

In other words, assuming that you have something like:

class DistanceUnit {
  public final static Foo METER = new Foo(...);

you would need

class Foo {
  public static String fromMetric(int value);

for example.

And just for the record: it doesn't really matter whether DistanceUnit.METER refers to a static field within a class, or to an enum - your todo is the same: that type that METER represents needs the corresponding methods. And in case you don't understand the difference between these concepts, start reading here for enums and there for static fields.

GhostCat
  • 137,827
  • 25
  • 176
  • 248
  • public static final double METER = 1; public static final double FOOT = 0.3048; public static final double PARSEC = 3.08567758 * Math.pow(10, 16); public static final double PLANCK = 1.616229 * Math.pow(10, -35); This is my declaration of the constants in the class DistanceUnit. I might be way off here but is what you saying that the primitive type double has to have the methods? – Niklas Westerberg Feb 08 '18 at 19:52
  • Can you read the code you put into this comment? Really? Please enhance your question accordingly instead of providing more information in comments like this! And what I am saying is : the type of METER must be a type to which you can add methods. Because you own that type! thus you cannot use double here. All the information you need is already written in my answer! – GhostCat Feb 08 '18 at 20:13
  • No, primitives like `double` don't have methods that you can call on them. However you can define classes as *constants* too, not only primitives. The term *constant* usually only refers to something being `static` and `final`. – Zabuzard Feb 08 '18 at 20:15
  • @Zabuza - You cannot mark an object as constant in Java using the `static` and `final` qualifiers. They affect only the *reference* to an object. – Andy Thomas Feb 08 '18 at 20:18
  • @AndyThomas Yeah, of course I meant that. But thanks for clarifying if someone didn't knew. – Zabuzard Feb 08 '18 at 20:19
2

The comments and the answer from @GhostCat should be all you need to implement those constants but I have feeling that you are still thinking about constants in terms of primitives/strings and not as objects. In java constants can also reference any objects.

Here is example for METER and FOOT implementation using interface and concrete implementations:

    public class DistanceUnit{
        public static final Converter METER = new MeterConverter();
        public static final Converter FOOT = new FootConverter();
    }


    public interface Converter{

        public double fromMetric(double d);

        public double toMetric(double d);       
    }

    public class MeterConverter implements Converter{

        @Override
        public double fromMetric(double d) {
            return d;
        }

        @Override
        public double toMetric(double d) {
            return d;
        }        
    }

    public class FootConverter implements Converter{

        @Override
        public double fromMetric(double meters) {
            return meters*3.28084;
        }

        @Override
        public double toMetric(double feet) {
            return feet*0.3048;
        }        
    }

There is better way to do this by replacing DistanceUnit with enum but I am leaving it to you as an exercise.

tsolakp
  • 5,858
  • 1
  • 22
  • 28
0

A single enum is sufficient. Java enum constants are objects. You can call methods on them.

Standard style is to uppercase the enum constants.

You only have to write toMetric() and fromMetric() once.

public enum DistanceUnit {
   METER( 1.0 ),
   FOOT( 0.3048 ),
   ...
   ;

   private m_distanceInMeters;

   DistanceUnit( double distanceInMeters ) {
     ...
   }

   public double fromMetric(double d) {
     ...
   }

   public double toMetric(double d) {
     ...
   }
}
Andy Thomas
  • 84,978
  • 11
  • 107
  • 151