Java: Referring to a Class inside its own method - java

I am working on an assignment that I'm trying to debug currently. I have numerous error: (method name) in class (SuperClass Name) cannot be applied to given types;. The project is repurposing a game centered around Procedural programming to the same game, but now around OOP. I'm new to Java and have been tasked with creating numerous Classes, two of which are subclasses to a Superclass (obviously), and I have been given what methods to have and their parameters. The problem I am having is that one method in a subclass is supposed to control a battle between two characters, the player and an enemy. Both of these classes are the subclass to the character class (superclass). Since this is a class assignment, I don't want to post everything that I have, but below is an example of the battle method I'm trying to perform. The problem I'm experiencing, and continue to have with "inheritance" in general, is exactly what is inherited between parent/child classes and how to pass certain values/variables between each of them.
In the example code below, this method is nested within the Player class that extends a Character class. This method needs to use and enemy from the Enemy class and perform the actions within. Depending on the outcome, I pass back a boolean to the main method of my program.
My problem is this; I'm unsure how to call a class that has been made "Player" class in this example, within a method that is already contained under the "Player" class. I was asked to use one argument for the method when called, Enemy. I'm positive that I'm not approaching this particular assignment in the appropriate way and there is a much better way to deal with this. But any help to understand what is possible is much appreciated as it will help me approach this assignment in the correct way.
Sample Method from the Player class is as follows:
public abstract class Character{ //Character Superclass - attack method called
public int attack(Player _player){
Random randomNumbers = new Random();
int enemyRandAtk = randomNumbers.nextInt(Weapon.getMaxDamage - Weapon.getMinDamage) + Weapon.getMinDamage;
int enemyAtk = enemyRandAtk + getStrength();
int charRemainingHP = _player.getHitPoints() - enemyAtk; //can I call _player in the Character class????
System.out.printf("%s attacks with ATK = %d + %d = %d\n", getName(), getStrength(), enemyRandAtk, enemyAtk);
System.out.printf("%s HP is now %d - %d = %d\n\n", _player.getName(), _player.getHitPoints(), enemyAtk, charRemainingHP);
return charRemainingHP;
}
public class Player extends Character{
public int attack(Enemy _enemy){
Random randomNumbers = new Random();
int enemyHP = _enemy.getHitPoints();
int charRandAtk = randomNumbers.nextInt(Weapon.getMaxDamage - Weapon.getMinDamage) + Weapon.getMinDamage;
int charAtk = charRandAtk + getStrength();
int enemyRemainingHP = _enemy.getHitPoints() - charAtk;
System.out.printf("\n\n%s attacks with ATK = %d + %d = %d\n", getName(), getStrength(), charRandAtk, charAtk);
System.out.printf("%s HP is now %d - %d = %d\n\n", _enemy.getName(), enemyHP, charAtk, enemyRemainingHP);
return enemyRemainingHP;
}
public boolean battleWizard(Enemy _enemy){
Random randomNumbers = new Random();
Scanner userInput = new Scanner(System.in);
int spellCast = randomNumbers.nextInt(4) + 1;
System.out.printf("*** %s vs The Evil Wizard ***\n\n", getName()); //getName() is in Player Class
boolean charWinning = false;
int updWizHP = _enemy.getHitPoints(); //****** Question 1. below
do{
System.out.print("Choose your action: \n" +
"1. Attack\n" +
"2. Attempt Spell Cast\n\n" +
"What would you like to do?: ");
int battleDecision = userInput.nextInt();
if (battleDecision == 1){
updWizHP = Player.attack(_enemy); //**** Question #2 Below
if (updWizHP <= 0){
charWinning = true;
break;
}
}else if(battleDecision == 2){
System.out.print("Enter your guess: ");
int playerGuess = userInput.nextInt();
if (playerGuess == spellCast){
System.out.printf("The %s's spell is cast successfully! The Wizard's HP is now 0!\n\n", getName());
charWinning = true;
updWizHP = 0;
break;
}else{
System.out.print("Your spell missed the Wizard. Now he attacks!\n");
}
}
if (getHitPoints() > 0){
enemyDamage = Enemy.attack();
decreaseHitPoints(_enemy.attack(Player)); \\**** Question #3 below
if (getHitPoints() < 0){
charWinning = false;
break;
}
}
}while(getHitPoints() > 0 && _enemy.getHitPoints() > 0);
if (charWinning)
return true;
else
return false;
}
}
Please keep in mind that this is a method within a subclass (Player) that holds roughly the same methods as (Enemy) short of this one and a few others.
In terms of my code above, here are my specific questions:
Line 6 in method battleWizard (#1 Question in notes) - Since this method resides in the Player class, can I reference the Enemy class in this way? If not, what is a better way of doing so?
Line 12 in method battleWizard (#2 Question in notes) - How can I reference a class that has an object created in it's own name when the method (code example) is in the class itself? I'd like to take the end-user's player player and reference that object within itself, if that makes sense? I am trying to visualize how the compiler will perform this task and can't imagine this ever working.
13 Lines from the bottom (#3 Question reference in notes):
a) can you pass a method as a parameter to another method like this in Java?
b) is the proper way to invoke another subclass (same subclass level as the one calling the class) like this or is it even possible?
Thank you for the help. As I mentioned before, since this is a class assignment I'd prefer not to provide more samples of my code. But inevitably, if it helps me to understand then I will. Please let me know what further information you need.
ETA:
I added additional code to portray the relationship between the super and subclasses. For the Enemy subclass, it relies on the Character superclass for the attack method. So in my code example above, I hope that it clarifies 3.b. of my question. Any further information required, please let me know.

You are getting compilation errors because you defined attack(Player _player) which means you are allowing only Player objects to be passed but you are using like Player.attack(_enemy) which means passing Enemy object.
You need to correct this. Read my para, "As an aside...".
Line 6 in method battleWizard (#1 Question in notes) - Since this
method resides in the Player class, can I reference the Enemy class in
this way? If not, what is a better way of doing so?
As per your code sample, int updWizHP = _enemy.getHitPoints(); is a valid and sensible call if you want to get the hit points of the enemy. _enemy is your Enemy object and you can all any method on it as long as that method exists in that class.
Line 12 in method battleWizard (#2 Question in notes) - How can I
reference a class that has an object created in it's own name when the
method (code example) is in the class itself? I'd like to take the
end-user's player player and reference that object within itself, if
that makes sense? I am trying to visualize how the compiler will
perform this task and can't imagine this ever working.
Since Player is extending Character, so you would have attack method inherited in Player class (visualize this is as defining attack method in Character class). So, you really don't need to use updWizHP = Player.attack(_enemy); but you can simply use updWizHP = attack(_enemy);. However, this is a compilation error, read my first and last portion of answer.
Now, since attack method is not using any instance field of Player class (state of the Player class) so you need not to worry but if it was then you had to think and decide that on which Player class object you want to call your attack method.
13 Lines from the bottom (#3 Question reference in notes): a) can you
pass a method as a parameter to another method like this in Java? b)
is the proper way to invoke another subclass (same subclass level as
the one calling the class) like this or is it even possible?
For #3.a: Using decreaseHitPoints(_enemy.attack(Player)); you are not passing method to another method BUT first _enemy.attack(Player) will be evaluated and as your code an int would be returned and that value will be passed to decreaseHitPoints.
For #3.b: You are not invoking any sub-class but you are calling method on a object, it doesn't matter if the class that object represent lies in the inheritance tree or not. Only thing you need to make sure that it is a logical call and that method exists in the class.
I guess _enemy.attack(Player) will give you compilation error because you are not defining Player as an object reference variable. You have to use some variable, cannot use class name like this. Better use _enemy.attack(this)
_enemy.attack(Player) this suggests that in attack method you want to pass an Player object, now either you use _enemy.attack(this) which means pass on current object on which battleWizard is getting called (make sense) or use _enemy.attack(new Player()) which means create a new object of Player class and pass that one.
As an aside, I think you better be defining public int attack(Player _player){ as public int attack(Character _character){ because like this in future you can use attack method to pass an Enemy object or some sub-class of Character
That's the beauty of "Inheritance" and "Program to interface". I would recommend you to search and learn about these 2 concepts.
Few quick notes for you, may be you will be aware (these are general notes trying to expose the topic/concept, there could be more limiting behavior, so please read more on each topic/concept):
An object is a runtime representation of a class.
Methods of super class are inherited by sub-class, and to call them you need not to use an object, if you are calling from same class. Visualize this as defining that method in same class (read more on inheritance in context public v/s protected v/s private methods).
You can override the inherited methods.
A method accepting a super type can be invoked with object of any of its subclass. For example, in your case giveMeAnyCharacter(Character char) can be used as giveMeAnyCharacter(new Person()) or giveMeAnyCharacter(new Enemy()).
In Java this means current object or instance and super means super class. So, either create a new object or if you want to use the same object on which you are presenting working then use this.
Always put your all common code (method or instance fields) in super class and let sub-classes take advantage of it using inheritance.

So, Java has "visibility" for methods and fields (and classes too), that defines what exactly is visible to an other class. Look up f.e. JLS 6.5.7.1-1, Simple Method Names and Visibility.
However, in your case "cannot be applied to given types" implies that you pass to a method different parameter types than what the signature says.
Still, for question 2, you just write this.attack(_enemy), or simply attack(_enemy). (BTW, what's with the underscores? I hope it's an artifact from the conversion and not something in your style guide)
Question 3: just use _enemy.attack(this).
BTW, you have your OO terminology mixed up - one passes instances of classes around.

Your question is quite unclear, but I think the problem is your lack of terminology as well as a lack of understanding. I'll try a few pointers for you:
Line 6 in method battleWizard - Since this method resides in the
Player class, can I reference the Enemy class in this way? If not,
what is a better way of doing so?
int updWizHP = _enemy.getHitPoints(); //****** Question 1. below
If getHitPoints() is in the Player class, you cannot call it with an Enemy instance. Fields and methods must exist in the classes of the instance being used in the call, or in their inheritance tree (super classes).
If getHitPoints() is both common to both Player and Enemy, you should place the method in the nearest class common to both - in your case, it would be the Character class. Putting the method in the Character class (and giving it protected or public visibility) allows it to exist in both Player and Enemy classes (and to be called using associated instances of Player and Enemy)
How can I reference a class that has an object created in it's own
name when the method (code example) is in the class itself?
The only thing I can possibly imagine you describing here is the this keyword (which you don't seem to be using in your code). this represents the current instance of the class you are in.
So using this.attack(_enemy) is how you would get the current Player instance to attack the specified enemy.
a) can you pass a method as a parameter to another method like this in
Java? b) is the proper way to invoke another subclass (same subclass
level as the one calling the class) like this or is it even possible?
a) No. Java does not allow methods to be passed as parameters. If you want to pass a method, you must pass an instance (of a class containing the method) as a variable - say x - and then call the method you want to execute as x.method(). What you are doing is calling a method and using the return value as a parameter which is perfectly allowed.
decreaseHitPoints(_enemy.attack); // passing a method - not allowed
decreaseHitPoints(_enemy.attack(Player)); // passing a return value from calling a method - OK
b) I think what you want is this.decreaseHitPoints(_enemy.attack(this));. Yes, you can (and should) call methods in other classes - but if your calling class is unrelated (i.e not inherited from), you can only call those methods if they have been declared with public visibility.

Related

How to pass variables into an object after it was instantiated via a super() call?

TLDR: I pass data into the instantiation of a mob. Part of that instantiation proccess involves instantiating AI for the mob. I want the data I pass into the mob to be passed into the AI for the mob. This is difficult because of a forced Super() call among other things.
The story:
I am creating my own version of Monsters inside a game.
I have coded myself pathFinders (AI goals that entities use to navigate the world). Then I took an existing mob (in this case a cow) and erased its normal AI and replaced it with my own: PathFinderGoalRpgMeleeAttack.
I would like to create new instances of my cow (i.e. RpgCow rpgCow = new rpgCow(damage,knockback)).
The issue is that when I instantiate a new mob (which extends another class remember) I am forced to call super(). The super method calls method r() (which I override to add my own AI). Since the super() calls r(), the values of damage and knockback are still 0.0 and 0.0 (default java values for double) since damage and knockback have not had a chance to be set yet.
Any thoughts on how I can get around this and insert the data I pass into the cow creation into the PathFinder creation?
I have heard abstraction or reflection might be a good thing to look into, but just reading documentation on the two subjects, neither seems like it would help me.
EDIT, cause I guess I wasn't that clear:
The issue is that the values of Damage and Knockback are still 0 when I pass them into the PathFinder, which means later on when I do this.getDamage in my pathFinder, regardless of what values I passed into the mob on creation the damage and knockback will always be 0.
Code:
public class RpgCow extends EntityCow
{
private double damage;
private double knockback;
public RpgCow(World world, double damage, double knockback)
{
super(world);
this.damage = damage;
this.knockback = knockback;
this.bukkitEntity = new CraftRpgCow(this.world.getServer(), this);
}
#Override
protected void r()
{
this.goalSelector.a(3,new PathFinderGoalRpgMeleeAttack(this,damage,knockback));
}
private static class CraftRpgCow extends CraftCow
{
private CraftRpgCow(CraftServer server, EntityCow parent)
{
super(server, parent);
}
}
}
If you make the method definition of r() abstract in the super class, then any call of r() will use the instance's implementation of it, even it it is being called with in the super class's constructor.
This is probably a better solution than calling r() in the constructor of the child class (RpgCow)after the super() call, which, depending on your implementation, should overwrite the `cow.goalselector' that was set in your super() call.
This will require you to have the super class be abstract, but as you are programming a game with entities/mobs, having an abstract base class is a functionality you probably want anyways.
EDIT: Another way to go about this would to be to pass the AI you want into the constructor of the super class and into r(), and if it's null, do the base class's functionality, else do assign the new AI. Interfaces would be a handy way to polymorphise the AI objects.

Objects Within Objects in Java

I've been given a coursework assignment where I have to build a prototype hotel booking system, in accordance with the specification, which is as follows:
You will need at least three classes:
Hotel
This should store all the essential information about a hotel,
including a name and some rooms.
Room
This should store the number of beds in a room.
Bed
This should store the size of a bed (i.e. single or double).
I'm totally confused about where to start!
I was under the impression that objects could not be contained within other objects.
For example, let's assume we instantiate a "Hotel" object. How would we then instantiate "Room" objects, and within that object, "Bed" objects?
How are these objects being stored? How do we interact with them indirectly, from another object?
Typically you don't need to nest classes into other classes, which are called inner classes, unless the work that a class takes care of can be chunked into small units that never need to be known outside it's parent class.
It sounds like the concept you want to look into is Composition. It's when an object holds a reference to another object.
public class Room {
private boolean isVacant;
public Room() {
isVacant = true; // The room starts vacant
}
// Pretend there is a way for clients to check in and out of the room
public boolean isVacant() {
return isVacant;
}
}
public class Hotel {
// Using composition, I can make an instance of one class
// available to the methods of another
private Room room101;
public Hotel(Room room101) {
this.room101 = room101;
}
public boolean isRoom101Vacant() {
return room101.isVacant();
}
}
Our hotel may not be very useful having only one room, but this example shows how you can "compose" one object into another. Methods of Hotel can now use methods of it's Room instance known as room101. You will want to think about how your rooms are structured, and how you want to represent it within your Hotel class. A few objects used to store collections of other objects include ArrayList and HashMap.
Edit:
this is a fairly difficult concept to understand before you understand what a class is compared to an instance of that class (an object). In the constructor of my sample Hotel class, I have a variable of type Room called room101. And outside of the constructor is an instance field of the same type and name.
Java will always refer to a variable or reference of the nearest scope. So if I have a method reference called room101, how can I refer to that other one declared outside the constructor, at instance level? That's where this comes in.
public class ThisExample {
// This is a separate variable at the instance level
// Lets call this global in the comments
private int a;
public ThisExample() {
// This is a separate variable in the method level,
// lets call this local in the comments
int a;
a = 5; // our local is now assigned 5
this.a = 10; // Our global is now assigned 10
this.a = a; // our global is now assigned to 5
a = this.a * 2; // our local is now assigned to 10
}
}
In short, this refers to "this" instance of a class. It's a way for an instance of a class to refer to itself as if from the outside. Just like how another object would refer to room101's method as room101.isVacant(). A method in the Room class would similarly do this.isVacant() for the same effect.
And as a final note, if there is only one declaration of a symbol within a class. The this keyword is implied. So Room can call it's own method just as well without it as long as there is no other conflicting symbols of the same name. (This doesn't occur with methods as much as with instance fields/local variables)
Hopefully this helps clear things up a bit!
Your assignment is how to model some real world concepts into code.
It appears that the core of your problem can be stated as a Guest can book a Room.
I don't want to do your work for you, so let me start by asking how you would write that in code? After that, we can address the "Hotel" and "Bed". Is this a major assignment or just a quick question? Your implementation would depend on this.
A rule to learn and apply is:
An action on an object in the real world, becomes a method of that object in an Object Oriented approach.

Static factory method for sub-classes with variable number of constructor arguments

This is more of a style question, where I'm unsure what solution to my problem would be the "cleanest".
The implementation details are not important, what I want to do is the following:
I've got an abstract class that is extended by several subclasses which are all very similar in nature. I want to hide these classes from the client by making them instantiable only through a static method in the superclass which returns a superclass reference to a subclass instance (the concrete class is determined by the method parameters).
So far so good, I believe that's a very common thing to do.
Now, these subclasses I'm talking about can be divided into two groups, one group, whose members require two parameters in order to be constructed and another group, whose members need an additional parameter.
So now my question is this: How can I let the client obtain both of these types via a static method like the one mentioned above. Do I provide two static methods with different paramter lists? Do I force the client to pass a zero on the third optional parameter that the first group doesnt need? Is there a design pattern for this? (I have considered the Builder pattern from Effective Java, but as far as I understnad it that ones usually used in a different context). Or do I modify my inheritance hierarchy?
Any answers would be appreciated!
EDIT:
I believe my question is a little bit convoluted at the moment, all add a little bit of code to make it clearer:
abstract class SuperClass{
public static SuperClass getSuperClass(String type, int i1, int i2, int optional) {
/*
*'type' alone determines which concrete subclass is instanciated
*'optional' is only needed for the construction for some of those 'types'
*so the implementation of this method might look like this:
*/
switch(type) {
case "1":
return new Subclass1(i1, i2);
break;
case "2":
return new Subclass2(i1, i2, optional);
break;
/*
*So the problem is this: always passing 'optional' is weird if it
*is then simply discarded in some cases.
*Overloading is weird as well because I don't want to split up
*the switch statement or check for exceptions in every case
*(when optional is/is not declared for types where it
*shouldn't/should be)
*/
}
}
You have two options :
Option 1
Your static factory method in the super class can be implemented using var-args :
public static SuperClass newInstace(int...parameters) {
SuperClass superClass = null;
if(parameters.length == 2) {
if(parameters[1]>=5) {//instantiate a subclass based on a value
super = new SubClass1(parameters[0],parameters[1]);
} else {
super = new SubClass2(parameters[0],parameters[1]);
}
} else if(parameters.length == 3) {
if(parameters[2]>=5) {
super = new SubClass3(parameters[0],parameters[1],parameters[2]);
} else {
super = new SubClass4(parameters[0],parameters[1],parameters[2]);
}
} else {
throw new IllegalArgumentException("Invalid number of parameters passed to newInstance. Expected number of parameters [min = 2, max = 3]")
}
return superClass;
}
Option 2
Alternately, you could overload the newInstance method and have one that takes 2 parameters and the other that takes 3 parameters.
There are pros and cons of both approaches as described below :
When the frequency at which you expect new fields to be introduced in existing subclasses or the frequency at which you expect new subclasses to be introduced with more fields than the existing ones is extremely low, approach 1 is a better option.
When the frequency at which you expect new fields to be introduced in existing subclasses or the frequency at which you expect new subclasses to be introduced with more fields than the existing ones is relatively higher, approach 2 is a better option since approach 1 will result in a very large method body.
You could pass a configuration strings, or configuration object (e.g. Properties) which has as much detail as the implementation needs. It could be 1 or 100 arguments. However, for the caller there is one and only wrapping argument passed.
It depends. It sounds like that your superclass static method returns a SuperClass instance. If so, you can return different subclass instances according to the additional parameter.
Consider an abstract class Vehicle. Now two abstract classes SingleDeckVehicle and MultiDeckVehicle extend Vehicle and let the first two parameters be the number of wheels and the number of seats, and the additional parameter be the number of decks of the vehicle. Then, the number of deck will be important and indeed your client will pass a 1 as the third argument if he/she wants a SingleDeckVehicle instance.
However, you can also create another static method. Suppose you have defined a static method Vehicle.getVehicle(int wheelNo, int seatNo, int deckNo). You may also define another: Vehicle.getSingleDeckVehicle(int wheelNo, int seatNo) which returns Vehicle.getVehicle(wheelNo, seatNo, 1);.
A similar example is BorderFactory:
http://docs.oracle.com/javase/7/docs/api/javax/swing/BorderFactory.html. I hope I understood your question correctly...

Get static variable of subclass given superclass

This was very difficult for me to word into a question so allow me to explain.
I have an abstract class Entity and subclasses House and Warehouse. Each subclass has the same static variables with different values.
When a button is pressed in my game an Action is created which specifies which Entity subclass gets created and placed in the world. I want to write a generic method to place some Entity to the world using the static variables of which ever subclass it is.
I have a class PlaceEntityAction and when the mouse is clicked the appropriate entity will be placed assuming conditions are correct. How can I pass the Class I want to be placed to this Action so it works with any generic Entity?
Here is some dumbed down code:
if (mousePressed)) {
if (some conditions are true) {
int ex = x pos
int ey = y pos
if (world.player.haveFunds(e.COST_ENERGY, e.COST_MONEY,
e.COST_RESOURCE)) {
if (world.places[ex][ey] == 0) {
world.entities.add(e);
world.player.addEnergy(-e.COST_ENERGY);
}
}
}
}
So basically how can I get that e to be whatever subclass I pass to the Action since COST_MONEY, etc is static and should be accessed by the Class and not an object?
I'm really struggling to express what I want. Maybe someone can decipher this or provide some other insight regarding my issue. I can provide any other information necessary if you want.
EDIT:
e is an instance of whichever subclass I previously initialized based on an ID system but I don't like this method.
Static variables are the wrong approach here, especially since you've already instantiated your entity.
Instead, create abstract functions costEnergy(), costMoney(), and so on on the parent class, and implement them (with the correct values) on the child.
Static variables aren't polymorphic in Java. An option would be to declare abstract methods getCostEnergy, getCostMoney and getCostResource in Entity, and have each subclass override those methods to return different constants. Would that work for your scenario?

the static concept in java

I can't seem to understand the static key word (java) so I googled it up and viewed a thread in this website, though I'm sure the answer was conclusive and clear -it always is over here- I didn't seem to understand it for two reasons; I'm not a native English speaker and the language was a bit vague for me, and it lacked exemples of use in classes, instance of classes, interfaces (if possible), instance of interfaces and variables, lists and arrays ect.
I would really appreciate any help and please keep the English as simple as possible ;)
Thank you
Aditsan
Note from editor: Please note that the original poster is asking for examples, and is not a native English speaker as you provide answers. From the comments, it appears that OP doesn't understand the concept well enough to ask about the parts that don't make sense yet, so examples would be awesome! It may take extra details and multiple different explanations to find the combination of answers that works best.
I think it helps to understand what non-static means, i.e. field/methods/... that are declared without the keyword static.
Every field declared without the keyword static exists as part of an object. If you have two objects, each of these two objects has a field with possibly different contents:
class X {
int f;
}
X x1 = new X();
X x2 = new X();
x1.f = 5;
x2.f = 10;
// x1.f still is 5
However, static fields exist not per object, but per class. So in the following example, there is only one field g no matter how many (if any!) objects of class Y you have:
class Y {
static int g;
}
Y y1 = new Y();
Y y2 = new Y();
y1.g = 5;
y2.g = 10;
// y1.g is 10, because y1.g and y2.g mean the exact same thing
I personally think accesses to static fields should be made using the class (Y.g) instead of mentioning object instances (y1.g), so that the existence without any object instance is more explicit.
For methods the difference is that non-static methods are associated to an object instance, which can be accesses using this inside the method. When invoking a method declared with void m() you can access non-static (and static) fields of the object it is invoked on (so for x1.m() from the example above you can get to the field containing 5, for x2.m() you can access the field containing 10.
Static methods, however, can be invoked without having a (corresponding?) object around. If the declaration is static void n() inside class Y, you can call this method using Y.n() or y1.n() (if y1 is an instanceof Y, as above). Here, too, I prefer the first way of writing it down. Because in static methods you do not have a reference to the object instance (which is named this in non-static methods), you cannot access specific non-static fields from inside a static method - simply because there is no clear association to a specific object.
Regarding static and class definitions: This is rather advanced. You can declare a class inside another class. If the inner class is not static, every object instance of the inner class also has a reference to an instance of the outer class (which also means that you only can create an instance of the inner class if you have an instance of the outer class). This is not always what you want. By declaring the inner class static it just exists and can be used, more or less, like a class defined in its own file.
Basically, static implies/provides two things:
1) Only one instance of an "item" exists in the whole system (JVM)
2) Static "items" are also context/state free
To explain (1) above: Suppose you have a Meal Token issuer. No matter how many users/processes are there in the system, all tokens must be issued by a single "thing". You would develop that "thing" as static. You would then decide what that "thing" is. It could be a class that does a complex operation and implements a complex business rule. Then you would have a single static class issuing tokens in "a single uniform way" for the whole system. Some times, all that matters is that the token should be "static" but how it is issued could be non-static. Then you would simply implement a "Static" token counter.
To explain (2) : Going by what is said for (1) above, you can easily see why it is important that the static "things" operate in a context-free manner. That is, they do not know who calls them or for what purpose. When they are called, they do not borrow anything from the past, they need all inputs from the current caller, and they just do their job, and remember nothing for the future.

Categories