Subclass constructor with different values - java

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.

Related

Why would I combine a private constructor with a static nested class?

I'm currently digging a little bit into accessibility of Java classes. While there is a varity of possibilities to define classes, I wonder about a use case for the example below.
Basically, the constructor of AnotherClass is private. However, AnotherClass has a static nested class, which is accessible within the PublicClass class.
It's just something I came up with out of curiosity, but as it actually works, I wonder, why would I ever use something like this?
Example
public class PublicClass {
public PublicClass() {
AnotherClass.AnotherInnerClass innerClass = new AnotherClass.AnotherInnerClass();
innerClass.anotherTest();
}
}
class AnotherClass{
/**
* Private constructor - class cannot be instantiated within PublicClass.
*/
private AnotherClass(){
}
/**
* Static inner class - can still be accessed within package.
*/
static class AnotherInnerClass{
public void anotherTest(){
System.out.println("Called another test.");
}
}
}
Note those classes are within the same file.
Output
Called another test.
The AnotherInnerClass CAN use the private constructor of AnotherClass. This is used for example in the Builder pattern, which is something along the lines of this:
public class Foo {
public Foo() {
Bar.Builder barBuilder = new Bar.Builder();
Bar bar = barBuilder.build();
}
}
public class Bar{
private Bar(..){
}
static class Builder{
public Bar build(){
return new Bar(..);
}
}
}

Java Returning Type of Child class (abstract)

I've been trying my best with some basic code, and I am completely stuck...
I have an abstract class "Piece":
public abstract class Piece {
private static int type;
public int getType() {
return type;
}
}
The "Pawn" is the Child:
public class Pawn extends Piece {
private static final int type = 1;
}
And now for the problem: When creating the Pawn with Pawn p = new Pawn();, p.getType() returns 0, not 1...
How can I fix this?
The problem is that you already have a variable declared in your abstract class. You shouldn't redeclare it in your subclass. Instead, set the abstract class's variable like this:
public class Pawn extends Piece {
public Pawn() {
type = 1;
}
}
You should also declare the variable as protected so that subclasses can access it and refrain from making it static, since that will allow only one value for all subclasses:
public abstract class Piece {
protected int type;
public int getType() {
return type;
}
}
This code you write relies on an instance and not on a static context:
Pawn p = new Pawn();
p.getType();
A static final field is not designed to be inherited by child classes.
And creating a static final field in the child class with the same name as in the parent class doesn't allow to override it either.
1) So you should use an instance field and not a static field for the type field.
2) If you want to override the behavior of getType() in the child class, in fact you don't even need to use a field. Using a method should be enough.
In the base class :
public abstract class Piece {
public int getType() {
return 0;
}
}
In the child class :
public class Pawn extends Piece {
#Override
public int getType() {
return 1;
}
}
Here is one way. But you really need to read up on classes and abstract classes.
public abstract class Piece {
public int getType() {
return 0;
}
}
public class Pawn extends Piece {
public int getType() {
return 1;
}
}
Having a static variable in a class means that all instances of that class share the same value. I don't think that's what you intended.
Also, you can use the hierarchy of inheritance to your advantage by not redefining the getType() method.
Here is one of many ways to solve it:
public abstract class Piece {
protected int type;
public int getType() {
return type;
}
}
public class Pawn extends Piece {
public Pawn() {
type = 1;
}
}
There are two problems with your approach.
The first is that Java does not support inheritance of static methods. Not that it couldn't have supported this - it's just a design choice. What this means is that any method of class Piece, which calls getType() - calls the Piece class' implementation of getType(), not a polymorphic call to getType() of whatever the actual subclass is.
The second problem is that you're sort of reinventing the wheel. Java has rich reflection facilities: You can use getClass() and instanceof for your check:
if(myObject instanceof Piece && myObject.getClass() != Piece.class) {
// do stuff
}
and of course you can make this a method of the piece class (no need to override it).

How do I create an instance of a inner class in the outer class constructor

I switched from C++ to Java and have a problem with nested classes. I would like to initiate an instance of a subclass in the constructor of the superclass. I tried it like this, but it seems to be wrong.
public class Aircraft {
public class LandingGear {
}
public Aircraft() {
Aircraft.LandingGear myLandingGear = this.new LandingGear();
}
}
The idea is that every instance of the class Aircraft has an instance "myLandingGear" of the subclass LandingGear.
For this use case, your nested class should be static (if it's going to be nested at all), and then you just use a simple new:
public class Aircraft {
public static class LandingGear {
// ----^
}
public Aircraft() {
Aircraft.LandingGear myLandingGear = new LandingGear();
// --------------------------------------^^^^
}
}
When it's not static, it's an inner class, which from your description isn't what you want. More on nested classes in this Java tutorial.
But unless there's a really good reason for LandingGear to be nested inside Aircraft, consider making it a peer instead.
Every Aircraft will have a LandingGear
public class Aircraft {
private LandingGear myLandingGear;
public Aircraft() {
myLandingGear = new LandingGear();
}
public LandingGear getLandingGear() {
return this.myLandingGear;
}
}
public class Aircraft {
public class LandingGear {
public static void m1()
{
//Your code snipet
}
}
public Aircraft() {
LandingGear.m1();
}
}

Innerclass sharing attribute information

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)

Abstract class with final uninitialized field

I was wondering if the below code makes any sense, since the compiler warns that "the blank final field objects may not have been initialized". Is there a better way of doing this?
public abstract Test {
protected final ArrayList<Object> objects;
}
public TestSubA extends Test {
public TestSubA() {
objects = new ArrayList<Objects>(20);
// Other stuff
}
}
public TestSubB extends Test {
public TestSubB() {
objects = new ArrayList<Objects>(100);
// Other stuff
}
}
I would make the field final and force the constructors to pass the value up:
public abstract class Test {
private final ArrayList<Object> objects;
protected ArrayList<Object> getObjects() {
return objects;
}
protected Test(ArrayList<Object> objects) {
this.objects = objects;
}
}
public class TestSubA extends Test {
public TestSubA() {
super(new ArrayList<Object>(20));
// Other stuff
}
}
public class TestSubB extends Test {
public TestSubB() {
super(new ArrayList<Object>(100));
// Other stuff
}
}
The problem with initializing the final parameters directly in the constructor of the sub-classes is that you need to do it all in one line since super() must be the first statement of the constructor. So instead, I prefer to make the constructor non-public and make a static build method like this:
public abstract class Test {
protected final ArrayList<Object> objects;
protected Test(ArrayList<Object> objects) {
this.objects = objects;
}
}
public class TestSubA extends Test {
public static TestSubA build() {
ArrayList<Object> objects = new ArrayList<Object>(20);
objects.put(...);
// Other stuff
return new TestSubA(objects);
}
private TestSubA(ArrayList<Object> objects) {
super(objects);
}
}
Instantiate the objects in the abstract class constructor and just pass the difference to the that constructor.
Generally speaking, it might be better to have a constructor in the base class that always sets the field, and not have a default constructor that doesn't set it. The subclasses can then explicitly pass the parameter in the first line of their constructor using super(value)

Categories