So I just started with java, so this is just a simple problem ig, but I have to make a small project for school. I made 2 classes, one called Pokémon and one called trainer. In the Pokémon class I made a constructor and a method to create objects, because I couldn't just create the object:
public class Pokemon {
public String name;
public String typ;
public int maxLp;
public int aktLp;
public int ap;
public Pokemon(String pname, String ptyp, int pmaxLp, int paktLp, int pap) {
name=pname;
typ=ptyp;
maxLp=pmaxLp;
aktLp=paktLp;
ap=pap;
}
public void CreatePokemon(String[] args) {
Pokemon Squirtle = new Pokemon("Squirtle", "Water", 20, 20, 5);
Pokemon Charmander = new Pokemon("Charmander", "Fire", 20, 20, 5);
}
}
In the other class, Trainer, I wanted to use these created objects (Pokemon Squirtle and Pokemon Charmander) to let them fight, the "fight" is basically just one pokemon, I wanted to use Squirtle in the function Squirtle attack, attacking Charmander dealing as much damage as declared in ap, changing the variable aktLp in the object Glumanda, which is the current hp of glumanda:
public class Trainer
{
public String name;
public String gender;
public int money;
public int amountPokemon;
public int amountFights;
public Trainer(String tname, String tgender, int tmoney, int tamountPokemon, int tamountFights) {
name=tname;
gender=tgender;
money=tmoney;
amountPokemon=tamountPokemon;
amountFights=tamountFights;
}
public void ChooseSquirtle() {
System.out.println("You choose Squirtle!");
}
public void ChooseCharmander() {
System.out.println("You choose Charmander!");
}
public void SquirtleAttack() {
System.out.println("Squirtle attacks Charmander!");
Charmander.aktLp = Charmander.aktLp - Squirtle.ap;
}
}
So for this project I have to use - even if I don't like it - BlueJ. BlueJ says: "cannot find symbol - variable Glumanda" - but why? Do I have to call the method CreatePokemon() ? Well I thought I had to and added CreatePokemon(); ,pressed compile and there was another error, but there is no explanation whatsoever. I can't find the problem even though it might be easy. As I said I pretty much just started with java so tips are appreciated - also, I tried my best translating the variables, sorry if you don't understand them and if they are inacurrate.
Your code is not very abstract and has a few flaws:
You're creating pokemon object inside the pokemon class definition. What you should do instead is create it in some higher level method, e.g.: main.
The trainer class uses two pokemons to attack each other. The problem is, the pokemon classes have not been instantiated in a scope that trainer can access. What you should do instead is either instantiate a new pokemon inside the trainer class, or pass pokemon objects as parameters to the generic attack function.
The trainer class could like this with instantiating new pokemon inside.
class Trainer {
public String name;
public String gender;
public int money;
public int amountPokemon;
public int amountFights;
private Pokemon squirtle;
private Pokemon charmander;
public Trainer(String tname, String tgender, int tmoney, int tamountPokemon, int tamountFights) {
name = tname;
gender = tgender;
money = tmoney;
amountPokemon = tamountPokemon;
amountFights = tamountFights;
squirtle = new Pokemon("Squirtle", "Water", 20, 20, 5);
charmander = new Pokemon("Charmander", "Fire", 20, 20, 5);
}
public void ChooseSquirtle() {
System.out.println("You choose Squirtle!");
}
public void ChooseCharmander() {
System.out.println("You choose Charmander!");
}
public void SquirtleAttack() {
System.out.println("Squirtle attacks Charmander!");
charmander.aktLp = charmander.aktLp - squirtle.ap;
}
}
Or like this with accepting pokemons as parameters:
class Trainer {
public String name;
public String gender;
public int money;
public int amountPokemon;
public int amountFights;
public Trainer(String tname, String tgender, int tmoney, int tamountPokemon, int tamountFights) {
name = tname;
gender = tgender;
money = tmoney;
amountPokemon = tamountPokemon;
amountFights = tamountFights;
}
public void SquirtleAttack(Pokemon attacker, Pokemon defender) {
System.out.println(attacker.name+" attacks "+defender.name+"!");
defender.aktLp = defender.aktLp - attacker.ap;
}
}
public class Main {
public void CreatePokemon(String[] args) {
Pokemon squirtle;
Pokemon charmander;
squirtle = new Pokemon("Squirtle", "Water", 20, 20, 5);
charmander = new Pokemon("Charmander", "Fire", 20, 20, 5);
}
}
Just a couple of hints:
Not sure what your project structure is, but you cannot have 2 public classes in a single file. Public class has to have the same name as filename. You can, however, have multiple non-public classes in a single file. But generally it is not recommended to define multiple classes in a single file anyways.
Per Java naming conventions, you should name variables or object instances beggining with lowercase letter. Read more: https://www.oracle.com/java/technologies/javase/codeconventions-namingconventions.html
Try to use public class properties as least as possible and private as often as possible. To manipulate private properties values, use getters and setters. more info here: https://www.freecodecamp.org/news/java-getters-and-setters/
Related
Just a question RE: Constructor Chaining in subclasses that I can't find a good answer on and I'm confusing myself a bit with.
I'm making a basic little Text Based RPG for some practice and I'm going through my constructors for an abstract class and have the constructors from 0-4 params chained together like below
abstract class Creature {
// Fields
private String name;
private int lifeForce;
private int strength;
private int agility;
// Constructors + Chaining
public Creature() {
this("Unknown")
}
public Creature(String name) {
this(name, 100);
}
public Creature(String name, int lifeForce) {
this(name, lifeForce, 10);
}
public Creature(String name, int lifeForce, int strength) {
this(name, lifeForce, strength, 10);
}
public Creature(String name, int lifeForce, int strength, int agility) {
this.name = name;
this.lifeForce = lifeForce;
this.strength = strength;
this.agility = agility;
}
My confusion is how best to format the constructors of a subclass of creature, for example this simple Person class introduces two new fields. There's definitely too much repetition if I write the constructors like this
// Constructors + Chaining
public Person() {
super("Unknown");
this.skillClass=new Mage();
this.dialogue="...";
}
public Person(String name) {
super(name);
this.skillClass=new Mage();
this.dialogue="...";
} etc etc etc
I suppose I could restrict the constructors to limit the repetition but I'm mostly just wondering if there's good best practice that I'm missing here.
Any and all suggestions welcome and if anyone has any good resources to recommend that go deeper than the usual
Class B extends Class A
examples I'd massively appreciate.
In situations like this one when you need to use multiple constructors with different parameters, it is recommended to use the builder pattern like this :
abstract class Creature {
// Fields
private String name;
private int lifeForce;
private int strength;
private int agility;
private Creature(Builder<?> builder) {
this.name = builder.name;
this.lifeForce = builder.lifeForce;
// Add the other attributes here.
}
public static abstract Builder extends Builder<T extends Builder<T>> {
private String name;
private int lifeForce;
private int strength;
private int agility;
public Builder(//here you put the attributes that you need to have in all instances) {
// here you do the affectations.
}
// now you need to make the functions that set each property :
public Builder lifeForce(int lifeForce) {
this.lifeForce = lifeForce;
return this;
}
// you do the same thing for all the other attributes.
...
public Creature build() {
return new Creature(this);
}
}
}
So for the explanation : This pattern will allow you to create instances of your class by setting only the needed attributes.
As here you have subclasses the builder pattern will be little bit more harder to understand but it is the perfect solution in such situation.
We need to apply the builder pattern also for every subclasse so let's do it for the person class :
public class Person extends Creature {
private int anotherField;
public Person(Builder builder) {
super(builder);
this.anotherField = anotherField;
}
public static Builder extends Creature.Builder<Builder> {
public Builder(//add the fieldHere if it is needed in all class instances) {
// if the field is not mandatory you can omit this constructor but you need to put the function below.
}
public Builder anotherField(int anotherField) {
this.anotherField = anotherField;
}
public Person build() {
return new Person(this);
}
}
Now let me show you how tricky is this solution :
1/ declare person with 2 fields :
Person p1 = Person.Builder().name("name").anotherField(0).build();
2/ declare another one with just one field
Person p2 = Person.Builder().agility(1000).build();
Remark : In these two examples, i supposed that your builders' constructors don't have parameters. If for example the name is mandatory field :
Person p3 = Person.Builder("name").anotherField(0).build();
I wish that you had the idea about using builder pattern.
I'm making a game right now and I'm trying to setup a CreatePlayer method.
In the main class, I take the Player class as an object to get its variables, methods ect.
package com.deud07.main;
import com.deud07.player.Player;
public class Main {
public static Player player = new Player("Bob", 86, null);
public static void main(String[] args) {
System.out.println(player.Position);
}
}
The 3rd parameter of Player is the Position, which is an array.
The problem I'm having is that I'm not sure how to set each element of the array without writing:
position[0] = 1f;
position[1] = -6f;
position[2] = 0f;
The code for Player:
package com.deud07.player;
public class Player {
public static String Name;
public static int ID;
public static float x;
public static float y;
public static float z;
public static float[] Position = {x, y, z};
public Player(String name, int id, float[] pos) {
Player.Name = name;
Player.ID = id;
Player.Position = pos;
}
public void createPlayer(String name, int id, float[] pos) {
Player player = new Player(name, id, pos);
player.Name = name;
player.ID = id;
player.Position = pos;
}
}
Any solutions? And while you're at it, anything I can do to fix up my code?
I believe you're asking for a shorthand method. You might also find them as "one liners". The way to initiate an array in one line without a variable is as follows:
Player player = new Player("Bob", 86, new float[]{1f, -6f, 0f});
As for "fixing your code", it goes outside of the actual question you've posted. Two things I can say are
Java conventions state that variables must be camel case. So your Player class' attributes should be name, id and position.
Your method createPlayer() does exactly the same the constructor does, thus it is not necessary. To create a new Player, just use... well, new Player().
Also, x, y and z are kind of useless. If you need x for example, just use position[0] instead.
I am rather new to Java, rather only a week's worth of learning so I am still very inexperienced. I have spent a few days on polymorphism and know that I can extend a parent class to a child class, but I would like to know how to have a grandparent class have all the attributes of the parent classes. I have done a bit of research but haven't found what I was looking for. What I am working on is creating objects of clothing. I have one grandparent which is 'Clothing' three parents 'Upper_wear', 'Lower_wear', and 'Shoes' with many children such as 't-shirts', 'shorts' and 'sandals'. Currently what I have in the parents code is:
public class Upper_wear
{
private String fabric;
private int numb_zippers;
private String draw_string;
private int numb_pockets;
private int size;
private String color;
private double length_sleeves;
private int length_shirt;
private String collar;
private String hood;
private int code;
private double price;
private String name;
Upper_wear(String fabric,int numb_zippers,String draw_string,int numb_pockets,int size,String color, double length_sleeves, int length_shirt, String collar, String hood, int code, double price, String name){
this.fabric = fabric;
this.numb_zippers = numb_zippers;
this.draw_string = draw_string;
this.numb_pockets = numb_pockets;
this.size = size;
this.color = color;
this.length_sleeves = length_sleeves;
this.length_shirt = length_shirt;
this.collar = collar;
this.hood = hood;
this.code = code;
this.price = price;
this.name = name;
}
public String get_fabric(){
return fabric;
}
public int get_numb_zippers(){
return numb_zippers;
}
public String get_draw_string(){
return draw_string;
}
public int get_numb_pockets(){
return numb_pockets;
}
public int get_size(){
return size;
}
public String get_color(){
return color;
}
public double get_length_sleeves(){
return length_sleeves;
}
public int get_length_shirt(){
return length_shirt;
}
public String get_collar(){
return collar;
}
public String get_hood(){
return hood;
}
public int get_code(){
return code;
}
public double get_price(){
return price;
}
public String get_name(){
return name;
}
}
And for the children's code I have:
public class Jacket extends Upper_wear
{
Jacket(String fabric,int numb_zippers,String draw_string,int numb_pockets,int size,String color, double length_sleeves, int length_shirt, String collar, String hood, int code, double price, String name){
super(fabric, numb_zippers, draw_string, numb_pockets, size, color, length_sleeves, length_shirt, collar, hood, code, price, name);
}
}
The reason why I don't just extend clothing with all the variables is because I don't want to state if or not 'Upper_wear' has 'Shoe_laces' which is a variable in 'Shoes'. Yet, I want to gather all parent classes into one because when I go to the run class. In the for loop, I want to list out the prices of every item of Clothing and not just of a parent class. I feel that I am limited to only iterating through one parent class at a time such as what I currently have:
public class Run
{
public static void main (String[]args){
Shoes Tennis_shoes_01 = new Shoes("Canvas", 0, "yes", 10, "red and white", 0,0.5,2.5, 00001, 750.99,"Tenny shoey");
Upper_wear T_shirt_01 = new Upper_wear("Cotton", 0, "no", 0, 14, "yellow", 14.5, 15, "v-neck", "no", 00002, 990.50, "Yel-ow");)
Shoes[]In_Stock = {Tennis_shoes_01};
Upper_wear[]In_Stock_upper = {};
Lower_wear[]In_Stock_lower = {};
System.out.println("Price");
System.out.println("-------");
for(Shoes x : In_Stock){
System.out.println(x.get_name() + ": " +x.get_price());
}
for(Upper_wear x : In_Stock_upper){
System.out.println(x.get_name() + ": " + x.get_price());
}
}
What I am wanting is something more like this:
public class Want_run
{
public static void main(String[]args){
Clothing Tennis_shoes_01 = new Shoes("Canvas", 0, "yes", 10, "red and white", 0,0.5,2.5, 00001, 750.99,"Tenny shoey");
//Not sure if this is possible to have a class that's different than the constructor but I am looking for it to come from clothing class with properties of Shoes.
Clothing T_shirt_01 = new Upper_wear("Cotton", 0, "no", 0, 14, "yellow", 14.5, 15, "v-neck", "no", 00002, 990.50, "Yel-ow");
//So I want all properties to be in clothing but the ones that the childeren don't have I want to be just blank.ex. Upper_wear is blank on the shoe_laces.
Clothing[]In_Stock = {Tennis_shoes_01, T_shirt_01};
//I really want everything to be just in one list to iterate through but I can't currently do that with multiple parents of my knowledge.
for(Clothing x : In_Stock){
System.out.println(x.get_name() + ": " + x.get_price());
}
//this way I have only one for loop for every item,and for parents that don't have 'price' I am hoping would just not print.
}
}
So I want clothing to have every attribute of 'Upper_wear', 'Lower_wear', and 'Shoes', but not the parents to have every attribute of Clothing. Such that the attributes that are specific to Shoes, I wish to be blank for the other two parents when it iterates through methods specific to Shoes. I'm not sure if what I am looking for is even possible to do. If you cannot understand what I am looking for, I am sorry for being confusing. Thank you for taking your time to read this and helping me.
What you are trying to do is a classic application of polymorphism. You just need to clarify a few concepts.
Your grand parent will contain all the attributes that are common to all children, such as item ID, name, colour(s), price, etc. It should also contain common functions, such as a print() function which is what you require in your main.
All children (including parents) will introduce their specific attributes in their classes, such as hood/collar for uppers, and inner lining for jacket. They will also override (provide their own implementation of) functions they need to customize according to their needs. So, in your case, while the Clothing will have a print() function, each sub class will have its own implementation of it, in which it will print all its own properties such as number of zippers, shoelaces.
Finally, in your main, you will have a list of type Clothing, which will contain references to objects of all types you want. A parent can point to an object of a child type. For example,
Clothing c = new Jacket(...);
c.print(); // This will call the print() of class Jacket, not Clothing
I suggest reading up on dynamic polymorphism. This link contains a quick introduction and a nifty example.
I want to code a little text adventure/dungeon crawler type of game. At the moment I have the classes Creature, Player, and Enemy. The classes Player and Enemy are subclasses of Creature.
I want to make the level of the enemy dependent on the level of the player. So for example, the enemy's level should always be 1 level above the player's level. So when the player is level 4 you should only be able to face enemies which are level 5.
My idea was to put something like this in the constructor of the Enemy class:
public Enemy(String name, int hp, int atk, int exp) {
super(name, Player.getLevel + 1, hp, atk);
this.exp = exp;
}
But that is clearly not allowed. Now I have no idea how to achieve this result. I lack some basic understanding of Java, but I'm willing to learn.
My code looks like this at the moment. I left the getters and setters out for better readability.
public class Creature {
private String name;
private int level;
private int hp;
private int atk;
public Creature (String name, int level, int hp, int atk){
this.name = name;
this.level = level;
this.hp = hp;
this.atk = atk;
}
}
public class Player extends Creature {
private int currentEXP;
private int expBar;
public Player(String name) {
super(name, 1, 100, 10);
this.currentEXP = 0;
this.expBar = 50;
}
}
public class Enemy extends Creature {
int exp;
public Enemy(String name, int level, int hp, int atk, int exp) {
super(name, level, hp, atk);
this.exp = exp;
}
}
First of all, the private modifier makes level unavailable in the subclasses. To solve that, you can either make change private to protected (or nothing / default), or you can provide an accessible getter method (int getLevel() { return level; }).
Your Enemy constructor takes a level argument, so to implement the player level + 1 feature, you can simply pass player.getLevel() + 1, alternatively pass player.getLevel() and let the constructor take care of adding 1.
The method using these classes (assuming main for now) would look something like this:
public static void main(String[] args) {
Player p = new Player("Player1");
Enemy e = new Enemy("Enemy1", p.getLevel() + 1, 100, 10, 40);
}
To clarify, the reason why Player.getLevel + 1 doesn't work is because Player is a class, but you need a Player object (i.e. the result of calling new Player(...)) to refer to instance fields or methods, such as getLevel.
I am very new to programming and have a question about using variables in what I believe to be called "nested classes."
class BeginningGameTest {
int attack;
int defend;
public static class James
{
attack = 25;
defend = 15;
}
public static class Janet
{
attack = 45;
defend = 1;
}
public static class Jackson
{
attack = 10;
defend = 20;
}
public static void main(String[] args) {
System.out.prinln(James.attack);
}
}
Do I have the general idea down? I would like to save variables that are the "same" thing, but are different from class to class and are accessed differently like in the print line. I do get a few errors, what should I do to keep the same concept and still keep it fairly simple so I could understand it? Are there any easy to understand tutorials for people who are new to programming in general?
Thanks in advance!
The design of this seems incorrect.
What you're trying to go for when working in an object-oriented language is the basic model of something you wish to represent.
Those three static classes seem to represent the same type of object, so let's create a simple model for them. Think of models like a cookie-cutter. Every cookie cut with this will be the same generic "shape", but will have different characteristics about it (sprinkles, frosting beard, etc). This model should be in its own separate file.
public class Player {
private String name;
private int attack;
private int defense;
public Player(String theirName, int theirAttack, int theirDefense) {
name = theirName;
attack = theirAttack;
defense = theirDefense;
}
// create getters and setters for their attack and defense
}
To actually make use of it, you'd want to instantiate the object.
public class BeginningGameTest {
public static void main(String[] args) {
Player p1 = new Player("James", 25, 15);
Player p2 = new Player("Janet", 45, 1);
Player p3 = new Player("Jackson", 10, 20);
// interactions with the objects below
}
}
Some superb beginner resources already exist in the Java tag wiki; give those a thorough reading. Try new things out, and don't be afraid to ask (good) questions about things you don't understand.
You should create an inner class then define instances of that class within the main method.
public class BeginningGameTest {
public static void main(String[] args) {
Player james = new Player(25,15);
Player janet = new Player(45,1);
Player jackson = new Player(10,20);
System.out.println(james.getAttack());
}
}
class Player{
int attack;
int defend;
public Player(int attack, int defend){
this.attack = attack;
this.defend = defend;
}
public int getAttack() {
return attack;
}
public void setAttack(int attack) {
this.attack = attack;
}
public int getDefend() {
return defend;
}
public void setDefend(int defend) {
this.defend = defend;
}
}
You should use the concept of instances to distinguish persons, rather than defining a class for each person. You can define a single class "Person" and instantiate James, Jackson etc. To give them each different attack/defence values, you can use constructors with arguments.
I feel that you might benefit from reading an introduction to object oriented programming. Try searching for "object oriented programming".
You can go two ways about this. You could create subclasses such that James, Janet and Jackson are all classes of the same type, being BeginningGameTest. For example, James could be:
public class James extends BeginningGameTest
{
public James()
{
attack = 25;
defend = 15;
}
}
What I think you want James, Janet and Jackson to be, are not subclasses, but rather instances of the same class BeginningGameTest, like this:
BeginningGameTest James = new BeginningGameTest();
James.setAttack(25);
James.setDefend(15);
There are a few concepts you should read upon:
Classes vs instances
Inheritance
And I also implicitly introduced you to the concept of setters (and getters), typical for Java beans.
This will work:
public static class James
{
static int attack = 25;
static int defend = 15;
}
// ...
Then this would work:
public static void main(String[] args)
{
System.out.prinln(James.attack);
}
This is probably a better design:
public class Player()
{
public static enum NAME { JAMES, JANET };
int attack, defend;
public Player(NAME name)
{
switch (name)
{
case JAMES:
attack = 25;
defend = 15;
break;
// ...
}
}
public static void main(String[] args) throws Exception
{
System.out.println(new Player(NAME.JAMES).attack);
}
}
This is a better design for realistic requirements: (allowing run-time creation of players)
int attack, defend;
String name;
public Player(int attack1, int defend1, String name1)
{
attack = attack1;
defend = defend1;
name = name1;
}
What you can simply do is create different objects of your class that will hold different values of variables attack and defend. Here is the code for the same.
/* package whatever; // don't place package name! */
class Main
{
int attack,defend;
public Main(int attack,int defend)
{
this.attack=attack;
this.defend=defend;
}
public void show()
{
System.out.println("attack: "
+attack+" defend: "+defend);
}
public static void main (String[] args) throws java.lang.Exception
{
Ideone James = new Main(125,15);
James.show();
Ideone Janet = new Main(45,1);
Janet.show();
Ideone Jackson = new Main(10,20);
Jackson.show();
}
}