Defining class field and calling parent's constructor - java

These are two classes of code that I wrote.. the problem here is I am not sure how to define class fields to represent Grass, fire and water as a Type using static..
Also I am not sure if I had used the super function the right way.. How do I properly call the parent's constructor so that I dont have to re define "knockedOut boolean" and be able to use Fire as the type?
Question could be confusing but I am not sure how to explain it better :( sorry
public abstract class Pokemon {
private String name;
private String type;
private int attack;
private int health;
private boolean knockedOut;
static private String Grass;
static private String Water;
static private String Fire;
public Pokemon (String n, String t, int a, int h) {
name = n;//state
type = t;//state
attack = a;//state
health = h;//state
knockedOut = false;
}
public abstract int takeDamage(Pokemon enemy);
public String toString() {
return "}";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public int getAttack() {
return attack;
}
public void setAttack(int attack) {
this.attack = attack;
}
public int getHealth() {
return health;
}
public void setHealth(int health) {
this.health = health;
}
public boolean isKnockedOut() {
return knockedOut;
}
public void setKnockedOut(boolean knockedOut) {
this.knockedOut = knockedOut;
}
}
public abstract class Charizard extends Pokemon {
private static String Fire;
private int attackFire;
private int healthFire;
private static String Water;
private static String Grass;
public Charizard(int a, int h) {
super("Charizard", Fire, a, h);
attackFire = a;
healthFire = h;
}
public int takeDamage(Pokemon enemy){
int enemyAttack = enemy.getAttack();
if(enemy.getType().equals(Water)){
enemy.setHealth(enemy.getHealth()-attackFire/2);
healthFire = healthFire-enemy.getAttack()*2;
if(enemy.getHealth()<=0){
enemy.setKnockedOut(true);
}
}
else if(enemy.getType().equals(Fire)){
enemy.setHealth(enemy.getHealth()-attackFire/2);
healthFire = healthFire-enemy.getAttack()*2;
if(enemy.getHealth()<=0){
enemy.setKnockedOut(true);
}
}
else if(enemy.getType().equals(Grass)){
enemy.setHealth(enemy.getHealth()-attackFire/2);
healthFire = healthFire-enemy.getAttack()/2;
if(enemy.getHealth()<=0){
enemy.setKnockedOut(true);
}
if(healthFire <=0){
Charizard.set = true;
}
}
return enemyAttack;
}
}

You want to declare your different types like this:
static public final String GRASS= "Grass";
static public final String WATER = "Water";
static public final String FIRE = "Fire";
(I'm following the established convention here that fields declared static, public, and final should have names in all uppercase letters.)
By declaring these fields public, any other classes (including those that extend Pokemon, such as Charizard) that might need to test the type of a Pokemon can use them. By declaring them final, nobody can change them even though they are public. By giving them initial values, you make them actually useful for distinguishing different types of Pokemon, as well as avoid the inevitable NullPointerException that would happen the first time you executed something like p.getType().equals(Pokemon.FIRE)
As for knockedOut, it looks like you're handling it the right way. The field knockedOut is private in Pokemon but you've provided public getter and setter methods that other classes can (and do) use to access it.

Related

enum not getting called in constructor

I'm trying to build some Dota2-like classes, with simple details. I got stuck at one point where I need my hero's attribute in Main, but the constructor for it doesn't work. Here is the code for Hero class:
enum attribute {
Strength, Intelligence, Agility
};
public class Hero extends Unit {
private int level;
private static int str;
private static int intl;
private static int agi;
private static attribute heroAttribute;
public attribute getAttribute() {
return heroAttribute;
}
private static int attributeDamage() {
if (heroAttribute == attribute.Strength)
return str;
else if (heroAttribute == attribute.Intelligence)
return intl;
else
return agi;
}
public Hero(int level, int str, int intl, int agi, attribute heroAttribute) {
super(200 + 20 * str, attributeDamage());
System.out.println("A hero has been spawned.");
}
}
and the Main:
public class Main {
public static void main(String[] args) {
Hero h1= new Hero(25,400,30,30,attribute.Agility);
System.out.println(h1.getAttribute());
}
}
What I get is that I have null "attribute" value.
Try put this attributes without the static, and initiate these attributes...
private int str;
private int intl;
private int agi;
private attribute heroAttribute;
public Hero(int level, int str, int intl, int agi, attribute heroAttribute) {
this.str = str;
this.intl = intl;
this.ai = agi;
this.heroAttribute = heroAttribute;
super(200 + 20 * str, attributeDamage());
System.out.println("A hero has been spawned.");
}
i suggest you to create new enum class that containt those 3 attribute and then, implement them.
by the way, all enum entities should be upper case like: STRENGTH, AGILITY, INTELLIGENT
public enum HeroAttribute {
STRENGTH("str"),
AGILITY("agi"),
INTELLIGENT("intl");
private String literal;
HeroAttribute(String literal) {
this.literal = literal;
}
public String getLiteral() {
return literal;
}
}

Simplest Java, I have simple code with Bicycle and Human

Human has String named mName which is used in constructor, and Bicycle has String mOwner, I need to link one to another, Im new in this (programming) so Im not sure about what I should read about to understand better.
I created findOwner method that returns me mOwner, and declared mName "Dave" in Human's constructor... can I somehow make findOwner method return me current Human object's value?
sorry for my English and thank you)
Here's my code:
public class Human {
public String mName;
public Human(String name){
mName = name;
}
}
/* this one is my Bicycle */
public class Hecaniv {
private String mOwner;
private int mSpeed;
private int mShift;
private int mWheels;
public Hecaniv(int shift, int speed, int wheels){
mSpeed = speed;
mShift = shift;
mWheels = wheels;
}
public int currentSpeed(){
return mSpeed;
}
public int currentShift(){
return mShift;
}
public int numOfWheels(){
return mWheels;
}
public String findOwner(){
return mOwner;
}
}
Instead of having the name of the owner, you can just have the owner object itself as a field of Bicycle.
class Human {...}
class Bicycle {
Human owner;
public Bicycle(Human owner) {
this.owner = owner;
}
public Human findOwner() {
return owner;
}
}

Can a static final field be initialized in subclasses? If so, how?

I need to write some code which is as follows:
public class Person {
public static final String NAME;
public Person(String NAME) {
this.NAME = NAME;
}
}
public class Player extends Person {
public Peter(String name) {
super(name);
}
}
It's basically, I want the Player class to have a static final field called NAME, that is being initialized somewhere else, without manually writing in every class public static final String NAME = "Peter".
Is it possible?
As it has been said in the comments, you have poorly declared your NAME variable. In actuality, you don't want it to be static (although you can keep the final modifier, if you want). Your code should, instead, be something along the lines of:
public class Person {
public final String name;
public Person(String name) {
this.name = name;
}
}
public class Player extends Person {
public Player(String name) {
super(name);
}
}
Every person should have their own name; you don't want all objects to be sharing one NAME field
I do not know if I fully understand your question, but I think you have a few mistakes in your code. Like declare name of person as static variable, because static variables are often used as variables for the entire class, and if you changed the name, would change the name to the entire class, not for one instance. Also final is wrong, because you cannot set final variable.
I would do something like this:
public class Person {
private String name;
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Override
public String toString() {
return String.format("Person: %s", this.getName());
}
}
public class Player extends Person{
public Player(String name) {
super(name);
}
public String toString(){
return String.format("Player: %s", this.getName());
}
}
public class Match {
private Player player_one;
private Player player_two;
public Match(Player player_one, Player player_two) {
this.player_one = player_one;
this.player_two = player_two;
}
public Player getPlayer_one() {
return player_one;
}
public void setPlayer_one(Player player_one) {
this.player_one = player_one;
}
public Player getPlayer_two() {
return player_two;
}
public void setPlayer_two(Player player_two) {
this.player_two = player_two;
}
#Override
public String toString() {
return String.format("Right now are playing %s VS %s",player_one.getName(), player_two.getName());
}
}
public class PlayerTest {
public static void main(String[] args) {
Player peter = new Player("Peter");
Player anna = new Player("Anna");
Match tennisMatch = new Match(peter, anna);
System.out.println(tennisMatch.toString());
}
}
I static field (variable) only exists once for all instances of your class. Therefore what you try does not work by design.
What value would you expect the field to have after you created three different instances of this class using different parameters?
A final variable cannot be changed once it got initialized. For static variables this happens before the first instance of the class is even constructed. At the moment the constructor is executed the field cannot be changed anymore.
To initialize a static final variable you have to assign a value directly at the definition using the = operator or you have to do it in a static initializer which looks like this:
public class FooBar {
public static final String STATIC_VARIABLE;
static {
STATIC_VARIABLE = "Hello World";
}
}
You can make it like this:
private static final NAME;
public Player(String name){
NAME = name;
}
A final varible can be initialized once only if it wasn't initialized yet.
So in this way the constructor is helping you make it.

I don't understand private variables?

There is nothing wrong with the code, but I don't understand why you have to create a private String name, and then equals that string with the string from method i.e. name = n.
public class Person {
private String name;
public Person (String n) {
name = n;
}
public String getName() {
return name;
}
public boolean sameName(Person other) {
return getName().equals(getName());
}
}
A private variable can't be accessed from outside the class, but only by the methods inside the class so it's safer

What inheritance for my Object class to weapon class & armor class

I'm making a little game with a hero having inventory filled with object.
public enum Objects_type
{
WEAPON,
ARMOR
}
public abstract class Objects_class
{
protected String name;
protected Objects_type type;
public Objects_class(String name, Objects_type type)
{
this.name = name;
this.type = type;
}
}
public abstract class Armor extends Objects_class{
int life = 0;
int res_fire = 0;
public Armor(String name, int largeur, int hauteur) {
super(name, Objects_type.ARMOR);
}
}
public abstract class Weapon extends Objects_class
{
protected int dmg_fire = 0;
public Weapon(String name) {
super(name, Objects_type.WEAPON);
}
}
public class StickOfJoy extends Weapon{
public StickOfJoy() {
super("Stick of Joy");
dmg_fire = 2;
}
}
public class ArmorOfPity extends Armor{
public ArmorOfPity()
{
super("Armor of Pity");
life = 30;
}
}
Then I have functions like :
Hero.getObject (Objects_class obj)
{
if (obj.getType == Objects_type.WEAPON)
....
}
I'd like to be able to consider the Objects_class obj as a Weapon but of course it's not possible (casting a mother to its child) so it makes me think my inheritance structure is bad.
What should I've done ?
David Conrad has some good points I recommend you read through that I won't repeat here but here is how I would do it.
Suppose you have a character that is roaming around in your game world picking up items, there can be many different items, some so different from each other in behavior they warrant the creation of a new subclass (like picking up boots vs picking up wings).
Once you pick up an item, you have the choice of letting the hero try and see what kind of item was picked up (instanceof, enums, whatever) or you can let the item figure out where it is supposed to go.
Here is a simplified example where the player has only two inventory slots, a weapon and an armor. Notice how easy it is to simply add a new item (like a health potion, or a superdupernewspecialweapon) to the mix without having to change anything in the player or do casting.
public abstract class Item {
private int ID;
private static int IDCounter;
private String name;
public Item(String name) {
this.name = name;
this.ID = IDCounter;
IDCounter++;
}
public int getID() {
return ID;
}
public String getName() {
return name;
}
public abstract void attachToPlayer(Player player);
}
public class Armor extends Item {
private int life;
private int res_fire;
public Armor(String name) {
super(name);
}
#Override
public void attachToPlayer(Player player) {
// Only equip if upgrade
if (player.getArmor().res_fire > this.res_fire)
player.setArmor(this);
}
}
public class Weapon extends Item {
private int dmg_fire;
public Weapon(String name) {
super(name);
}
// ...stuff
#Override
public void attachToPlayer(Player player) {
// Only equip this if upgrade? You decide the logic
if(player.getWeapon().dmg_fire>this.dmg_fire)
player.setWeapon(this);
}
}
public class SuperSpecialWeapon extends Weapon {
private float bonusHealthModifier = 1.0f;
public SuperSpecialWeapon(String name) {
super(name);
}
#Override
public void attachToPlayer(Player player) {
// This bonus adds +100%HP bonus to the player!
int hp = (int) ((1 + bonusHealthModifier) * player.getHealth());
player.setHealth(hp);
player.setWeapon(this);
}
}
public class Potion extends Item {
private int health = 100;
public Potion() {
super("HealthPotion");
}
#Override
public void attachToPlayer(Player player) {
// If the player has room for one more potion, pick this up
Potion[] potions = player.getHealthPotions();
for (int i = 0; i < potions.length; i++) {
if(potions[i]==null){
potions[i] = this;
break;
}
}
}
// ..other stuff
}
And finally the player
public class Player {
private Armor armor;
private Weapon weapon;
private String name;
private Potion[] healthPotions = new Potion[10];
private int health;
public Player(String name) {
this.name = name;
}
public Armor getArmor() {
return armor;
}
public Weapon getWeapon() {
return weapon;
}
public void setWeapon(Weapon weapon) {
this.weapon = weapon;
}
public void setArmor(Armor armor) {
this.armor = armor;
}
public void setHealth(int health) {
this.health = health;
}
public int getHealth() {
return health;
}
public Potion[] getHealthPotions() {
return healthPotions;
}
}
There is no need of Objects_type, since objects in Java know what type they are, and their type can be tested with the instanceof operator. You say that you cannot cast "a mother to its child", but it is possible to downcast an object to a child type. In general, it could throw a ClassCastException, but if you have tested it first with instanceof, that won't happen.
public class Objects_class {
protected String name;
public Objects_class(String name) {
this.name = name;
}
}
public class Armor extends Objects_class {
int life = 0;
int res_fire = 0;
public Armor(String name, int largeur, int hauteur) {
super(name);
}
}
public class Weapon extends Objects_class {
protected int dmg_fire = 0;
public Weapon(String name) {
super(name);
}
}
public class Hero {
public void getObject(Objects_class obj) {
if (obj instanceof Weapon) {
Weapon weapon = (Weapon) obj;
wield(weapon);
}
if (obj instanceof Armor) {
Armor armor = (Armor) obj;
wear(armor);
}
}
}
I have removed the abstract modifier from the classes since there is no need of it, but perhaps you wanted it to ensure that those base classes are never instantiated. Also, I would change the name of Objects_class to something like Item since the words Object and class have particular meanings that could cause confusion. I would also rename Hero's getObject method to something like pickUpItem since it isn't a getter, in the Java sense.

Categories