Inherit subclass variable by super in Java - java

This title does not express what I mean quite well, I apologize, but it is difficult for me to express it better, because I don't quite understand what's going on due to lack of OOP knowledge and experience.
I am building a basic game, which is going to have the player run around a board with a 'hero' sprite, being chased by a 'badGuy' sprite. Because the two sprites share 5-6 methods, I decided to make a super class 'Sprite' and two classes 'Hero extends Sprite' and 'BadGuy extends Sprite'. Now for all those super methods, including stuff like:
getX(); getY(); getBounds(); render();
to work I need the super class to track the location of 'Hero' and 'badGuy'. So I implemented 'Sprite' like this:
package game.sprites;
import javafx.scene.shape.Rectangle;
import javax.swing.*;
import java.awt.*;
public class Sprite {
public static int x;
public static int y;
private int imageWidth;
private int imageHeight;
public Image image;
public Sprite(int x, int y) {
Sprite.x = x;
Sprite.y = y;
}
public static void render(Graphics g, Image image) {
g.drawImage(image, x, y, null);
}
public Image loadImage(String filePath) {...}
public void getImageDimensions() {...}
public Rectangle getBounds() {
return new Rectangle(x, y, imageWidth, imageHeight);
}
public Image getImage() {
return image;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
}
The problem kicks in when I want to give different starting coordinates to 'Hero' and 'BadGuy' objects. Currently if I set them different, the second call of 'Sprite' overrides the first and both start at the same spot (which would be very frustrating if your goal is to run from 'badGuy').
'Hero' and 'BadGuy' are currently initialized this way:
public class BadGuy extends Sprite {
public BadGuy() {
super(x, y);
initBadGuy();
}
public void initBadGuy() {
loadImage("resources/craft.gif");
getImageDimensions();
x = 860; // Hero x = 20;
y = 560; // Hero y = 20;
}
So what I tried to do is make the subclasses override Sprite's x and y. But I googled it and I understand that this is very bad idea and thus it is not possible. So my question is something like: How can I make 'Sprite' inherit subclass 'x' and 'y' variables and perform the necessary methods when the certain subclass is called.
Now that I look at it - both the constructor and init<>() are identical for the subclasses, so maybe they can be implemented in 'Sprite' instead? Just a thought, but I'm getting quite confused already, so no idea.
Thanks.

You are getting this problem because x and y are declared as static fields in your Sprite class.
From JLS 8.3.1.1. static Fields
If a field is declared static, there exists exactly one incarnation of the field, no matter how many instances (possibly zero) of the class may eventually be created. A static field, sometimes called a class variable, is incarnated when the class is initialized (§12.4).
Use following code:
Change your Sprite Class like below:
public class Sprite {
public int x;
public int y;
....
}
BadGuy class:
public class BadGuy extends Sprite {
public BadGuy(int x, int y) {
super(x, y);
...
}
....
}
Hero class:
public class Hero extends Sprite {
public Hero(int x, int y) {
super(x, y);
...
}
....
}
From Main class do following: //From where you want to create Object of both classes
public static void main(String[] args){
Hero hero = new Hero(20,20);
BadGuy badGuy= new BadGuy(860,560);
}

Related

Java - rectangle getBounds();

Today I decided to make a top down based game using Java. I have already made the window and included the Jframe. But I found a problem on creating the GameObject in the Rectagle GetBounds(); . I don't know what really is because I am a beginner and I know the basics of java :( .
If anyone can help me to resolve this problem I give the code example below:
package example;
import java.awt.Graphics;
import java.awt.Rectangle;
public abstract class GameObject {
protected int x, y;
protected float velX = 0, velY = 0;
public GameObject(int x, int y) {
this.x = x;
this.y = y;
}
public abstract void tick();
public abstract void render(Graphics g);
public abstract void Rectangle getBounds();
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public float getVelX() {
return velX;
}
public void setVelX(float velX) {
this.velX = velX;
}
public float getVelY() {
return velY;
}
public void setVelY(float velY) {
this.velY = velY;
}
}
The code causes the following errors:
Illegal modifier for the field Rectangle; only public, protected,
private, static, final, transient & volatile are permitted Return type
for the method is missing Syntax error, insert ";" to complete
FieldDeclaration This method requires a body instead of a semicolon
void is an invalid type for the variable Rectangle
Note: I'm using Java SE-8 and Eclipse Oxigen.
If you want to create an instance of GameObject (like this: new GameObject()) then GameObject class must not be abstract.
You cannot create an instance of abstract class. You can only create a class that inherits from abstract class and implements all or some methods.
Here you can either implement methods tick(), render(Graphics g) and getBounds() or create a new class that inherits from GameObject (public class GameObjectImp extends GameObject) and implement methods there.

Understanding when to use Inheritance, and how [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
I'm currently not sure how inheritance would best fit into my Java program, or whether it would best be implemented using interfaces or not. An example of the context I'm talking about is below.
Imagine that I'm making a game, and I have enemies in my game. These enemies all have various variables and behaviours in common, but are all unique in some way. For example, Enemy1,
class Enemy1 {
float x, y, width, height;
public Component(float x, float y, float width, float height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
public void AI() {
//some code
}
}
and Enemy2,
class Enemy2 {
float x, y, width, height;
public Component(float x, float y, float width, float height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
public void AI() {
//some different code
}
}
So with these two separate enemies, I understand (or at least believe) that I can change Enemy2 to resemble
class Enemy2 extends Enemy1 {
#Override
public void AI() {
//some different code
}
}
But, what now if I have five different types of AI code each enemy could have, and then instead of defining the code for the AI behaviour within the class for each enemy, I want to have another class which contains all of the AIs, allowing me to extend/implement the AI class/interface and select the one I want.
I'm not sure what the best way to do any of this is. In a nutshell, I want to have different enemies which share properties, each which would have similar, but different, functions within them (such as the AI code), but overall would still be quite unique. Would it be most efficient to do this with only classes? Interfaces? And how would I go about doing this? Would I have a class drawing off a class drawing off a class? Or just a class extending a class and implementing an interface at the same time? I'm not quite sure what the best inheritance structure would be to use.
Sorry if I have made any fundamental misunderstandings or mistakes.
Any help would be much appreciated.
You could make an abstract AI class with a process function:
abstract class AI
{
public abstract void process(Enemy en);
}
And then you can extend it.
class AISipleMovement extends AI
{
#Override
public void process(Enemy en)
{
en.moveRandomly(); //Insert actual code here
}
}
or just:
class AIStayFrozen extends AI
{
#Override
public void process(Enemy en)
{
}
}
And in the Enemy class:
class Enemy1 {
float x, y, width, height;
AI ai;
public Enemy1(float x, float y, float width, float height, AI ai) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.setAI(ai)
}
public void setAI(AI aiIn)
{
this.ai = aiIn;
}
public void AI() {
ai.process(this);
}
}
Of course, this is minimal example, you should cover if ai isn't null to prevent NullPointerException and similar stuff.
class Enemy2 extends Enemy1
Does that semantically make sense though? Is Enemy2 also an Enemy1? Knowing nothing of the game, let's say Enemy1 is a Dire Wolf and Enemy2 is a Bear. A Bear is not also a Dire Wolf, so this structure would make no sense. But if Enemy2 is, say, a Dire Wolf Pack Leader then this would make sense, because it is also a Dire Wolf.
I want to have another class which contains all of the AIs
That just sounds weird to me. One object which contains all of the logic for your other objects, and they pull their logic from it? That sounds pretty close to the "God object" anti-pattern. You should probably keep the logic on the objects which own it.
Based on the description, it sounds like you want an abstract class. A base Enemy class which itself can't be instantiated, but which holds the commonalities of all enemies. Something like:
abstract class Enemy {
float x, y, width, height;
public Enemy(float x, float y, float width, float height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
abstract public void AI();
}
Then any enemy would inherit from that:
class DireWolf extends Enemy {
public DireWolf(float x, float y, float width, float height) {
super(x, y, width, height);
}
public void AI () {
//...
}
}
Indeed, any class which extends Enemy would be required by the compiler to implement AI(). So the common functionality and common interface is held in the abstract base class, and each class which inherits from it will provide its implementation to that interface.
EDIT
This approach requires a constructor for every child class. This may work to your advantage, for example, if every DireWolf is the same size, the constructor could look like this:
public DireWolf(float x, float y) {
super(x, y, 64, 64);
}
Then you could initialize your wolf as follows:
Enemy wolf = new DireWolf(0, 0);

Is there any benefits of using generic parameter rather than using the base class parameter?

Please review the code below:
abstract class Shape {
protected double x;
protected double y;
public Shape(double x, double y) {
this.x = x;
this.y = y;
}
abstract protected void draw();
}
class Circle extends Shape {
public Circle(double x, double y, double r) {
super(x, y);
this.r = r;
}
protected double r;
protected void draw() {
System.out.println(String.format("Draw Circle. %f %f %f", x, y ,r));
}
}
class RenderEngine {
public static void draw1(Shape s) {
s.draw();
}
public static <T extends Shape> void draw2(T t) {
t.draw();
}
}
public class Runner {
#Test
public void run() {
Circle c = new Circle(1,2,3);
RenderEngine.draw1(c);
RenderEngine.draw2(c);
}
}
What's the difference between draw1() and draw2()? Which one is better? Does draw2() have more extensibility? Or does draw2() have better performance?
There is no difference in your scenario, because the type of the object being drawn is consumed internally in the drawX method.
It would make a difference if your method were to use T in some other context, such as returning the original back to the caller:
public static <T extends Shape> T draw2(T t) {
t.draw();
return t;
}
This makes a difference in situations when a subclass defines new methods on top of the base class. For example, if Circle defined
double radius() { return r;}
you could do the following:
double r = RenderEngine.draw1(c).radius();
This would be impossible with an implementation returning Shape.
Note: The above is to demonstrate the differences, not to suggest that the new implementation is more desirable than the original one.
draw2 will do the same thing as draw for things that are already shapes. But when it says T extends Shape, it allows it to take in a parameter that is not a shape. At that point, it will allow it to use the draw method without crashing, whether or not it's a shape, it just might not draw anything.

Should I be using Inner Classes? Example Code inside

I like consolidating my code/classes as much as possible without each class itself getting messy. So I looked into using NestedClasses, though InnerClasses in this case because the InnerClass needs access the OuterClass's members.
Example
Lets say I have a program that calculates various shape attributes to shapes. So given a Rectangle Shape, it would find the Area/Perimeter from inputs of length and width.
I would first create an abstract class Shape, which has abstract methods getArea() and getPerimeter(). I would then create my subclass RectangleShape, extend the shape class, #Override those methods with the necessary logic.
Now there's a shape Rectangular Prism (Cube). It has the same variables/methods as RectangleShape does, but with one extra, height. In the past I would create another subclass of RectangleShape and go from there.
Is it better/not worse to use an InnerClass instead and have an abstract class PrismShape? I ask this because Prisms share the same methods, no matter the shape. If you're at all confused by the above I'm posting code below of what I'm saying.
Example Code
Shape Class
public abstract class Shape {
public abstract double getArea();
public abstract double getPerimeter();
}
PrismShape Class
public abstract class PrismShape{
public abstract double getVolume();
public abstract double getSurfaceArea();
public abstract double getLateralArea();
}
RectangleShape Class
import Abstract.Shape;
import Abstract.ShapePrism;
public class RectangleShape extends Shape{
//Variables Declared
private double _length, _width;
//Constructor
public RectangleShape(double _length, double _width) {
setLength(_length);
setWidth(_width);
}
//Getters and Setters
#Override
public double getArea() {
return getLength() * getWidth();
}
#Override
public double getPerimeter() {
return (2 * getLength())+ (2 * getWidth());
}
public double getLength() {
return _length;
}
private void setLength(double _length) {
this._length = _length;
}
public double getWidth() {
return _width;
}
private void setWidth(double _width) {
this._width = _width;
}
//Inner Class Prism
public class RecPrismShape extends PrismShape{
//Variables Declared
private double _height;
//Constructor
public RecPrismShape(double _height) {
setHeight(_height);
}
//Getters and Setters
#Override
public double getSurfaceArea(){
return (getLateralArea() + (2 * getArea()));
}
#Override
public double getVolume(){
return getArea() * getHeight();
}
#Override
public double getLateralArea(){
return getPerimeter() * getHeight();
}
public double getHeight() {
return _height;
}
private void setHeight(double _height) {
this._height = _height;
}
}
}
I'm open to criticism, still fairly new to Java. My thought process during this was I have 2d Shape attributes and 3d (Prism) shape attributes. The 3d Shapes derive their attributes from 2d shapes, but not visa versa. So for me at least having InnerClasses makes sense.
My own take on this: A public inner class seems most useful when the rest of the program has an object of the outer class, and it wants to create an object of the inner class that "belongs" to the outer class object in some way; that is, it's tightly associated with it.
The way you've arranged things, however, it means that if the client wants to create a RecPrismShape object, it has to first create a RectangleShape object that the prism object will belong to. Most likely, this is not going to be useful. That is, the client creates a RectangleShape rect just because it has to, in order to create a RecPrismShape, and the rect object wouldn't be useful to it in any other way.
I think a better idea would be to have a RecPrismShape object have a private RectangleShape object as one of its fields, but this would be an "implementation detail". That way, you'd get to reuse the RectangleShape code, which it seems like you're trying to do.
public class RecPrismShape extends RectangleShape {
private RectangleShape rect;
private double height;
public RecPrismShape(double length, double width, double height) {
rect = new RectangleShape(length, width);
this.height = height;
}
// and just one example of how you could use it
public double getVolume() {
return rect.getArea() * getHeight();
}
}

Easy way to force an extending class to set multiple values

Example, let's say from a game:
public class Enemy {
protected int x, y;
protected int width, height;
protected int hitpoints;
protected int speed;
}
I want to have multiple classes extending this one (one for every enemy type) but I need to make sure (preferably force this) somehow that the extending class assigns values to all of these variables.
I don't want to pass them through a constructor call or set them in it - so currently I'm forced to do this by simply copying the entire decelerations into every class and assigning them values in the same line.
Is there perhaps a more efficient way to do this?
(Sorry if the question is somewhat vague..)
Thanks in advance.
Edit - This is how I would create an extending class:
public class Skeleton extends Enemy {
protected int x, y;
protected int width, height;
protected int hitpoints;
protected int speed;
}
One alternative to Jordão's answer would be to use the builder pattern:
public class SkeletonBuilder
{
private int x, y, width, height...;
public SkeletonBuilder withCoords(int x, int y) { this.x = x; this.y = y; }
public SkeletonBuilder withSize(int width, int height) { this.width = width; this.height = height; }
...
public Skeleton build() { return new Skeleton(x, y, width, height); }
}
public class Skeleton
{
/* package */ Skeleton(int x, int y, int width, int height, ...)
}
// game code
Skeleton skeleton = new SkeletonBuilder().withCoords(1, 4).withSize(2, 30).build();
If some of the params could be defaulted then set them up in the SkeletonBuilder constructor. If the other params are required, then you could either set a boolean flag in the builder, or use boxed objects, and fail in the build() method if they're not set.
To both force the subclasses to set the values in the constructor and to make the constructor call readable, you're going to have to write a lot more code in the superclass. This is one way I could think about it (just showing x and y):
abstract class Enemy {
protected int x, y;
protected Enemy(X x, Y y) {
this.x = x.value;
this.y = y.value;
}
protected static class X {
private final int value;
private X(int value) { this.value = value; }
}
protected static class Y {
private final int value;
private Y(int value) { this.value = value; }
}
protected static X x(int value) { return new X(value); }
protected static Y y(int value) { return new Y(value); }
}
class Skeleton extends Enemy {
public Skeleton() {
super(x(12), y(13));
}
}
UPDATE: if it makes sense to have composite types that encapsulate related values, they can make the code better:
class Skeleton extends Enemy {
public Skeleton() {
super(position(12, 13), size(300, 300), ...);
}
}
Your class Skeleton should not declare the same variables as set in Enemy.
As to your question, the simplest option is to make the variables final, and then set them in a constructor. The compiler will enforce that they are all set.
I think you should create a Type interface
interface Type
{
int getX();
int getY();
int getWidth() ;
int getHeight();
int getHitpoints();
int getSpeed();
}
Then the compiler will do the enforcement work.
Based on the comments (and although I would go with a constructor on the superclass) one way to go at it would be to declare the Enemy class as abstract (which probably should be if you just want to define common behaviour there) and initialize the variables as calls to abstract methods.
This way the extending classes would be forced to implement those methods and in essence initialize the variables.
Here's a simplified example:
public abstract class Enemy {
protected int x = getX();
protected int y = getY();
protected abstract int getX();
protected abstract int getY();
}
public class Skeleton extends Enemy {
#Override
protected int getX() { return 10; }
#Override
protected int getY() { return 10; }
}
Its more verbose, but perhaps it achieves the readability you are looking for.

Categories