8

I am currently making a text based adventure in Java for the purposes of using it a test platform, to try out new things I learn from this Java book I'm reading.

I am now trying to declare an instance of a subclass (as the player is scripted to find it). The parent class is Item and it has two subclasses: Weapon and Armour.

However, no matter which way I try and declare it in, the IDE I'm using (Eclipse) flags the line with the following error:

No enclosing instance of type Item is accessible. Must qualify the allocation with an enclosing instance of type Item (e.g. x.new A() where x is an instance of Item).

When I attempt to declare it like any of the following:

Item machinePistol = new Weapon(); 
Weapon machinePistol = new Weapon();
Item machinePistol = new Item.Weapon();
Weapon machinePistol = new Item.Weapon();

For reference the item class looks like this:

package JavaAIO;

public class Item 
{
    public String itemName;
    public double itemWeight;

    public class Weapon extends Item
    {
        public double damage;
        public double speed;
    }
    public class Armour extends Item
    {
        public double dmgResist;
        public double attSpdMod;    
    }
}

So if anyone could tell me how I could properly instantiate a Weapon (so I can set the values of its fields and give it to the player), I would greatly appreciate it.

Gary
  • 13,303
  • 18
  • 49
  • 71
James
  • 215
  • 1
  • 2
  • 7
  • This should be handy as well: http://download.oracle.com/javase/tutorial/java/javaOO/nested.html – Bad Request Dec 10 '10 at 20:46
  • Thanks for that, also thanks to Wesley for editing my code snipet so it looks right. – James Dec 10 '10 at 20:59
  • Possible duplicate of [Java - No enclosing instance of type Foo is accessible](http://stackoverflow.com/questions/9560600/java-no-enclosing-instance-of-type-foo-is-accessible) – fabian Mar 04 '16 at 00:34

3 Answers3

13

"No enclosing instance of type Item is accessible. Must qualify the allocation with an enclosing instance of type Item (e.g. x.new A() where x is an instance of Item)."

It's pretty self-explaining:

Item machinePistol = new Item().new Weapon(); 

Or:

Item item = new Item();
Item machinePistol = item.new Weapon(); 

However, I strongly recommend to put them in their own classes so that you can end up with:

Item machinePistol = new Weapon();
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • This works too, but why do you strongly reccomend to put them in their own classes? – James Dec 10 '10 at 20:44
  • So that you can create a weapon without the unnecessary overhead to create an item first. Also, inner classes are generally supposed to used by their parent (sub)class exclusively. If they are ever used outside, then it's high time to refactor them into their own classes. – BalusC Dec 10 '10 at 20:46
  • Declaring the inner classes `static` also avoids the extra overhead (allowing you to instantiate them with `new Item.Weapon()` - which @Joel shows very nicely in his answer). Still I agree that in this case, it would be better to put them in their own scope. – Levite Dec 16 '14 at 10:34
6

To do this:

Item machinePistol = new Item();
Weapon machinePistol = new Item.Weapon();

you would want to declare your inner classes as static:

 public static class Weapon extends Item
 {

  public double damage;
  public double speed;

 }

 public static class Armour extends Item
 {
  public double dmgResist;
  public double attSpdMod; 

 }

Or another (and better) option is to not make them inner classes:

public class Item {}
public class Weapon extends Item {}
public class Armour extends Item {}

Then you can make them like this;

Item machinePistol = new Item();
Item machinePistol = new Weapon();
Item someArmour = new Armour();
Joel
  • 16,474
  • 17
  • 72
  • 93
1

You shouldn't declare the classes Weapon and Armour inside Item. Just declare them outside:

public class Item {
    public String itemName;
    public double itemWeight;
}

public class Weapon extends Item {
    public double damage;
    public double speed;
}

public class Armour extends Item {
    public double dmgResist;
    public double attSpdMod;
}

So you can instantiate them like this:

Weapon machinePistol = new Weapon();
Hosam Aly
  • 41,555
  • 36
  • 141
  • 182
  • I tried that too but it just says "The public type Armour must be defined in its own file" – James Dec 10 '10 at 20:41
  • 1
    @James Yes, you should have a file for each of the three classes you are defining since they are not inner classes. – unholysampler Dec 10 '10 at 20:45
  • Right, i am going to a combination of this, and what some of other answers have said, many thanks you guys are very quick to answer! – James Dec 10 '10 at 20:52