How can a static method change a variable? (Java) - java

I have this class:
class Inventory {
boolean smallknife = false;
boolean SRLockerkey = false;
void checkinv () {
System.out.println("You have the following items in your inventory: ");
System.out.println(smallknife);
System.out.println(SRLockerkey);
}
}
The Inventory test class
class InvTester {
public static void main(String args[]) {
Inventory TestInv = new Inventory();
System.out.println("This program tests the Inventory");
SKTrue.truth(TestInv.smallknife);
TestInv.checkinv();
}
}
and this class with a method to try to change the inventory
class SKTrue {
static boolean truth(boolean smallknife) {
return true;
}
}
class SKTrue {
static void truth(boolean smallknife) {
smallknife = true;
}
}
I would like to avoid using TestInv.smallknife = SKTrue.truth(TestInv.smallknife) and still change the variable but with a method. Is there a way that this can be done? I want that the truth method does the variable changing and I don't want to do the pass by reference part in the Inventory Test class. Thanks. Is there a way to do this in Java? (I also tried the second version which I think makes more sense)

Assuming you don't want to reference the variables directly (i.e. TestInv.smallknife = blah), the best practice in Java is to declare the variables as private and access them by getters/setters, e.g.:
class Inventory {
private boolean smallknife;
public boolean isSmallknife() {
return smallknife;
}
public void setSmallknife(boolean smallknife) {
this.smallknife = smallknife;
}
}
Now, you can do this:
Inventory TestInv = new Inventory();
TestInv.setSmallknife(SKTrue.truth(blah));
It is called Encapsulation, you can read more about it here.

Related

over reliance on one arrayList

public class InventorySetDAO{
public LinkedList<CustomInventory> inventories = new LinkedList<>();
}
I am developing plugin that add/delete data in arraylist. and There's too much reference on the arrayList from other class.
Class InventoryItemModifier:
public class InventoryItemModifier {
InventorySetDAO inventorySetDAO;
public InventoryItemModifier(InventorySetDAO inventorySetDAO){
this.inventorySetDAO = inventorySetDAO;
}
public void addItem(ItemStack itemStack, ClickAction click, RequiredItems requiredItems) {
Bukkit.getPluginManager().callEvent(new ItemAddedEvent());
inventorySetDAO.getLastInventory().addItem(itemStack, click, requiredItems);
}
public void removeItem(ItemStack itemStack){
Bukkit.getPluginManager().callEvent(new ItemRemovedEvent());
inventorySetDAO.getLastInventory().removeItem(itemStack);
}
}
Class InventoryPlayerAccessor:
public class InventoryPlayerAccessor {
InventorySetDAO inventorySetDAO;
public boolean openPage(Player player) {
if (!inventories.isEmpty()) {
inventories.get(0).openInventory(player);
return true;
}
return false;
}
public boolean openPage(Player player, int index) {
if (!inventories.isEmpty()) {
if (index >= 0 && index < inventories.size()) {
inventories.get(index).openInventory(player);
return true;
}
}
return false;
}
}
I think there is risk of manipualte arrayList unproperly, so I think arrayList must be in a class and provide methods(add/insert/remove...) but if then there are too much responsibilities in that class.
I tried to seperate them into multiple classes, but it doesn't seem to solve this problem. is there a way to reduce reliance on arrayList, or efficient way to encapsulate arrayList?
To reduce each classes reliance on the underlying ArrayList (or just List), you could think about using the composite pattern instead of the DAO pattern. This would hide all/most of the logic to the InventorySet class.
class InventorySet {
private final List<CustomInventory> inventories = new ArrayList<>();
public void addItem() { }
public void removeItem() { }
}
Then, you can just keep your InventoryPlayerAccessor (maybe rename) but compose it of a InventorySet for easy access.
class InventorySetView {
void open();
}

Calling boolean methods

