Possible to make an enum of anonymous inner classes?

So make a simple weapon system.

Disclaimer I’m no Java guy but I’d do…

IWeapon {
Some behaviours here like shoot or load, etc
}

Weapon : IWeapon {
Some common functions for all weapons

//virtual shoot() : spawn a simple bullet based on some data file (speed, effect, sound, damage)
}

//Weapons are data driven
standardWeapon = new Weapon(DATA FOR THE WEAPON)
flamerWeapon = new Weapon(DATA FOR THE WEAPON)

//Only need a sub class when BEHAVIOUR is different
ShotgunWeapon : Weapon {
//Override shoot() to spawn x many bullets in an arc - randomise pellet speed
}

Something::setWeapon(IWeapon newWeapon) {
etc
}

Ah, but it is. Parametrizing a single effect type was simply an example.

If I understand correctly, you want to be able to define various types of weapons and new behaviors for them at runtime? If so you could do something like below.


interface Weapon {
    void fire(...);
 
    void reload(...);
}

class DefaultWeapon implements Weapon {
    
    private final WeaponMetaData meta;

    public DefaultWeapon(WeaponMetaData data /* type specific data such as bullet style, speed, etc. */) { this.meta = data; }

    void fire(...) {
    } // fire off a single bullet for default behavior

    void reload(...) {
    }
}

class FlamethrowerWeaponImpl extends DefaultWeapon {
 
    public FlamethrowerWeaponImpl(WeaponMetaData meta) {
        super(meta);
    }   

    @Override
    void fire(...) {
    } //do what has to be done for a specialized implementation.
}

This way you can create specialized implementations for weapons that don’t follow the standard “spawn an accelerated particle” behavior.


static Weapon PISTOL = new DefaultWeapon(pistolMetaData);
static Weapon RIFLE = new DefaultWeapon(rifleMetaData);
static Weapon FLAMETHROWER = new FlamethrowerWeaponImpl(flamethrowerMetaData);

Well at least you get it… but the whole point of this was I don’t want to have to create 20 different classes for 20 different weapon types. Meanwhile, everyone else still thinks I mean I want different parameters to define damage, speed, etc…

The only cases which you would need to define a different class is if you need a weapon which implements non-standard behavior (standard defined as whatever is in DefaultWeapon.) What the others were saying is that if you feed the default implementation enough data then you won’t need to create specialized implementations. For example, I have a class named DefaultWeapon which fires a single shot and a specialized implementation named SpreadShotWeapon. I can eliminate the need for SpreadShotWeapon type if I introduce three new parameters: angle, particle count and shot type.

You don’t have to create 20 different classes - you only create a NEW CLASS when you need BEHAVIOUR that is different.

Right, but the amount of classes I’ll need is equivalent to the number of uniquely different weapons, which is a lot, considering the behavior of a machine gun, flamethrower, rocket launcher, and shotgun are all different. Besides… how do you know how many different weapon types I’ll have?

