I got a very easy question here, but don't know in what direction to search...
I built a class that extends another class with an uninstantiated object. How do I make sure I dont forget to instantiate the object in the subclass? Here's what I mean:
public class Hitbox{
....
}
public class Enemy{
protected Hitbox hbox; // edit: changed to protected
}
public class AngryLady extends Enemy{
hbox = new Hitbox(10, 20); // Must not forget this!
}
One way would be to always check if (hbox!=null) before using thishandle, but that feels silly. There has to be an easier way like with abstract classes, where already the compiler gives an error when a method from the abstract class has not been implemented.
Just initialize your variable in the constructor of the parent class:
public abstract class Enemy{
protected Hitbox hbox;
public Enemy(int a, int b) {
hbox = new Hitbox(a, b);
}
}
public class AngryLady extends Enemy {
public AngryLady(int a, int b) {
super(a, b);
}
}
If you need a different HitBox instance per subclass of Enemy, use Factory method pattern. This is a very simple example:
public enum HitboxType {
ANGRY
}
public final class HitboxFactory {
private HitboxFactory() {
}
public static Hitbox createHitbox(HitboxType hitboxType) {
switch(hitboxType) {
case HitboxType.ANGRY:
return new AngryHitbox();
case <another_case>:
return <respective hitbox>
}
//in case of invalid parameter
return null;
}
}
And it would be better using dependency injection:
public abstract class Enemy{
protected Hitbox hbox;
public Enemy(Hitbox hitbox) {
hbox = hitbox;
}
}
public class AngryLady extends Enemy {
public AngryLady(Hitbox hitbox)) {
super(hitbox);
}
}
//...
AngryLady angryLady = new AngryLady(HitboxFactory.createHitbox(HitboxType.ANGRY));
//...
Another tip in case you don't want to have null Hitboxes is to create an empty Hitbox:
public class EmptyHitbox extends Hitbox {
public EmptyHitbox() {
super(0,0); //or whatever arguments it needs
}
}
And in the factory method:
public static Hitbox createHitbox(HitboxType hitboxType) {
switch(hitboxType) {
/* ... */
}
//in case of invalid parameter
return new EmptyHitbox();
}
First it should be protected since subclass doesn't have access to private fields.
public class Enemy{
protected Hitbox hbox;
}
To make sure you don't forget, you should really initiate the object where you are declaring it - the parent class.
public class Enemy{
//if you just don't want/need to define a constructor explicitly and you know a b ahead.
int a = 0;
int b = 0;
protected Hitbox hbox = new Hitbox(a, b);
}
In this case, you can always use hbox in the subclass without worrying about it.
Since the hbox field is inherited from the parent class, it should be initialized at the parent class:
public class Enemy {
private final static int DEFAULT_H = 10;
private final static int DEFAULT_W = 10;
// default initialization
private HitBox hbox = new HitBox(DEFAULT_W,DEFAULT_H);
public HitBox getHBox() {
return hbox;
}
}
Unless hbox must be initialized differently for each subclass, in which case you should use chained constructors to initialize the HitBox.
public class Enemy {
private final HitBox hbox;
public Enemy(HitBox hbox) {
this.hbox= hbox;
}
public HitBox getHBox() {
return this.hbox;
}
}
public class AngryLady extends Enemy{
public AngryLady() {
super(new HitBox(10, 20));
}
}
This example assume Enemy is not an abstract class.
Related
I have in mind two ways to initialize a final field in an abstract class and I have to pick the most elegant, correct and understandable for other developers way. There will be at least 10 implementations of my abstract class. Any ideas on which one should I choose?
First way:
public sealed abstract class GuiComponent permits DummyComponent {
private final Node internalNode;
//------Constructor
protected GuiComponent() {
internalNode = Objects.requireNonNull(initInternalNode());
}
//------Protected
protected abstract Node initInternalNode();
protected final Node getInternalNode() {
return internalNode; //subclasses will use this
}
}
public final class DummyComponent extends GuiComponent {
#Override
protected Node initInternalNode() {
HBox hbox = new HBox();
//some Node preparation
return hbox;
}
}
Second way:
public sealed abstract class GuiComponent permits DummyComponent {
private final Node internalNode;
//------Constructor
protected GuiComponent(Node internalNode) {
this.internalNode = Objects.requireNonNull(internalNode);
}
//------Protected
protected final Node getInternalNode() {
return internalNode; //subclasses will use this
}
}
public final class DummyComponent extends GuiComponent {
//------Constructor
public DummyComponent() {
super(initInternalNode());
}
//------Private
private static Node initInternalNode() {
HBox hBox = new HBox();
//...
return hBox;
}
}
In my opinion, the second approach is better. The reason being that the GuiComponent constructor requests a Node, so it is easier to understand that a Node is in fact needed. This makes it explicit, while the other approach makes it implicit because unless you see GuiComponent code, you have no way to know that getInternalNode() method will be called in GuiComponent constructor. You can even say that it is a side-effect of this constructor, as we all know side-effects are usually better avoided in software development.
I have parent class Hammer and then his child class Mjolnir. I want to set the remainingUsage for Mjolnir to 4. I managed to do it by creating method in Hammer classs called setUsage and then use it in Mjolnir constructor. Is it possible to do it in more easy way without that setUsage method?
public class Hammer extends AbstractActor {
private int remainingUsage;
private Animation image;
public Hammer() {
this.remainingUsage = 1;
image = new Animation("sprites/hammer.png");
setAnimation(image);
}
}
public class Mjolnir extends Hammer {
Mjolnir(){
super();
this.setUsage(4);
}
}
You can do something like this:
...
private remainingUsages;
public Hammer() { this(1); }
public Hammer(int remainingUsages) { this.remainingUsages = remainingUsages; }
And then just call super(4) from your subclass. Calling other methods within your constructor is not good practice.
This question already has answers here:
Subclassing a Java Builder class
(10 answers)
Closed 6 years ago.
If I am using the builder pattern to configure new objects I may have two classes like Game and HockeyGame (shown below). When I want to create a new HockeyGame, I get it's builder and start calling methods to configure the object as needed.
The problem I am running into is shown in the main function. Once I call one method from the super class it returns as an intance of Game.Builder, and I can no longer call any method from the child class.
What is the best way to deal with this?
Main.java
class Main {
public static void main(String[] args){
HockeyGame hg = new HockeyGame.Builder()
.setScore(5)
.setTimeLimit(3600)
//--------------------------------------------------------------------
.setIceTemperature(-5) // Error! Cannot call setIceTempurature() on
// an instance of Game.Builder
//--------------------------------------------------------------------
.build();
}
}
Game.java
public class Game{
int score;
int timeLimit;
public Game(int score, int timeLimit) {
this.score = score;
this.timeLimit = timeLimit;
}
public static class Builder {
int score;
int timeLimit;
public Builder setScore(int score) {
this.score = score;
return this;
}
public Builder setTimeLimit(int timeLimit) {
this.timeLimit = timeLimit;
return this;
}
public Game build() {
return new Game(score, timeLimit);
}
}
}
HockeyGame.java
public class HockeyGame extends Game {
float iceTemperature;
public HockeyGame(int score, int timeLimit, float iceTemperature) {
super(score, timeLimit);
this.iceTemperature = iceTemperature;
}
public static class Builder extends Game.Builder {
float iceTemperature;
public HockeyGame.Buidler setIceTemperature(float iceTemperature) {
this.iceTemperature = iceTemperature;
return this;
}
public HockeyGame build(){
return new HockeyGame(score, timeLimit, iceTemperature);
}
}
}
Thanks.
You need to use the getThis() trick that is prevalent in much fluent API code.
First you need to make your Game.Builder generic in itself:
public static class Builder<B extends Builder<B>>
Then you add a getThis() method:
public B getThis() {
return (B) this;
}
Now you change your setters to return a B and return getThis() rather than this:
public B setTimeLimit(int timeLimit) {
//...
return getThis();
}
Your extension class also needs to be generic, in itself:
public static class Builder<B extends Builder<B>> extends Game.Builder<B>
Now you can use the code, and it will "remember" the intended type:
HockeyGame hockeyGame = new HockeyGame.Builder<>().setScore(10)
.setTimeLimit(20)
.setIceTemperature(-1)
.build();
This final code looks something like:
public class Game {
private final int score;
private final int timeLimit;
private Game(final Builder<?> builder) {
this.score = builder.score;
this.timeLimit = builder.timeLimit;
}
public static class Builder<B extends Builder<B>> {
private int score;
private int timeLimit;
public B setScore(int score) {
this.score = score;
return getThis();
}
public B setTimeLimit(int timeLimit) {
this.timeLimit = timeLimit;
return getThis();
}
protected B getThis() {
return (B) this;
}
public Game build() {
return new Game(this);
}
}
}
public class HockeyGame extends Game {
private final float iceTemperature;
private HockeyGame(final Builder<?> builder) {
super(builder);
this.iceTemperature = builder.iceTemperature;
}
public static class Builder<B extends Builder<B>> extends Game.Builder<B> {
private float iceTemperature;
public B setIceTemperature(float iceTemperature) {
this.iceTemperature = iceTemperature;
return getThis();
}
#Override
public HockeyGame build() {
return new HockeyGame(this);
}
}
}
N.B: I have made the fields private final and also the main type constructors - this forces people to use the Builder. Also, the constructor can take a Builder<?> and copy the variable from there - this tidies the code a little.
The actual hack is, as you may have noticed, here:
public B getThis() {
return (B) this;
}
Here, we force a cast of the Builder to its generic type - this allows us to change the return type of the method dependant upon the specific instance being used. The issue is, if you declare a new Builder something like the following:
public static class FootballGame extends Game {
private FootballGame(final Builder<?> builder) {
super(builder);
}
public static class Builder<B extends HockeyGame.Builder<B>> extends Game.Builder<B> {
float iceTemperature;
#Override
public FootballGame build() {
return new FootballGame(this);
}
}
}
This this will blow up at runtime with a ClassCastException. But the setter method will return a HockeyGame.Builder rather than FootballGame.Builder so the issue should be obvious.
Try something like this
You explicitely cast it back to a HockeyGame.Builder object and work with its own method(s) on it.
The problem you had is that setTimeLimit returns a Builder object (mother class) and so you can not use the child methods on it.
HockeyGame hg = ((HockeyGame.Builder)(new HockeyGame.Builder().setScore(5)
.setTimeLimit(3600)))
.setIceTemperature(-5)
.build();
Also, setIceTemparature should return a HockeyGame.Builder object to be able to build on it.
public Builder setIceTemperature(float iceTemperature) {
this.iceTemperature = iceTemperature;
return this;
}
I have a class called ContentStream... the problem is that the inner class AddRectancle suppose to get the info of the getter of the class GraphicBeginn...I thought the class ContentStream can reach the getter at least as the getter is public ... plse tell me how to
public class ContentStreamExt extends ContentStreamProcessor
{
private Matrix graphicalMatrix;
public ContentStreamProcessorExt(ExtListener extListener)
{
super(extListener);
}
private void enhanceAdditional()
{
GraphicBeginn beginnGraphic = new GraphicBeginn();
super.register("a", beginnGraphic);
super.register("b", new AddRectangle(beginnGraphic));
}
private static class AddRectangle(GrapicBeginn beginn)
{
// should get the info of uUx and uUy
}
private static class GraphicBeginn implements ContentOperator
{
private float uUx;
private float uUy;
public float getuUx()
{
return this.uUx;
}
public float getuUy()
{
return this.uUy;
}
..... // the input for uUx and uuy will be created in a method
}
The code you gave has a number of problems, it doesn't compile correctly as another poster has noted. It also appears you are providing a method signature while also declaring a class called "AddRectange". Is this a class or a method? You need to decide which, it can't be both. Here is an example that I think illustrates what you're trying to do in a general sense:
public class SampleClass {
public SampleClass() {
}
private void sampleClassMethod() {
A a = new A();
a.acceptB(new B());
}
private class A {
public void acceptB(B bObject) {
System.out.println(bObject.memberVar1);
}
}
private class B {
private int memberVar1 = 5;
}
}
If i understand your question correctly, The add rectangle class should be passed an instance of graphic begin on which it can invoke the public getters. This wiring can be done by the content stream class.
By the way the following is syntactically invalid
private static class AddRectangle(GrapicBeginn beginn)
What I'm trying to do is create a class (Square) that uses a Builder pattern, and then extend this class as an inner class (MyCube) inside the Object where it's needed (DrawMyCube).
For reasons that are a bit to complex to get into it's preferred to extend these as inner classes (references to local variables).
I've tried to make the example as simple as possible because the real use case is too complex to use on here:
public abstract class Square {
protected Integer length;
protected Integer width;
public abstract static class Builder {
protected Integer length;
protected Integer width;
public abstract Builder length(Integer length);
public abstract Builder width(Integer width);
}
protected Square(Builder builder) {
this.length = builder.length;
this.width = builder.width;
}
}
Now I need to extend and use this in here:
public class DrawMyCube {
private String myText;
private Integer height;
private String canvas;
private MyCube myCube;
public DrawMyCube(String canvas) {
this.canvas = canvas;
myCube = new MyCube.Builder().length(10).width(10).text("HolaWorld").build();
}
public void drawRoutine() {
myCube.drawMe(canvas);
}
protected class MyCube extends Square {
protected String text;
public static class Builder extends Square.Builder{
protected String text;
public Square.Builder length(Integer length) {this.length = length; return this;}
public Square.Builder width(Integer width) {this.width = width; return this;}
public Square.Builder text(String text) {this.text = text; return this;}
}
protected MyCube(Builder builder) {
super(builder);
this.text = text;
}
protected void drawMe(String canvas) {
canvas.equals(this);
}
}
}
However the problem is the static Builder in the inner class:
The member type Builder cannot be declared static; static types can
only be declared in static or top level types.
Alternatively, I can create the inner class MyCube as a regular class, but then the problem becomes that I can not refer back to anything inside the DrawMyCube class (and in the real use case there are many references to various of these).
Static nested classes can only be declared in a static context, which is why you're seeing that compiler error. Just declare your Builder class adjacent to MyCube (or anywhere else in static context, it doesn't matter). For example:
public class DrawMyCube {
protected class MyCube extends Square { }
public static class MyCubeBuilder extends Square.Builder { }
}
Note that the builder will need a reference to the outer DrawMyCube instance in order to instantiate a new MyCube. For this reason you might just make it an inner (non-static) class of MyCube:
public class DrawMyCube {
protected class MyCube extends Square { }
public class MyCubeBuilder extends Square.Builder { }
}
As you can see I still declared it adjacent to MyCube because having a builder as an inner class to what it builds just doesn't make sense.
Edit: As you mentioned, a simple alternative would be to make MyCube static:
public class DrawMyCube {
protected static class MyCube extends Square {
public static class Builder extends Square.Builder { }
}
}
Because honestly there isn't a huge benefit to using inner classes - just the implicit outer instance reference - and this would let you keep your existing hierarchy and naming conventions. You can easily implement the reference to the outer DrawMyCube yourself - it just takes a little more code.
As a side note you're probably going to want to use generics to implement your builder pattern, for example an abstract Builder<T> where an implementation builds an instance of T. As it is, there won't be a way to narrow down what your deriving builder classes produce. Here's a sketch of what I'm hinting at:
abstract class Square { }
abstract class SquareBuilder<T extends Square> { }
class MyCube extends Square { }
class MyCubeBuilder extends SquareBuilder<MyCube> { }