5

I've been trying to learn Java and I'm working on a project.

I have an abstract class called Card that I'm using as a template to make sub-classes.

It has a method to set the name field and color field of the card and a method to set the cost.

I have a subclass of Card called Workshop.

I'm trying to use the methods of Card in Workshop to set the name and color fields of Workshop.

To do so, I'm calling the methods super.setCardNameColor("Workshop", "Green") and super.setCardCost(0,0,0,0,0,0,0,0);

However, in order to do this Eclipse in making me use (what appears to be) double curly braces in the class declaration.

I suspect this has something to do with Anonymous Inner Classes, perhaps from calling 'super' or something like that, but none of my Google searches are giving me the information I need. Can anyone shed some light on the subject here? I'm using sysout and getters to make sure that the values are being set correctly on an instance of Workshop, but I'm baffled by the double braces. Thank you ahead of time for your help!

Edit: here is the code

public abstract class Card
{
    private String cardName = "";
    private String cardColor = "";
    private int coinCost = 0;
    private int woodCost = 0;
    private int brickCost = 0;
    private int stoneCost = 0;
    private int oreCost = 0;
    private int glassCost = 0;
    private int clothCost = 0;
    private int paperCost = 0;

    private int coinValue = 0;
    private int pointValue = 0;
    private int millitaryValue = 0;
    private int woodValue = 0;
    private int brickValue = 0;
    private int stoneValue = 0;
    private int oreValue = 0;
    private int glassValue = 0;
    private int clothValue = 0;
    private int paperValue = 0;

    private Card discountForCard;
    private Card discountFromCard;

    public void setCardNameColor(String cardName, String cardColor) {
        this.cardName = cardName;
        this.cardColor = cardColor;
    }

    public void setCardCost(int coinCost, int woodCost, int brickCost,
            int stoneCost, int orecost, int glassCost, int clothCost,
            int paperCost) {
        this.coinCost = coinCost;
        this.woodCost = woodCost;
        this.brickCost = brickCost;
        this.stoneCost = stoneCost;
        this.oreCost = orecost;
        this.glassCost = glassCost;
        this.clothCost = clothCost;
        this.paperCost = paperCost;
    }

    public void setCardValue(int coinValue, int millitaryValue, int pointValue,
            int woodValue, int brickValue, int stoneValue, int oreValue,
            int glassValue, int clothValue, int paperValue) {
        this.coinValue = coinValue;
        this.millitaryValue = millitaryValue;
        this.pointValue = pointValue;
        this.woodValue = woodValue;
        this.brickValue = brickValue;
        this.stoneValue = stoneValue;
        this.oreValue = oreValue;
        this.glassValue = glassValue;
        this.clothValue = clothValue;
        this.paperValue = paperValue;
    }

    public void getCardInfo() {
        System.out.println(cardName + cardColor + coinCost + woodCost+brickCost+stoneCost+oreCost+glassCost+clothCost+paperCost);
    }

    public void setGivesDiscountTo(Card card) {
        card = discountForCard;
    }

    public void setReceivesDiscountFrom(Card card) {
        card = discountFromCard;
    }

    public String getCardName() {
        return cardName;
    }
}


public class Workshop extends Card
{
    {
        super.setCardNameColor("Workshop", "Green");
        super.setCardCost(0, 0, 0, 0, 0, 1, 0, 0);
    }
}
Clashsoft
  • 11,553
  • 5
  • 40
  • 79
Qumbaala
  • 253
  • 4
  • 14

1 Answers1

13

The inner braces in the "double curly braces" are initializer blocks. (Think of them as a constructor.)

<class name> {       // class declaration
    {   // initializer block
        ...
    }
}

See for instance What is an initialization block?.

Since you can't put statements ("code") directly in a class declaration, like this:

new YourClass() { System.out.println("hello"); }

you experience that "Eclipse makes you use double curly braces" because the following

new YourClass() {{ System.out.println("hello"); }}

makes the statement go in the initializer block with is valid code.


Regarding your edit: Your problem is here:

public class Workshop extends Card {{
    super.setCardNameColor("Workshop", "Green");
    super.setCardCost(0, 0, 0, 0, 0, 1, 0, 0);
}} 

This isn't very common style of programming. Perhaps you're after:

public class Workshop extends Card {
    public Workshop() {
        setCardNameColor("Workshop", "Green");
        setCardCost(0, 0, 0, 0, 0, 1, 0, 0);
    }
}
Community
  • 1
  • 1
aioobe
  • 413,195
  • 112
  • 811
  • 826
  • 1
    Not really. The outer ones are the braces that define the body of an anonymous class, and the inner ones define an initializer block. – JB Nizet Feb 15 '15 at 21:30
  • 1
    Answer reworded. Thanks JB Nizet. – aioobe Feb 15 '15 at 21:32
  • I always forget that you cannot put code directly in a class. It feels weird because you do exactly that when your defining member fields and methods, but I supposed that declaring them and prefacing them with access modifiers and return types make that acceptable. – Qumbaala Feb 15 '15 at 21:40
  • 1
    @DavidEhrmann, refer to the link in my answer for the difference between static initializer and instance initializer. – aioobe Feb 15 '15 at 21:41
  • @David No. Static initializer blocks are only executed once and are very much more useful than initializer blocks (if you need those you probably have a flaw in your class design). – Voo Feb 15 '15 at 21:41
  • I've looked at the link. This seems to be exactly what Eclipse is suggesting. Thank you for your answer, you have broadened my understanding of the language :D – Qumbaala Feb 15 '15 at 21:43
  • [Why this these initialization blocks can be bad](http://stackoverflow.com/questions/924285/efficiency-of-java-double-brace-initialization) – Obicere Feb 15 '15 at 21:44
  • Wow, I never thought to just assign the value inside the default constructor. I've done something like that before, but it didn't occur to me in this case. Again, you've helped me reformat the way I'm thinking about the problem and the language in general. Thank you greatly! This is exactly why learning by doing is the best kind of learning! – Qumbaala Feb 15 '15 at 21:57
  • 1
    @Qumbaala executable code cannot be directly inside a class - which makes sense, because when would it run? Field initializers are actually moved to the constructor by the compiler (or the static initializer, for static fields). Field and method declarations are not executable (even though methods contain executable code). – user253751 Feb 15 '15 at 22:16