Try do components object : (crazy and flexible ^^)


	class Bullet_Dmg implements Bulet_Procces {
		int Dmg;	
		public Bullet_Dmg(int dmg){
			Dmg = dmg;
		}
		
	    @Override
        public void update(){
    		if(bulet hit do damage)
        }
	    public Bullet_Dmg set_Dmg(int dmg){Dmg = dmg;return this;}
	}
	class Bullet_Heal implements Bulet_Procces {}
	class Bullet_Time_Explode implements Bulet_Procces {}
	
	class Weapon_Pistrol_Graphics implements Weapon_Graphics {
        @Override
        public void draw(Graphics g2d) {
            // draw each particle in the particles list
        }
	}
	class WeaponObj{
		Bulet_Procces proc;
		Weapon_Graphics graph;
		
		public WeaponObj(Bulet_Procces Proc, Weapon_Graphics Gra(){
			proc = Proc;
			graph = Gra;
		}
        public void draw(Graphics g2d){
        	graph.draw(g2d);
        }
        public void update(){
        	proc.update();
        }
		
		public WeaponObj set_New_Proc(Bulet_Procces Proc){proc = Proc; return this;}
	}
	
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////	
	Bullet_Dmg pistol_Bullet = new Bullet_Dmg(10);
	Weapon_Pistrol_Graphics pistol_GR = new Weapon_Pistrol_Graphics();
	
	WeaponObj pistol = new WeaponObj(pistol_Bullet, pistol_GR);
	
	Bullet_Heal pistol_Bullet_2 = new Bullet_Heal(30);
	pistol.set_New_Proc(pistol_Bullet_2);
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////	

Not necessarily. If the standard weapon behaviour is to fire (a) number of (b) projectiles, in an arc from -© to +© radians with a reload factor of (d) milliseconds then they’d all have the same BEHAVIOUR wouldn’t they. But your data would be different - that is the point.

I already know HOW to make an anonymous inner class to implement the weapons the way I want… the only reason I asked this was to determine if I could somehow put the declarations for these in a separate file and be able to just import them and use an ID to refer to the object without cluttering up my main code.

I understand exactly what you’re saying, except perhaps the “scale” of different behaviors. The “scale” does have an effect in terms of a reasonable abstraction vs. engineering time.

Exactly…you only need a new class when a behavior cannot (or isn’t worth) making data-driven.

Again, exactly data-driven design is your friend.

With no notion of scale this is a difficult question to answer…and most likely few of us would agree on what the cleanest solution is.

/*****************/
File 1 – bullets :
Arraylist list
Bullet 1 – id 1
Bullet 2 – id 2

get_By_ID(int id_Find){
for Arraylist
Object obj = list.get(i)
if(id_Find == obj.id)
return obj
}
get_By_Name(String name_Find)
if(name.equals(name_Find)) //Not lf(name == name_Find) Dont do that // Obj == obj - memory address !!!
//…
/*****************/
File 2 – Graphicks :
//…

/*****************/
File 3 - weapon
new Weapon(1, 15); //Weapon bullet - id 1, Graphicks Id -15
new Weapon(“Pistol_1”, “Pistol_2”); //Weapon bullet Name - Pistol_1, Graphicks Name - Pistol_2

I’m going to make one last attempt to get my point across in case anyone is still confused. I wrote a prototype Weapon class similar to what I was looking for. Instead of using an enum, I made a class called “WeaponType” with public members containing the anonymous inner class objects. Note that what the fire() method does in this example is irrelevant. It’s to demonstrate what I meant.

Main Class: http://pastebin.com/MYewSQgv
Weapon Class: http://pastebin.com/kAJrpVGL
Weapon Interface: http://pastebin.com/MQyv1nzC
Weapon Type Class (Contains anonymous inner classes): http://pastebin.com/QbFuLyMy

I hope I got the point across this time.

You can do this:


enum WeaponType {

    FLAMETHROWER(...) {
        void fire(Point2D target) {}
    },
    
    PISTOL(...) {
        void fire(Point2D target) {}
    };

    private WeaponType(...) {}
    
    abstract void fire(Point2D target);
}

@Icecore
I would recommend using a code tag if you really don’t want to avoid clutter.

You’re still creating a new subclass for every type of weapon you define, you’ve just stripped them of meaningful names – they’ll show up in tracebacks and toString and so on as WeaponType$1 and WeaponType$2 instead of Pistol and Flamethrower. I just don’t see what that buys you. Wanting to avoid lots of subclasses is a laudable goal, but you’re not going to get there by making them anonymous, you only really get it through composition of traits.

You could also use the enum syntax sugar described above, where you will at least get meaningful names, but that does statically restrict your set of weapons at compile-time – that’s kind of the point of enums in general. So enums also won’t really buy you anything.

It sounds to me like maybe you want to be able to introduce new weapons on a “plug-in” basis by having different jars declare “here are my implementations of WeaponInterface”. For that, you’ve got SPI, but that’s a whole new rabbit hole which isn’t worth going down here, unless I know that’s exactly what you want to do.

I read this entire thread, and I must say that what you are trying to achieve with enums is very wasteful. Chances are that the weapons list is going to grow, and some weapons are going to share types and firing patterns.

Eventually, you are going to have to code each type of firing pattern and weapon behavior in the game. Wouldn’t a better solution be to make a WeaponPattern and WeaponBehavior subset? Then a generic Weapon class that uses those 2 features can be created.

You can only have so many Weapon Behaviors and Firing Patterns. So instead of focusing on the weapon enumerations, you can instead focus on the Behaviors and Pattern. If each weapon can only have 1 firing pattern and 1 behavior, you should be able to dramatically reduce the amount of classes you need.


public class Weapon(){

        private String weaponName;
        private WeaponBehavior behavior;
        private WeaponPattern pattern;

        Weapon(String name, WeaponBehavior behavior, WeaponPattern pattern){
               //Initialize weapon here
        }

        public void fire(){
               //This weapon fires
        }
} 


Since your beginning goal was to not use a different class for each weapon, you can use one Weapon class to determine the firing pattern and behavior for all weapons. Enumerations will just have you write a lot of extra code regardless, and all you’ll achieve is a Weapon ID.

As a sanity check note that all of this is an utter waste of time if your number of weapons is small. Just make a single class per weapon and move on to the next thing. Otherwise all the the useful comments are saying the exact same thing and are simply using different constructions and different levels of data segregation. Be data-driven and use composition.