Java declare class in method

Java: Referring to a Class inside its own method

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 >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; > > 
  1. 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?
  2. 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.
  3. 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?
Читайте также:  Java assert that throw exception

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.

Источник

Use of class definitions inside a method in Java

I agree, it’s incredibly messy looking. I inspected some code that my colleague wrote and found this local class in a method. it just made me feel like this module was totally defiled.

8 Answers 8

This is called a local class.

2 is the easy one: yes, a class file will be generated.

1 and 3 are kind of the same question. You would use a local class where you never need to instantiate one or know about implementation details anywhere but in one method.

A typical use would be to create a throw-away implementation of some interface. For example you’ll often see something like this:

 //within some method taskExecutor.execute( new Runnable() < public void run() < classWithMethodToFire.doSomething( parameter ); >>); 

If you needed to create a bunch of these and do something with them, you might change this to

 //within some method class myFirstRunnableClass implements Runnable < public void run() < classWithMethodToFire.doSomething( parameter ); >> class mySecondRunnableClass implements Runnable < public void run() < classWithMethodToFire.doSomethingElse( parameter ); >> taskExecutor.execute(new myFirstRunnableClass()); taskExecutor.execute(new mySecondRunnableClass()); 

Regarding interfaces: I’m not sure if there’s a technical issue that makes locally-defined interfaces a problem for the compiler, but even if there isn’t, they wouldn’t add any value. If a local class that implements a local interface were used outside the method, the interface would be meaningless. And if a local class was only going to be used inside the method, both the interface and the class would be implemented within that method, so the interface definition would be redundant.

Читайте также:  Javascript get base url

Inner classes were added in Java 1.1 — I’m guessing local classes were as well but I don’t have documentation on that.

Could you provide a better example for what could be a use case of a non-anonymous local class? Your second block of code could be rewritten with anonymous classes.

Most uses of non-anonymous local classes can be accomplished with anonymous classes. I didn’t flesh out the example but you’d typically use a named local class if you need to create more that one instance of the same class type.

For the OP: note that local class provides a way for threads to communicate — the parameter above might be declared in the enclosing method, and is accessible by both threads.

Those are called local classes. You can find a detailed explanation and an example here. The example returns a specific implementation which we doesn’t need to know about outside the method.

Great link (still works after 7+ years!). In particular, note «Like member classes, local classes are associated with a containing instance, and can access any members, including private members, of the containing class

  1. The class can’t be seen (i.e. instantiated, its methods accessed without Reflection) from outside the method. Also, it can access the local variables defined in testMethod(), but before the class definition.
  2. I actually thought: «No such file will be written.» until I just tried it: Oh yes, such a file is created! It will be called something like A$1B.class, where A is the outer class, and B is the local class.
  3. Especially for callback functions (event handlers in GUIs, like onClick() when a Button is clicked etc.), it’s quite usual to use «anonymous classes» — first of all because you can end up with a lot of them. But sometimes anonymous classes aren’t good enough — especially, you can’t define a constructor on them. In these cases, these method local classes can be a good alternative.

2. Ehrm, sure it will. Class files will be generated for every nested, local or anonymous class in your java file.

«2. No such file will be written.» — this is wrong. It creates TestClass$1TestMethodClass.class , analogous to how inner classes .class files are named.

Good answer, exception for 2: you will get the anonymous class generated, in this case «TestClass$1TestMethodClass.class»

The real purpose of this is to allow us to create classes inline in function calls to console those of us who like to pretend that we’re writing in a functional language 😉

The only case when you would like to have a full blown function inner class vs anonymous class ( a.k.a. Java closure ) is when the following conditions are met

  1. you need to supply an interface or abstract class implementation
  2. you want to use some final parameters defined in calling function
  3. you need to record some state of execution of the interface call.
Читайте также:  Php проверить imagick установлено

E.g. somebody wants a Runnable and you want to record when the execution has started and ended.

With anonymous class it is not possible to do, with inner class you can do this.

Here is an example do demonstrate my point

private static void testMethod ( final Object param1, final Object param2 ) < class RunnableWithStartAndEnd extends Runnable< Date start; Date end; public void run () < start = new Date( ); try < evalParam1( param1 ); evalParam2( param2 ); . >finally < end = new Date( ); >> > final RunnableWithStartAndEnd runnable = new RunnableWithStartAndEnd( ); final Thread thread = new Thread( runnable ); thread.start( ); thread.join( ); System.out.println( runnable.start ); System.out.println( runnable.end ); > 

Before using this pattern though, please evaluate if plain old top-level class, or inner class, or static inner class are better alternatives.

The main reason to define inner classes (within a method or a class) is to deal with accessibility of members and variables of the enclosing class and method. An inner class can look up private data members and operate on them. If within a method it can deal with final local variable as well.

Having inner classes does help in making sure this class is not accessible to outside world. This holds true especially for cases of UI programming in GWT or GXT etc where JS generating code is written in java and behavior for each button or event has to be defined by creating anonymous classes

I’ve came across a good example in the Spring. The framework is using concept of local class definitions inside of the method to deal with various database operations in a uniform way.

Assume you have a code like this:

JdbcTemplate jdbcOperations = new JdbcTemplate(this.myDataSource); jdbcOperations.execute("call my_stored_procedure()") jdbcOperations.query(queryToRun, new MyCustomRowMapper(), withInputParams); jdbcOperations.update(queryToRun, withInputParams); 

Let’s first look at the implementation of the execute():

 @Override public void execute(final String sql) throws DataAccessException < if (logger.isDebugEnabled()) < logger.debug("Executing SQL statement [" + sql + "]"); >/** * Callback to execute the statement. (can access method local state like sql input parameter) */ class ExecuteStatementCallback implements StatementCallback, SqlProvider < @Override @Nullable public Object doInStatement(Statement stmt) throws SQLException < stmt.execute(sql); return null; >@Override public String getSql() < return sql; >> //transforms method input into a functional Object execute(new ExecuteStatementCallback()); > 

Please note the last line. Spring does this exact «trick» for the rest of the methods as well:

//uses local class QueryStatementCallback implements StatementCallback, SqlProvider jdbcOperations.query(. ) //uses local class UpdateStatementCallback implements StatementCallback, SqlProvider jdbcOperations.update(. ) 

The «trick» with local classes allows the framework to deal with all of those scenarios in a single method which accept those classes via StatementCallback interface. This single method acts as a bridge between actions (execute, update) and common operations around them (e.g execution, connection management, error translation and dbms console output)

public T execute(StatementCallback action) throws DataAccessException < Assert.notNull(action, "Callback object must not be null"); Connection con = DataSourceUtils.getConnection(obtainDataSource()); Statement stmt = null; try < stmt = con.createStatement(); applyStatementSettings(stmt); // T result = action.doInStatement(stmt); handleWarnings(stmt); return result; >catch (SQLException ex) < // Release Connection early, to avoid potential connection pool deadlock // in the case when the exception translator hasn't been initialized yet. String sql = getSql(action); JdbcUtils.closeStatement(stmt); stmt = null; DataSourceUtils.releaseConnection(con, getDataSource()); con = null; throw translateException("StatementCallback", sql, ex); >finally < JdbcUtils.closeStatement(stmt); DataSourceUtils.releaseConnection(con, getDataSource()); >> 

Источник

Оцените статью