Extended class and static variable - java

I've DynamicObject, Player, Enemy classes
public class DynamicObject {
protected static float speed;
}
public class Player extends DynamicObject {
/*some code*/
Player.speed = 100;
}
public class Enemy extends DynamicObject {
/*some code*/
Enemy.speed = 50;
}
And always speed value is overridden. Of course I can create new speed variable in Player and Enemy, but then the existing DynamicObject class is pointless. I want to have different speed values on each class. All objects of current class will have the same speed. How I should make it in correct way?

The speed variable should not be static. Otherwise it won't be bound to any of the instances of the DynamicObject class, nor any of it's subclasses instances.
If you want to have a different speed value for each of the subclasses, you can do:
public class DynamicObject {
protected float speed;
public DynamicObject(float speed) {
this.speed = speed;
}
public float getSpeed() {
return this.speed;
}
}
public class Player extends DynamicObject {
/*some code*/
public Player(float speed) {
super(speed);
}
}
public class Enemy extends DynamicObject {
/*some code*/
public Enemy(float speed) {
super(speed);
}
}

If every DynamicObject has a speed, and the speed is the same for every instance of, for example, Player, then you should have
public abstract int getSpeed();
in DynamicObject, and
#Override
public int getSpeed() {
return 100;
}
in Player.
If you need to have access to the constant speed returned for evry instance of Player without instantiateing a Player, just use
public static final int CONSTANT_PLAYER_SPEED = 100;
#Override
public int getSpeed() {
return 100;
}
and use Player.CONSTANT_PLAYER_SPEED to access the speed of all players.

Remove the static from that variable, if a variable is static, it's belong to the class, not to instances.
And making a static variable protected doesn't make any scene, since, inheritance and static are totally different.
protected float speed;

You could also have an abstract method, which would mean that you would always have to override it in your sub classes.
public abstract class Dynamic {
protected float speed;
abstract void setSpeed();
}
public class Player extends Dynamic{
#Override
void setSpeed() {
this.speed=50;
}
}

Related

How I can implements method from one class in another class

I have class Shape2D, in that class I have method that calculate circle area circleArea, also I have class CircleArea where I store all atributes that I need for my method. Also, my class CircleArea extends class Shape2D. So, How I can implement my method from class Shape2D into class CircleArea.
This is my Shape2D class:
public class Shape2D {
public static void areaCircle(Circle c) {
double circleArea = Math.pow(c.getR(), 2) * Math.PI;
}
}
And this is my Circle class:
public class Circle extends Shape2D {
private double r;
public Circle() {
}
public double getR() {
return r;
}
public void setR(double r) {
this.r = r;
}
}
To implement one of the methods from the Shape2D class in the Circle class, you could do:
Shape2D.areaCircle(circleObject);
The above line can be called in the Circle class. Don't forget to pass in an actual circle object into the function.
You have a static method inside of 2D shape, meaning you can use it in any class without having 2DShape instantiated. This also means that you do not need the circle class to extend 2DShape to use this method, but I imagine you are going for that parent child relationship for the OO paradigm. If you don't want the method to be called from any class, remove static from the method. If you wish to call it statically inside of your Circle class constructor, first instantiate r to something, and then pass it into the static method call.
public class Circle extends Shape2D {
private double r;
public Circle() {
r=1;
Shape2D.areaCircle(this);
}
public double getR() {
return r;
}
public void setR(double r) {
this.r = r;
}
}
Note that your static function doesn't actually return anything, so it calculates the area and the value is lost. You can fix this inside of shape2D by changing the return type of circleArea to double in stead of void, and returning the result appropriately.
public static double areaCircle(Circle c) {
double circleArea = Math.pow(c.getR(), 2) * Math.PI;
return circleArea;
}
or non-statically, and protected in stead of public (either will work)
protected double areaCircle(Circle c) {
double circleArea = Math.pow(c.getR(), 2) * Math.PI;
return cricleArea;
}
If you wanted to do the same thing, but removed the static flag from the method, then you can use super to call parent methods.
public class Circle extends Shape2D {
private double r;
public Circle() {
r=1;
super.areaCircle(this);
}
public double getR() {
return r;
}
public void setR(double r) {
this.r = r;
}
}
Now if you wanted to actually store the area inside of this circleObject, I would create another attribute for the Circle class, and modify your constructor as such. Perhaps even adding a constructor that takes an int argument for radius (or in the future, an area with some way to differentiate the two that can get the radius value).
public class Circle extends Shape2D {
private double r;
private double area;
//Default Constructor
public Circle() {
r=1;
this.area = super.areaCircle(this);
}
//Radius constructor
public Circle(double rad) {
this.r = rad;
this.area = super.areaCircle(this);
}
public double getR() {
return r;
}
public void setR(double r) {
this.r = r;
}
}
It's also worth mentioning that you should look at the scope of these methods you create, and what you are trying to accomplish with them. For instance, you have your circleArea method defined as public, when it could be defined as protected and function similarly for this case. Protected means that the method can be used inside of the class, as well as all subclasses (children of the parent class, like circle). You can read information about these closures here. Also, when working with object inheritance, you should get into the habit of using the this keyword to reference which methods/attributes you actually wish to retrieve. Info on this keyword.
I realize this is a lot to take in, but if you have any questions feel free to comment!