My overall goal with this program is to validate that a user inputted string is in fact a valid number. I am required to use at least two methods, including the main method. I have read many posts related to calling user-defined methods from within the main method, but I am however struggling to make mine work. When declaring my isAValidNumber method, I keep getting the error "illegal start of expression". How can I declare this method so that I can call it from within the main method and contentiously run it until the user enters an invalid invalid number?
import java.util.Scanner;
public class IsAValidNumber
{
public static void main(String[] args)
{
//prompt user for a valid number
Scanner consoleInput = new Scanner(System.in);
System.out.print("\nEnter a valid integer or floating point value: \n");
String input = consoleInput.nextLine();
/* while(isAValidNumber = true)
{
//
} */
public static isAValidNumber(String input)
{
for(int j=0;j<input.length();j++)
{
if(input.matches("\\d+(\\.\\d*)?|\\.\\d+") == true)
{
boolean isAValidNumber = true;
}
else
{
boolean isAValidNumber = false;
}
}
}
}
}
You can't declare methods inside of methods in Java. Declare isAValidNumber outside of main (either before or after it, doesn't matter) and you should be OK:
public class IsAValidNumber
{
public static boolean isAValidNumber(String input)
{
// Method's body snippet for brevity's sake
}
public static void main(String[] args)
{
// Code that can call isAValidNumber
}
}

Abstract methods without abstract classes

I'm kinda new to Java, and I'm trying to write an RPG of sorts.
Now, in the game the player character would have skills. These could be very diverse, from hurting enemies to healing the player and a lot of other things. It'd make sense to create a Skill class with an abstract applyEffect() method, to be defined on each particular skill.
However, I cannot have a non-abstract class containing abstract methods, and every skill should be an object of the Skill class, so it can't be abstract. The obvious solution is to make the Skill class abstract and create a subclass for every single skill, and then instantiate that into an object to use.
This approach seems a bit redundant. Is there anything else I could conceivably do in this situation?
EDIT: While we're at it, if I want an object that will appear a single time with standard variables, is there any workaround to making a class just for that one object and then instantiating it?
I would not write skills (like 'heal' and 'hide') as classes. I view classes as objects (players), and methods as abilities (skills). Skills like 'heal' or 'hide' are clearly better as methods than classes.
I would simply have one class that has all methods, but only the selected ones are available for use. Having the skills as enums isn't a bad idea either.
enum Skill {
HEAL, HIDE, ATTACK, THROW
}
class Player {
boolean canHeal = false;
boolean canHide = false;
boolean canAttack = false;
boolean canThrow = false;
Player(Skill[] skills) {
for(skill : skills) {
switch(skill) {
case Skills.HEAL: canHeal = true;
break;
case Skills.HIDE: canHide = true;
break;
case Skills.ATTACK: canAttack = true;
break;
case Skills.THROW: canThrow = true;
break;
default: //error
}
}
}
void heal() {
[...]
}
void hide() {
[...]
}
void attack() {
[...]
}
void throw() {
[...]
}
boolean canHeal() {
return canHeal;
}
boolean canHide() {
return canHide;
}
boolean canAttack() {
return canAttack;
}
boolean canThrow() {
return canThrow;
}
}
Now the players can be restricted to only use the methods that should be available to them. What I would do is probably to write a GameHandler-class to take care of everything and do all the checking there.
How about this:
public abstract class Skill {
public abstract void applyEffect();
}
... somewhere else ...
Skill dig = new Skill() {
#Override
public void applyEffect() {
doSomeDigging();
}
};
This one still creates a subclass in the background, but you might like it better.
i would use enums also, you can stuff a bunch of login in them. the maps let each player have whatever skills and stats they need. you can nest enums like this or that.
import java.util.Map;
import java.util.Random;
import java.util.TreeMap;
public class So36107587 {
enum Stat {
food,health,magic;
}
enum Skill {
heal,hurt,hunt;
static void apply(Skill skill,double amount,Player player) {
double a=amount*random.nextDouble(),x;
switch(skill) {
case heal:
x=player.stats.get(Stat.health);
player.stats.put(Stat.health,a+x);
break;
case hurt:
x=player.stats.get(Stat.health);
player.stats.put(Stat.health,a-x);
break;
case hunt:
x=player.stats.get(Stat.food);
player.stats.put(Stat.food,a+x);
break;
}
}
static final Random random=new Random();
}
static class Player {
Player() {
init();
}
void init() {
for(Stat stat:Stat.values())
stats.put(stat,1.);
for(Skill skill:Skill.values())
skills.put(skill,1.);
}
void apply(Skill skill,Player player) {
Skill.apply(skill,skills.get(skill),player);
}
#Override public String toString() {
return ""+skills+" "+stats;
}
final Map<Stat,Double> stats=new TreeMap<>();
final Map<Skill,Double> skills=new TreeMap<>();
}
public static void main(String[] args) {
Player player=new Player();
System.out.println(player);
player.apply(Skill.heal,player);
System.out.println(player);
player.apply(Skill.hunt,player);
System.out.println(player);
}
}

