Domanda

Here is a program taken from the SCJP 6 example. Here, we create a enum with different coffee sizes, and declare a private variable called ounces to get the ounce value part of enumeration.

I was not able to understand the use of getLidCode method which is overriden. How would one access the getLidCode method?

package com.chapter1.Declaration;

enum CoffeSize {
    BIG(8), HUGE(10), OVERWHELMING(20) {
        public String getLidCode() {
            return "B";
        }
    };

    CoffeSize(int ounce) {
        this.ounce = ounce;
    }

    private int ounce;

    public int getOunce() {
        return ounce;
    }

    public void setOunce(int ounce) {
        this.ounce = ounce;
    }

    public String getLidCode() {
        return "A";
    }
}

public class Prog7 {

    CoffeeSize size;

    public static void main(String[] args) {

        Prog7 p = new Prog7();
            p.size = CoffeeSize.OVERWHELMING;

            System.out.println(p.size.getOunces());

            //p.size.getLidCode(); ? is this correct way
        }
    }
È stato utile?

Soluzione

It makes more sense if you space it out a bit more:

enum CoffeSize {
    BIG(8),
    HUGE(10),
    OVERWHELMING(20) {
        public String getLidCode() {
            return "B";
        }
    };
    // rest of enum code here
}

Only OVERWHELMING is overriding getLidCode().

You would access it via this approach (using your code):

System.out.println(p.size.getLidCode());

The reason for this: p.size is type CoffeSize, of which it has the method getLidCode(). It will print the value of the overridden method, as expected.

Altri suggerimenti

I am not overly familiar with enum's, but I believe the answer to your question is this:

There are two types of Lids, Lid A and B. Since B is right after the third declaration of standard sizes of coffees (OVERWHELMING), whenever getLidCode() is called on an CoffeeSize, and it matches 20, it will return Lid B. If there are any other, manually set, sizes, such as 12 or 14, or BIG or HUGE, it will return A.

So basically, Lid B means it's a standard lid for overwhelming coffees. If a customer asks for a 12 ounce, or 18 ounce, or any other ounces of coffee, or for a BIG or HUGE coffee, they get a Lid A.

In conclusion:

 p.size = CoffeeSize.BIG;
 System.out.println(p.size.getOunces()); // Outputs "8"
 System.out.println(p.size.getLidType()); // Outputs "A"

 p.size = CoffeeSize.OVERWHELMING;
 System.out.println(p.size.getOunces()); // Outputs "20"
 System.out.println(p.size.getLidType()); // Outputs "B"

 p.size = CoffeeSize(12);
 System.out.println(p.size.getOunces()); // Outputs "12"
 System.out.println(p.size.getLidType()); // Outputs "A"

 p.setOunce(20);
 System.out.println(p.size.getOunces()); // Outputs "20"
 System.out.println(p.size.getLidType()); // Outputs "B"

Method getLidCode normally returns constant "A". For CoffeSize.BIG and CoffeSize.HUGE, it is not overriden, so this is the value they will return. However, for CoffeSize.OVERWHELMING it's overriden and it will return "B".

If you think of enums as classes and their enum values as instances of that class, enums allows method overriding on a per-object basis. This is not possible with regular classes/objects.

This could also have been implemented as:

enum CoffeSize {
    BIG(8,"A"), HUGE(10,"A"), OVERWHELMING(20,"B");

    CoffeSize(int ounce,String lidCode) {
        this.ounce= ounce ;
        this.lidCode= lidCode ;
    }

    private int ounce;
    private String lidCode;

    public int getOunce() {
        return this.ounce ;
    }
    public void setOunce(int ounce) {
        this.ounce= ounce ;
    }
    public String getLidCode() {
        return this.lidCode ;
    }
}

Note that to make this alternate implementation more equivalent to the original one, no setLidCode method was defined.

The true power of this mechanism can be appreciated more easily in the following example, though:

enum BinaryOperation {
    ADDITION("+",1) {
        public double operate(double a,double b) {
            return a + b ;
        }
    },
    SUBTRACTION("-",1),
    MULTIPLICATION("*",2) {
        public double operate(double a,double b) {
            return a * b ;
        }
    },
    DIVISION("/",2),
    POWER("**",3);

    BinaryOperation(String repr,int priority) {
        this.repr= repr ;
        this.priority= priority ;
    }

    private String repr;
    private int priority;

    public String toString() {
        return this.repr ;
    }
    public int getPriority() {
        return this.priority ;
    }
    public double operate(double a,double b) {
        throw new UnsupportedOperationException() ;
    }
}

SUBTRACTION, DIVISION, and POWER will throw an exception when their operate method is invoked (for some reason, only commutative operations have been implemented at this point). However, BinaryOperation.ADDITION.operate(3.5,2.1) and BinaryOperation.MULTIPLICATION.operate(4.5,2.0) will return the expected values (5.6 and 9.0 respectively). This also answers your question about usage. Yes, your tentative example is correct.

There is no simple OO way of implementing this using fields or other mechanisms.

Note that it is getOunce and not getOunces . The following is the correct usage .

public class Prog7 {

CoffeSize size;

public static void main(String[] args) {

Prog7 p = new Prog7 ();
p.size = CoffeSize .OVERWHELMING;

System.out.println(p.size.getOunce());

System.out.println(p.size.getLidCode());

}

}

This would give the output as :

20

B

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top