Use a field or override a method to define a value of an abstract class

When setting a value of a parent class, which way is more preferable:
Set a field
public abstract class Weapon {
final Integer damage;
}
public class Knive extends Weapon {
public Knive(){
damage = 100;
}
}
Override a method
public abstract class Weapon {
public abstract int getDamage();
}
public class Knive extends Weapon {
#Override
public int getDamage(){
return 100;
}
}
Or is it just personal taste?
I think it depend on the situation. Both examples correct.
Your fist approach is more preferably when you have inheritance, and the're general logic for number of child classes. BUT, do make your property protected.
Second approach, is more suitable when you use light classes, like strategies without default implementation. In this case you can change your parent class to interface.
public abstract class Weapon {
protected final Integer damage;
protected Weapon(Integer damage) {
this.damage = damage;
}
// more logic here
}
public class Knive extends Weapon {
public Knive(){
super(100);
}
}
OR
public interface Weapon {
Integer getDamage();
}
public class Knive implements Weapon {
// light-weight strategy
public Integer getDamage() {
return 100;
}
}
The two ways are not opposed. You could use the one, the second or both.
But these don't have the same intention.
A constructor with parameter allows to value the created instance with this parameter : it sets the instance state.
While specifying a method as abstract allows to define a contract that subclasses have to respect. In this way the base class or any other class can rely on this method to perform some logic. The template method uses this idea.
Suppose you have a class Warrior that has a Weapon as field, you could compute the damage performed by a Weapon thanks to this method that each subclass will have to implement :
public class Warrior{
private Weapon weapon;
// ...
public void attack(Warrior otherWarrior){
otherWarrior.receiveAttack(weapon.getDamage());
}
}
Now nothing prevents you to store the damage information that you received in Weapon subclass :
public class Knive extends Weapon {
private int damage;
public Knive(int damage){
this.damage = damage;
}
#Override
public int getDamage(){
return damage;
}
}
As explained earlier the two approaches are not opposed at all.
I don't think this is about personal taste but about the reusability, correctness, and uniformity across extending classes.
public abstract class Weapon {
protected Integer damage;
public void setDamage(Integer damage){
this.damage = damage;
}
public Integer getDamage(){
return this.damage;
}
}
public class Knive extends Weapon {
public Knive(){
setdamage(100);//or damage = 100;
}
}
The setter and getter would be the same for all of the extending classes. In case if you want to explicitly override the setter and getter for some specific result, you could override it.
It depends a lot on when and where do you want to set the value, but note that an abstract class can have field, methods and even constructors, it just can't be instantiated. so for the example you provided I prefer using this:
abstract class Weapon{
private int damage;
public Weapon(int damage) {
this.damage = damage;
}
public int getDamage() {
return damage;
}
}
class Knife extends weapon{
//damage as a parameter
public Knife(int damage) {
super(damage);
}
//damage as a default value
public Knife(){
super(100);
}
}
then you can use it this way:
Weapon knife = new Knife(100);
Weapon defaultKnife = new Knife();
System.out.print(knife.getDamage()); --->100
You can also have getter and setter methods in the parent class and you don't even have to override anything in the child class.

There is no available constructor in the superclass (Java)

I have one super class, which called game that. It looks like this:
import java.util.ArrayList;
public class Game {
private ArrayList<Enemy> enemies = new ArrayList<Enemy>();
private ArrayList<Tower> towers = new ArrayList<Tower>();
private int corridorLength;
private int currentPosition = 0;
public Game(int corridorLength){
this.corridorLength = corridorLength;
}
public void addTower(int damage,int timeStep){
this.towers.add(new Tower(damage,timeStep)); // Add tower with
current position corrdor length
}
public void addEnemy(int health, int speed){
this.enemies.add(new Enemy(health,speed));
}
public void advance(){
this.currentPosition = this.currentPosition + 1;
if(this.currentPosition == this.corridorLength){
System.out.println("Game Over");
}
}
public void printDamage(){
System.out.println(this.towers.get(this.currentPosition));
}
}
The main focus is on the public void addTower(int, int)
So, I have a subclass called Tower:
public class Tower extends Game {
public Tower(int damage, int timeStep){
super.addTower(damage,timeStep);
}
public void getDamage(){
super.printDamage();
}
}
And subclass of the Tower subclass called Catapult:
public class Catapult extends Tower {
public Catapult(){
super(5,3);
}
}
I am new to Java and can't see what am I doing wrong here. Why do I need a default constructor for the Tower in the Game?
You need to explicitly declare default constructor in Game class.
public Game (){}
Since, Object instantiation chained to Object class during that, it will call its super class constructor. You have explicitly declared arg-constructor in Game, so default constructor won't be added automatically.