public variable in java?

I have four classes in my program in which One contains main()
but there is a error in first three lines in fruit, ch and demand variable. I want to use these variables in each class.
import java.util.Scanner;
public static int fruit = 0;
public static int ch;
public static boolean demand = false;
class stock{
synchronized int getfruit(){
while(demand){
try{
wait();
}catch(InterruptedException e){
System.out.println("Wait fruits uploading");
}
System.out.println("cutomer got : " + ch);
demand = true;
notify();
}
return ch;
}
synchronized void putfruits(int ch){
while(!demand){
try{
wait();
}catch(InterruptedException e){
System.out.println("uploaded already");
}
System.out.println("Uploading your demand : "+ ch + " fruits");
demand = false;
notify();
}
}
}
class vendor implements Runnable{
stock obj;
public vendor(stock obj) {
// TODO Auto-generated constructor stub
this.obj = obj;
new Thread(this, "vendor").start();
}
#Override
public void run() {
// TODO Auto-generated method stub
obj.putfruits(ch);
}
}
class customer implements Runnable {
stock obj;
public customer(stock obj) {
// TODO Auto-generated constructor stub
this.obj = obj;
new Thread(this, "cutomer").start();
}
#Override
public void run() {
// TODO Auto-generated method stub
obj.getfruit();
}
}
public class Fruitmarket {
public static void main (String args[]){
stock obj2 = new stock();
System.out.println("Initially market no capacity");
System.out.println("Enter how much quantity you want ?");
Scanner in = new Scanner ( System.in);
ch = in.nextInt();
}
}
How can I do this ? I'm beginner in java ?
This code will not compile. You need to put these variables inside a class like so:
import java.util.Scanner;
class stock {
public static int fruit = 0;
public static int ch;
public static boolean demand = false;
....
If you want to access these variables outside, you can do this by referring to it like this: stock.fruit
If you want to use constants, you can declare an Interface, which you will then use to store constants as public static final <type> <name>
EDIT : You should not implement the interface, instead simply call it : InterfaceName.CONSTANT
It is also good practice to name your constants in all capital letter.
EDIT 2 : It seems that since java 5 (I Guess I'm really outdated...) te use of static imports is considered better practice
Outside the Class definition you can't declare variables. Like the other guys said, you need to declare them inside the class.
If they are public and declared inside class Stock, you can access them from any other class. If they are friendly (no keyword, just static int fruit = 0;) you can access them from any class in the package. How to access them will depend on whether they're static or not. static fields can be accessed by referencing the class itself (e.g. stock.fruit), while for non-static fields you'll need to reference an object that is an instance of the class holding the field.
Now, with that said, I would very much recommend that you declare your variables where they should logically be placed, according to the context of the program. I'm not entirely sure what demand and ch are intended to mean, but just know that you can put them in any class, including Fruitmarket, so long as they have the correct access level modifiers (public, friendly, etc) and you attempt to access them in the right way (through the declaring class if they are static or through an instance of the declaring class if they are non-static)

Java-How do I call a class with a string?

I am a beginner programmer and this is my first question on this forum.
I am writing a simple text adventure game using BlueJ as a compiler, and I am on a Mac. The problem I ran into is that I would like to make my code more self automated, but I cannot call a class with a string. The reason I want call the class and not have it all in an if function is so that I may incorporate more methods.
Here is how it will run currently:
public class textadventure {
public method(String room){
if(room==street){street.enterRoom();}
}
}
public class street{
public enterRoom(){
//do stuff and call other methods
}
}
The if statement tests for every class/room I create. What I would like the code to do is automatically make the string room into a class name that can be called. So it may act like so:
Public method(string room){
Class Room = room;
Room.enterRoom();
}
I have already looked into using Class.forName, but all the examples were too general for me to understand how to use the function. Any help would be greatly appreciated, and if there is any other necessary information (such as more example code) I am happy to provide it.
-Sebastien
Here is the full code:
import java.awt.*;
import javax.swing.*;
public class Player extends JApplet{
public String textOnScreen;
public void start(){
room("street1");
}
public void room(String room){
if(room=="street1"){
textOnScreen=street1.enterRoom();
repaint();
}
if(room=="street2"){
textOnScreen=street2.enterRoom();
repaint();
}
}
public void paint(Graphics g){
g.drawString(textOnScreen,5,15);
}
}
public abstract class street1
{
private static String textToScreen;
public static String enterRoom(){
textToScreen = "You are on a street running from North to South.";
return textToScreen;
}
}
public abstract class street2
{
private static String textToScreen;
public static String enterRoom(){
textToScreen = "You are on another street.";
return textToScreen;
}
}
Seeing as you are rather new to programming, I would recommend starting with some programs that are simpler than a full-fledged adventure game. You still haven't fully grasped some of the fundamentals of the Java syntax. Take, for example, the HelloWorld program:
public class HelloWorld {
public static void main(String[] args) {
String output = "Hello World!"
System.out.println(output);
}
}
Notice that public is lowercased. Public with a capital P is not the same as public.
Also notice that the String class has a capital S.* Again, capitalization matters, so string is not the same as String.
In addition, note that I didn't have to use String string = new String("string"). You can use String string = "string". This syntax runs faster and is easier to read.
When testing for string equality, you need to use String.equals instead of ==. This is because a == b checks for object equality (i.e. a and b occupy the same spot in memory) and stringOne.equals(stringTwo) checks to see if stringOne has the same characters in the same order as stringTwo regardless of where they are in memory.
Now, as for your question, I would recommend using either an Enum or a Map to keep track of which object to use.
For example:
public class Tester {
public enum Location {
ROOM_A("Room A", "You are going into Room A"),
ROOM_B("Room B", "You are going into Room B"),
OUTSIDE("Outside", "You are going outside");
private final String name;
private final String actionText;
private Location(String name, String actionText) {
this.name = name;
this.actionText = actionText;
}
public String getActionText() {
return this.actionText;
}
public String getName() {
return this.name;
}
public static Location findByName(String name) {
name = name.toUpperCase().replaceAll("\\s+", "_");
try {
return Enum.valueOf(Location.class, name);
} catch (IllegalArgumentException e) {
return null;
}
}
}
private Location currentLocation;
public void changeLocation(String locationName) {
Location location = Location.findByName(locationName);
if (location == null) {
System.out.println("Unknown room: " + locationName);
} else if (currentLocation != null && currentLocation.equals(location)) {
System.out.println("Already in room " + location.getName());
} else {
System.out.println(location.getActionText());
currentLocation = location;
}
}
public static void main(String[] args) {
Tester tester = new Tester();
tester.changeLocation("room a");
tester.changeLocation("room b");
tester.changeLocation("room c");
tester.changeLocation("room b");
tester.changeLocation("outside");
}
}
*This is the standard way of formating Java code. Class names are PascalCased while variable names are camelCased.
String className=getClassName();//Get class name from user here
String fnName=getMethodName();//Get function name from user here
Class params[] = {};
Object paramsObj[] = {};
Class thisClass = Class.forName(className);// get the Class
Object inst = thisClass.newInstance();// get an instance
// get the method
Method fn = thisClass.getDeclaredMethod(fnName, params);
// call the method
fn.invoke(inst, paramsObj);
The comments below your question are true - your code is very rough.
Anyway, if you have a method like
public void doSomething(String str) {
if (str.equals("whatever")) {
// do something
}
}
Then call it like
doSomething("whatever");
In Java, many classes have attributes, and you can and will often have multiple instances from the same class.
How would you identify which is which by name?
For example
class Room {
List<Monster> monsters = new ArrayList <Monster> ();
public Room (int monstercount) {
for (int i = 0; i < monstercount; ++i)
monsters.add (new Monster ());
}
// ...
}
Monsters can have attributes, and if one of them is dead, you can identify it more easily if you don't handle everything in Strings.

Categories