Initializing superclass variables in subclasses?

Ok, so, for example, let's say I have an abstract class called "Car." The Vehicle class, among other things, has a static variable called wheels, which is not initialized. I want other subclasses to expand from the Vehicle class, such as Motorcycle and Truck, and the wheels are initialized in these subclasses.

The code:

public abstract class Vehicle { static int wheels; //number of wheels on the vehicle } 

But below does not work:

 public class Motorcycle extends Vehicle { wheels = 2; } 

Is there any way to do this efficiently?

EDIT: Thanks to all the people who answered so far. I get that instantiating is probably a better way than putting them in separate classes, but I don't get the “static” part of java, so I need a little help here.

What I'm trying to do for my program has separate sprites for motorcycle and truck classes, and I want them to be static, so I don’t have to reload the image every time I create a motorcycle or truck instance. In addition, they will have almost the same properties with each other, so they will both extend from the superclass Vehicle.

The only other way I see this is to simply not declare the sprite variable in the Vehicle class, but in the Motorcycle / Truck class, as shown below:

 public abstract class Vehicle { //Other coding } public class Motorcycle extends Vehicle { static BufferedImage sprite = //initialize image //Other coding } public class Truck extends Vehicle { static BufferedImage sprite = //initialize image //Other coding } 
+7
source share
7 answers

If the “wheels” are static, there is only one, and it will apply to all cars at once. Thus, the tricycle, motorcycle, 18-wheel loader and Ford will have the same number of wheels.

That doesn't make sense to me. It would be better if the “wheels” were an instance variable that is in the parent class, but each subclass is set accordingly.

But you can try

 Vehicle.wheels = 2; 

NOTE. I am adding to my answer as you have added your question.

I like your idea of ​​statics in each of the subclasses. But you have to make them private. Then put the abstract method in the parent class (Vehicle), for example

 public abstract BufferedImage getSprite(); 

Then each direct subclass must have the same method and can return a private static variable.

Make the variable static, so you only need to load it once. Make them private so that code outside the class itself cannot trick it and introduce errors. You could make them “final” if possible, so the code in the class itself cannot change it after the fact and introduce errors. (The "final" variable cannot change its value, but the contents of its value can change. Thus, the "final" is not wonderful, as it could be.)

+11
source

What you are trying to do is fundamentally wrong. You can do Motorcycle initialize wheels once:

 // Static initializer static { wheels = 2; } 

... or every time an instance was created:

 // Instance initializer { wheels = 2; } 

But there is only one variable - not one for Motorcycle , one for Truck , etc. If you did the same for both Truck and Motorcycle , then depending on what was initialized last, win.

It's unclear how you want to use this field in any case, but if you just have one static field, then it will just have one value - not one for each subclass.

+6
source

Static elements are defined only once and are common to each expanding class. Changing the value in one of them will affect all the others. This is what I believe you really want to achieve:

 public abstract class Vehicle { private int _wheels; //number of wheels on the vehicle public int getWheels(){return _wheels;} protected Vehicle(int wheels){ _wheels = wheels; } } public class Motorcycle extends Vehicle { public Motorcycle(){ super(2); } } public class Car extends Vehicle { public Car(){ super(4); } } 
+2
source

I think there is a much more elegant way to do this.

What I'm going to suggest is still suffering from the limitation that you need for the instance. I don’t see anything like this because you want wheels appear as part of a superclass, but the meaning of wheels depends on the subclass and inside Vehicle there is no concept of the type of subclass without an instance.

In my opinion, the "wheels" in this case are not static or non-static. This is a metadata class. And the Java way to specify class metadata is annotations.

You need a custom annotation like this:

 @Documented @Retention(RetentionPolicy.RUNTIME) public @interface VehicleMetadata{ int wheels(); } 

You then comment on Motorcyle as follows:

 @VehicleMetadata(2) public class Motorcycle extends Vehicle {} 

In the superclass, you provide an accessory that receives the value of the annotation property. I would recommend that you use the "lazy assessment" approach so that you do not use reflection every time you need a value.

Note the use of this to get an instance:

 private String wheelsValue; public String getWheels() { if (this.wheelsValue== null) { VehicleMetadatane = null; for (Annotation annotation : this.getClass().getAnnotations()) { if (annotation instanceof VehicleMetadata) { ne = (VehicleMetadata) annotation; break; } } wheelsValue = ne.wheels(); } return wheelsValue ; } 

In my opinion, this is the most elegant solution.

+2
source

Original class declaration:

 public abstract class Vehicle { static int wheels; //number of wheels on the vehicle } public class Motorcycle extends Vehicle{...} public class Truck extends Vehicle{...} 

does not work because the static variable comes with the class in which it was declared. Class static variables create memory for only one instance of a variable for each class, and not for a class object. When the compiler (jvm) sees a static variable in the Vehicle class, it allocates the memory of this variable and this memory location is static (does not change). Each subsequent use of the Vehicle class, whether extended or instantiated as an object, points to the same memory location for the static variable.

To use a static variable in child classes, you must use it inside the method. So you could essentially rewrite your motorcycle class as follows:

 class Motorcycle extends Vehicle{ public Motorcycle(){ wheels = 2; } } 

and it will be compiled; however, you cannot get the expected results. For example, if you do this in your code (provided that the Truck class is declared as a motorcycle class and assigns 4 wheels, as well as the getter method to return the value of the wheels).

 Motorcycle cycle = new Motorcycle(); Truck pickup = new Truck(); ... System.out.println("Motorcycle has " + cycle.getWheels() + " wheels."); 

will print:

The motorcycle has 4 wheels.

+2
source

Perhaps you should consider the constructors you use.

 public Vehicle(int wheels) { this.wheels = wheels; } public Motorcycle(int wheels) { super(wheels); } public Motorcycle cycle = new Motorcycle(2); 

The motorcycle uses a super constructor that knows what to do with the parameter. It automatically sets the wheels to 2.

0
source

If you create a static variable in your objects, it will be the same for every Vehicle class that you make, even if you make another subclass for your abstract Vehicle class. This is due to the "nature" of any static variable.

I think you want to use a non-static variable, so for each instance of any subclass of the abstract Vehicle class, you can determine the value of the wheels, and this is done as follows:

 public abstract class Vehicle { public int wheels; //number of wheels on the vehicle } 

and any subclass:

 public foo extends Vehicle{ public void someMethode(){ this.wheels = 2; } } 

You can also do this for a static variable, but then you change it for each instance of any Vehicle subclass

I hope I helped you

0
source

All Articles