I wanna change a variable's name by choice of user. I know that it can be done by Mab (not very charming), but I think that it can be done by polymorphism too, at least something that can simulate it. It is hard to explain, so the code below can illustrate it better. Thanks!
public class Main {
public static void main(String[] args) {
GenericObject o;
o = new Object1(10, 10);
o.wh();
System.out.println(o.w); // Output: 3 (ok)
System.out.println(o.h); // Output: 10 (ok)
o = new Object2(10, 10);
o.wh();
System.out.println(o.w); // Output: 7 (ok)
System.out.println(o.h); // Output: 4 (ok)
String inputFromUser = "1";
o = new Object + inputFromUser + (10, 10); /*I know that is an absurd, just to illustrate...
if polymorphism can solve this problem, I thik it's the best option. So how use it here?
I don't wanna use ifs or switchs, I will use more than 300 classes*/
o.wh();
System.out.println(o.w); // Output: 3 (that's what I wanna obtain)
System.out.println(o.h); // Output: 10 (that's what I wanna obtain)
}
}
abstract class GenericObject {
int w, h, x, y;
GenericObject (int x, int y) {
this.x = x;
this.y = y;
}
public abstract void wh();
}
class Object1 extends GenericObject{
Object1 (int x, int y) {
super(x, y);
}
#Override
public void wh () {
w = 3;
h = 10;
}
}
class Object2 extends GenericObject{
Object2 (int x, int y) {
super(x, y);
}
#Override
public void wh () {
w = 7;
h = 4;
}
}
Hope below code will help you.
HashMap<String, GenericObject > allTypes = new HashMap<>();
allTypes.put("1", new Object1(10, 10));
allTypes.put("2", new Object2(10, 10));
String inputFromUser = "1";
GenericObject o = allTypes.get(inputFromUser);
o.wh();
System.out.println(o.w); // Output: 3
System.out.println(o.h); // Output: 10
All design smells aside, I think that you're really looking for an answer using reflection. I think you can use the following code snippet to accomplish what you want:
// dynamically specify the class name based on the user's input.
Class<?> typeFromUser = Class.forName("Object" + inputFromUser);
// grab the correct package-private or public constructor whose type
// parameters are 2 primitive ints
java.lang.reflect.Constructor<?> constructor =
typeFromUser.getDeclaredConstructor(Integer.TYPE, Integer.TYPE);
// reflectively invoke the constructor with the two int values
Object obj = constructor.newInstance(10, 10);
// the instantiated object is of a raw type, cast it to the correct type
o = (GenericObject) obj;
I also tried this code and you can see the demo on IDEOne.
I think you can use reflection mechanism to do this. Below is the example code snippet:
String clsName = <your input(Object1 or Object2)>;
Class<?> clazz = Class.forName(clsName);
Constructor<?> cst = clazz.getDeclaredConstructor(int.class, int.class);
GenericObject obj = null;
if(clsName.equals("Object1")) {
obj = (Object1)cst.newInstance(10, 10);
} else if(clsName.equals("Object2")) {
obj = clsName.equals("Object1")
}
Related
I have 3 classes, among the classes, I am trying to play with methods for that from Second class I am passing some values into First class and from there I am passing values to third class
in the Third I am combining 3 parameters and storing in a variable called p.
now I am trying to print p value in Second class using a method which returns p value but it printing as zero but in the setFive() method it printing the actual value.
Please help me with this where i am doing wrong
Tried Code:
class First {
int x, y, z;
void setOne(int a, int b, int c) {
a = a + x;
b = b + y;
c = c + z;
Third obj = new Third();
obj.setFive(a, b, c);
}
void two(int a) {
this.x = a;
}
void three(int a) {
this.y = a;
}
void four(int a) {
this.z = a;
}
}
class Second {
public static void main(String args[]) {
First f = new First();
f.two(100);
f.three(150);
f.four(170);
f.setOne(1, 2, 3);
Third obj = new Third();
System.out.println(obj.getFive());
}
}
class Third {
int p;
public void setFive(int a, int y, int n) {
this.p = a + y + n;
}
public int getFive() {
return p;
}
}
Thanks
When you do Third obj = new Third(); inside first.setOne(int a,int b,int c), this obj is local to that method, no other object can see it. It is destroyed when the code exits that method
What you need to do it create that Third object in your Second class, and then pass it to First:
Third obj = new Third();
f.setOne(obj, 1, 2, 3);
then on First you need to change the signature to take the object, and call the setter on it:
void setOne(Third obj, int a, int b, int c) {
a = a + x;
b = b + y;
c = c + z;
obj.setFive(a, b, c);
}
While coding I was trying to declare a class that can create an arraylist of arraylists, but soon enough I found it hard to define a proper constructor for my class. I wanted to define some methods for me to handle the huge outer arraylist(1000*1000), but I might be affected by C and always tried to use something like structdef.
How should I define my class? I guess declaring every lines seperatedly is not a wise choice, and I don't want to use 2D arraylist directly. Besides, how should I define a constructor to get an object that is an 2D arraylist?
//Update here
Below is my code example:
class farbicMap {
//attribute
ArrayList<Integer> farbicUnit = new ArrayList<Integer>();
//constructor
farbicMap () {
for (int i=0;i<1000;++i) {
farbicUnit.add(0);
}//this gives an arraylist with size of 100
//I want to use the above arraylist to construct another list here
}
//method
setUnitValue(int v) {
...
}
}
Seems that I didn't really understand the concept of class... I wanted to use the class to represent a map with some nodes. Now that's much clearer to me.
This is how I understood your consern:
class Test {
public static void main(String[] args) {
Board board = new Board(1000, 1000);
board.put(1, 2, "X");
Object x = board.get(1, 2);
System.out.println("x = " + x);
}
}
class Board {
private final int xSize;
private final int ySize;
private ArrayList<ArrayList<Object>> board = new ArrayList<>();
public Board(int xSize, int ySize) {
this.xSize = xSize;
this.ySize = ySize;
for (int i = 0; i < xSize; i++) {
board.add(getListOfNulls());
}
}
public Object get(int x, int y) {
return board.get(x).get(y);
}
public void put(int x, int y, Object toAdd) {
List<Object> xs = board.get(x);
if (xs == null) {
xs = getListOfNulls();
}
xs.add(y, toAdd);
}
private ArrayList<Object> getListOfNulls() {
ArrayList<Object> ys = new ArrayList<>();
for (int j = 0; j < ySize; j++) {
ys.add(null);
}
return ys;
}
}
You should use Array if size is fixed.
Please run output of below two programs...
Program_1:
package p1;
class x {
public void methodA() {
System.out.println("Methos A of Class X");
}
}
class y extends x {
public void methodA() {
System.out.println("Method A of Class Y");
}
}
class Override1 {
public static void main(String[] args) {
x obj1 = new x();
x obj2 = new y();
y obj3 = new y();
/* y obj4 = new x(); */
obj1.methodA();
obj2.methodA();
obj3.methodA();
/* obj4.methodA(); */
}
}
Program_2 :
class x {
int a[] = new int[2];
x() {
a[0] = 10;
a[1] = 20;
}
}
class y extends x {
int a[] = new int[10];
y() {
a[0] = 12000;
a[1] = 1000;
a[2] = 120;
}
}
class Override2 {
public static void main(String[] args) {
x obj1 = new x();
x obj2 = new y();
// y obj3 = new x();
y obj4 = new y();
System.out.println(obj1.a[1]);
System.out.println(obj2.a[1]);
System.out.println(obj4.a[1]);
}
}
My specific question is that in Program_1 by what means MethodA of class Y Called? and in program_2 by What means '20' (a[1]) of class X is called?
please clear my basic concept about creation of object regarding memory allotment and reference assignment.
The short answer is that there is no data polymorphism in Java.
In the first example, methodA is the same method implemented in different classes.
In the second example, the two a are completely separate, unrelated data members (even though they happen to have the same name and data type).
The second example is equivalent to:
class x {
int a_x[] = new int[2];
x() {
a_x[0] = 10; a_x[1] = 20;
}
}
class y extends x {
int a_y[] = new int[10];
y() {
a_y[0] = 12000; a_y[1] = 1000; a_y[2] = 120;
}
}
class Override2 {
public static void main(String[] args) {
x obj1 = new x();
x obj2 = new y();
y obj4 = new y();
System.out.println(obj1.a_x[1]);
System.out.println(obj2.a_x[1]);
System.out.println(obj4.a_y[1]);
}
}
My specific question is that in Program_1 by what means MethodA of class Y Called? --> Its called Dynamic Dispatch mechanism (Method overriding). check here. Here, the method of the RHS (instance type) is called irrespective of the reference on the LHS (child / parent), provided the parent defines the same method.
What means '20' (a[1]) of class X is called --> depends on the type of reference. If reference is of X x.field is called irrespctive of RHS.
I've been searching a lot for this problem and I can't find a solution. I'm trying to build a mini-game and I have a method for creating platforms. I have a class with every platform parameters, and I made a class array so i can have multiple platforms at the same time.
Problem: When I try to call the method for constructing the platform by sending the parameters I want, it gives me a NullPointerException. The method was working before, but with everything static and so i couldnt have multiple instances of that class, and now I removed the static fields from the platform class and it gives me the NullPointerException every time I call the method.
I copied the part of the code that gives me the error, the error goes the following way:
public static void main(String[] args) {
Game ex = new Game();
new Thread(ex).start();
}
In Game class:
public Load_Stage load = new Load_Stage();
public Game() {
-other variables initializatin-
Initialize_Items();
load.Stage_1(); // <--- problem this way
In Load_Stage class:
public class Load_Stage {
public Platforms plat = new Platforms();
public void Stage_1(){
Stage_Builder.Build_Platform(200, 500, 300, plat.platform1);
Stage_Builder.Build_Platform(100, 200, 100, plat.platform1);
}
}
And inside the Stage_Builder class:
public class Stage_Builder {
public static final int max_platforms = 10;
public static Platform_1[] p1 = new Platform_1[max_platforms];
public static boolean[] platform_on = new boolean[max_platforms];
public Stage_Builder() {
for (int c = 0; c < platform_on.length; c++) {
platform_on[c] = false;
}
}
public static void Build_Platform(int x, int y, int width, ImageIcon[] type) { // BUILDS A PLATFORM
for (int b = 0; b < max_platforms; b++) {
if (platform_on[b] == false) {
p1[b].Construct(x, y, width, type); // <-- NullPointerException here
platform_on[b] = true;
break;
}
}
}
}
Thanks beforehand.
EDIT: Here's the Platform_1 class (sorry for forgetting about it):
public class Platform_1 {
private int platform_begin_width = 30;
private int platform_middle_width = 20;
public int blocks_number = 0;
public ImageIcon[] platform_floors = new ImageIcon[500];
private int current_width = 0;
public int [] platform_x = new int [500];
public int platform_y = 0;
public int platform_width = 0;
public void Construct(int x, int y, int width, ImageIcon [] type) {
platform_width = width;
platform_y = y;
for (int c = 0; current_width <= platform_width; c++) {
if (c == 0) {
platform_x[c] = x;
platform_floors[c] = type[0];
current_width += platform_begin_width;
} else if ((current_width + platform_middle_width) > platform_width) {
platform_floors[c] = type[2];
blocks_number = c + 1;
platform_x[c] = current_width + x;
current_width += platform_middle_width;
} else {
platform_floors[c] = type[1];
platform_x[c] = current_width + x;
current_width += platform_middle_width;
}
}
}
}
And the Platforms class:
public class Platforms {
public ImageIcon[] platform1 = {new ImageIcon("Resources/Sprites/Stage_Objects/Platform1/begin.png"),
new ImageIcon("Resources/Sprites/Stage_Objects/Platform1/middle.png"),
new ImageIcon("Resources/Sprites/Stage_Objects/Platform1/end.png")};
}
The problem and solution are both obvious.
public static Platform_1[] p1 = new Platform_1[max_platforms];
After this line of code executes, p1 is an array of references of type Platform_1 that are all null.
Executing this line of code tells you so right away:
p1[b].Construct(x, y, width, type); // <-- NullPointerException here
The solution is to intialize the p1 array to point to non-null instances of Platform_1.
Something like this would work:
for (int i = 0; < p1.length; ++i) {
p1[i] = new Platform1();
}
I'm not seeing where you put things in the p1 array in the Stage_Builder class.
Another possibility (unlikely, but possible if you haven't shown everything) is that something in the Platform class, which you didn't show, is not initialized, and is breaking when you call Construct.
Also, the following seems problematic
public static Platform_1[] p1 = new Platform_1[max_platforms];
public static boolean[] platform_on = new boolean[max_platforms];
public Stage_Builder() {
for (int c = 0; c < platform_on.length; c++) {
platform_on[c] = false;
}
}
it appears you declare static variables p1 and platform_on, but you only populate platform_on in a constructor. So the first time you create a Stage_Builder instance, you populate one static array with all false, and don't put anything in the other static array...
Populate those static variables in a static block
// static var declarations
static {
// populate static arrays here.
}
The array you are calling a message on was never filled.
You have
public static Platform_1[] p1 = new Platform_1[max_platforms];
so p1 is
p1[0] = null
p1[1] = null
.
.
.
p1[max_platforms] = null
You try to call
p1[b].Construct(x, y, width, type);
which is
null.Construct(...);
You need to initialize that index on the array first.
p1[b] = new Platform_1();
p1[b].Construct(...);
First of all, your problem is that p1[b] is most likely null, as duffymo pointed out.
Secondly, you are using arrays in a really weird way. What about
a) delete Stage_Builder
b) Instead, have an ArrayList somewhere
c) The equivalent of Build_Platform1() look like this, then:
p1.add(new Platform1(x, y, width, type);
d) no if on[i], no max_platforms, no for loop to add a platform (the latter is a bad performance problem if you actually have a few hundret platforms)
Let me give some code so you can see what I'm doing with the following java code for android. Say for example I have the following two classes, one extended from the other:
class MyClassOne {
protected float x, y;
MyClassOne(float x, float y) {
this.x = x; this.y=y;
}
public void printY(){
System.out.print(y);
}
}
class MyClassTwo extends MyClassOne {
protected String stringSpecificToThisClass;
private long longSpecificTothisClass;
MyClassTwo(float x, float y, String s, long l) {
this.x=x; this.y=y;
this.longSpecificTothisClass= l; this.stringSpecificTothisClass=s;
}
}
These classes are then initialized in the following way
private ArrayList<MyClassOne> mClassOne = new ArrayList<MyClassOne>();
private ArrayList<MyClassTwo> mClassTwo = new ArrayList<MyClassTwo>();
for(int i=0;i<5;i++){
Random random = new Random(10);
mClassOne.add(new MyClassOne(i*12, random.nextInt()));
mClassTwo.add(new MyClassOne(i*11, random.nextInt()));
}
now, what I want to do is compare and sort both arraylists according to the value of y.
The way i do this for a single list is like so:
private Object[][] mSort(){
Object[][] mSort = new Object[mClassOne.size()][2];
for(int i = 0; i<mClassOne.size(); i++){
mSort[i][0] = i;
mSort[i][1] = mClassOne.get(i).y;
}
Arrays.sort(mSort, new Comparator<Object[]>(){
#Override
public int compare(Object[] obj1, Object[] obj2){
Float comp1 = (Float)obj1[1]; Float comp2 = (Float) obj2[1];
return comp1.compareTo(comp2);
}
});
return mSort;
}
Object[][] mSort = mSort();
for(int i=0;i<mClassOne.size();i++){
int z = (Integer)mSort[i][0];
mClassOne.get(z).printY();
}
which could output something like this:
2, 4, 5, 6, 9
Hopefully the code above is clear enough so others can see what I'm trying to do; the question is:
"How could I combine both ArrayLists then sort them by their respective y value."
The Answer I was looking for
ArrayList<MyClassOne> mTest = new ArrayList<MyClassOne>();
mTest.addAll(mClassOne);
mTest.addAll(mClassTwo);
Collections.sort(mTest, new Comparator<MyClassOne>(){
#Override
public int compare(MyClassOne obj1, MyClassTwo obj2) {
return (int) (obj1.getY() - obj2.getY()); }
}
);
// mTest is now sorted, verified by ~ foreach(mTest) {print mTest.getY(); }
Well, you could use a Comparator<MyClassOne> which should be able to handle MyClassTwo instances as well, since MyClassTwo extends MyClassOne.
Just create a single List<MyClassOne>, add all elements of the other lists and sort.
In cases where the classes don't extend each other, introduce a common interface.