I am making simulations in java but i am having a hard time manipulating variables while extending.
To make the problem easier to express let's consider 2 Java classes Grid1 and Grid2.
Grid1
Class Grid1 {
public int a;
public int grid[];
public Grid1(int a) {
this.a=a;
grid = new int[50];
}
public update() {
for (int i : grid) {
i =a;
}
}
}
Grid2
Class Grid2 extend Grid1 {
public Grid2(int a) {
super(a)
}
@Override
public update() {
for (int i : grid) {
i =2*a;
}
}
}
Now let say i want to use Grid1 and Grid2 in the simulations. So i create two classes Sim1 and Sim2.
Sim1
Class Sim1 {
public Grid1 grid1;
public Sim1() {
grid1 = new Grid1(10);
}
public draw() {
draw_list(grid1); //lets say draw list is defined elsewhere
}
}
Sim2
Class Sim2 extend Sim1{
public Grid2 grid2;
public Sim2() {
grid2 = new Grid2(10);
}
}
Now when i run update()
in my main on Sim2 then draw_list i get the picture of Grid1 and not Grid2...
So how can i fix this ?
In other words i want to extend a class and change the type of the variable in the new extended class.
Thank you
PS: Actually the simulation are about conway game of life and the immigration automata. I want to extend immigration to be like conway ...
CodePudding user response:
All dogs are animals, right? Well, all Grid2 instances are also Grid1s. For the same reason: Grid2 extends Grid1
means: Grid2 is everything Grid1 defines, and more.
Thus, if you extend Sim1
you do not want to add a second field, because now your Sim2 has 2 fields. Instead, you want to end up assigning an instance of Grid2 to the field which is type Grid1. End up running Grid1 g = new Grid2();
which is perfectly legal java code, for the same reason Animal a = new Dog();
would be fine.
As written, your Grid1
class is dead in the water. You MUST call one of your parent class's constructors, and your Sim1 constructor makes a new Grid1 instance. Which you don't want when Grid2's constructor runs. We need to fix that, too. You've also slattered public
all over this, that's not very nice.
class Sim1 {
private Grid1 grid;
public Sim1() {
this(new Grid1(10));
}
protected Sim1(Grid1 grid) {
this.grid = grid;
}
public draw() {
draw_list(grid); //lets say draw list is defined elsewhere
}
}
Class Sim2 extend Sim1 {
public Sim2() {
super(new Grid2(10));
}
}
We now have 2 constructors; Sim2
can choose which one it wants to invoke, and we obviously invoke the one where we provide the ready-made Grid instance.