private static list which contains all object constructed

I'm writing animation program, in which many balls are running around and bouncing.
I made Ball class which represents ball's behaviour.
When I implement ball's collisioin with another ball,
I have to check the all other balls.
So I made this class.
public class Ball{
private static final List<Ball> allBalls;
static{
allBalls = new ArrayList<>();
}
private Ball(){}
public static Ball getNewBall(){
Ball ball = new Ball();
allBalls.add(ball);
return ball;
}
public void collision(){
for(Ball b : allBalls){
//check whether b is colliding with me
//and if colliding, change speed of me and b.
}
}
}
Is this kind of design (to hold all objects in private static list) good or bad ?
What you should have is a BallManager class that will handle that stuff.
public class BallManager {
private static BallManager instance = new BallManager();
private BallManager(){}
public static BallManager getInstance() {
return instance;
}
public List<Ball> ballsInPlay = new ArrayList<>();
public void createBall(int x, int y) {}
public void checkCollisions() {
// loop ball list and check collisions
// perform cleanup based on collisions
}
private void ballCleanup(){}
}
public class Ball{
public Ball(){}
public void collision(Ball other){}
}
NOTE: Changed from static class to singleton. Also, fixed the compilation error by adding () after checkCollisions method
Create Singleton BallManager using enum.
enum singleton are best to use.
Improving the previous answer.
public enum BallManager {
INSTANCE;
public List<Ball> ballsInPlay = new ArrayList<>();
public void createBall(int x, int y) {}
public void checkCollisions() {
// loop ball list and check collisions
// perform cleanup based on collisions
}
private void ballCleanup(){}
}
public class Ball{
public Ball(){}
public void collision(Ball other){}
}

How to create variables in java interfaces

I'm making a game with different types of building. I'm making an interface for each type. Some buildings have more than 1 type.
I have this code:
public interface DefenseBuilding {
int range;
int damage;
public void shoot ();
}
It gives me an error on the 2 variable declarations (range & damage). The error being something along the lines of "Final variable may not be initialised"
It works if I assign the variable in the interface, but I don't want to do that.
I can't just extend a class, because - as said earlier - some buildings need more than 1 type. Classes can only extend 1 other class so I need to use interfaces.
What I'm asking is, is there a way to have variables in an interface without having to initialise the variable inside the interface?
The whole point of interfaces is to specify as interface - i.e. how will your classes interface with client classes. Instance variables are clearly not part of any interface at all.
Instead, try this:
public interface DefenseBuilding {
public void shoot ();
}
and this:
public abstract class AbstractDefenseBuilding implements DefenceBuilding {
protected int range;
protected int damage;
}
edit:
Your classes should now extend AbstractDefenseBuilding, so they will inherit the variables. They also indirectly implement DefenceBuilding so they'll still be forced to implement the shoot() method (unless they are also abstract)
You can use a property method aproach.
public interface DefenseBuilding {
public void setRange(int range);
public int getRange();
public void setDamage(int damage);
public int getDamage();
public void shoot ();
}
Then in your class
public MyClass implements DefenseBuilding{
int range;
int damage;
public int getRange() {
return range;
}
public void setRange(int range) {
this.range = range;
}
public int getDamage() {
return damage;
}
public void setDamage(int damage) {
this.damage = damage;
}
public void shoot (){...}
}
All variables in Interface are static and final. Hence, unless initialized, compiler will keep giving an error that it is not initialized. This is enforced because interface cannot be instantiated and therefore any variable should be of static in nature and cannot be changed.
If your intention is to define class variables, do as NickJ suggested.
Interfaces define behavior but not state (other than constants). Protected variables are a potential danger to proper encapsulation of data (an object should hide its data and provide access through methods unless there is a very compelling reason not to). An alternative would be the following:
public interface DefenseBuilding {
public void shoot();
public int getRange();
public int getDamage();
}
It's also VERY common to provide an abstract class that partially implements the interface:
public abstract class AbstractDefenseBuilding implements DefensBuilding {
private int range;
private int damage;
public AbstractDefenseBuilding(int range, int damage) {
this.range = range;
this.damage = damage;
}
public int getRange() {
return range;
}
public int getDamage() {
return damage;
}
}

Categories