Is it possible to do an make an anonymous object through casting, when the compiler won't know what it's casting to until runtime? For example, public class Base{ yada yada yada } public class Derive1{ public void method(){} } public class Derive2{ public void method(){} } public class test{ Base x=new Base(); Object o1; if (true){o1=Derive1;} else {o1=Derive2;} (o1)x.method(); } will that work? I am quite the beginner, so please feel free to correct any other errors I may have made. Thanks. Adam
jason adam
Chicken Farmer ()
Ranch Hand
Joined: May 08, 2001
Posts: 1932
posted
0
That would not compile because (o1)x.method() is not a statement. When you cast, you are setting a returned object to be something different that what is returned. For example, in ArrayList, you have the get() method that returns an object of class Object. If your ArrayList holds a bunch of Strings, you would do something like String s = (String)aList.get( "key" ); Hope this helps a little, Jason
BJ Grau
Ranch Hand
Joined: Jul 10, 2001
Posts: 234
posted
0
Im not 100% sure what your trying to do. When you say (o1)x.method(); I think you are trying to cast, but thats not how you use the operator. You use it like this: (Type) Object of some type for example, if you have an instance of Date called d, and you want to cast it to an Object, you would say: Object o = (Object) d; In this case, though you dont even need to use the cast, because Object is a superclass of Date, so the cast is implied. Its OK to explicitly show it, but it would also be correct to say Object o = d; Now suppose you have an Object o, and you wish to cast it to a Date, you would have to explicitly say Date d = (Date) o; You should do some kind of type checking in your code using the instanceof operator if you want to use casting. For example, if you are casting an Object reference to soemthing like Date, and then start calling Date methods on it, you need to be sure you have an underlying object of type Date. You test for this by saying: (Suppose you have already gotten Object o from somewhere, but know that the underlying object being referred to is of type Date and you want to call some Date methods on it) if (o instanceof Date) { Date d = (Date) o; int i = d.getDate(); } else { //Do nothing becuase the Object reference we had was not //pointing to an object of type Date }
Now to your actual question, Im not sure what you want to do, but it sounds like you want to decide what type you are casting to at runtime. Im pretty sure you can't do this because there are some compile time rules that need to be followed when casting. Look at section 5.5 of the Java 2 spec http://java.sun.com/docs/books/jls/second_edition/html/conversions.doc.html#175725 i Im going to stop rambling now. Good luck.
Adam Pauls
Greenhorn
Joined: Sep 01, 2001
Posts: 3
posted
0
What I am trying to do, as unclear as it may be, is make (o1)x return a Derived class, and then call that class's method(). The reason I am doing this is because I'm trying to make a chess game, where every piece has a different isMovePossible() method, but all contain the same data. The pieces are stored in an array of type Piece, but when I want to see if a Piece can make a move, I want to cast it, like so: if ( (King)PieceX.isMovePossible() ) { . . . } When running the game though, I'll want to call that method on any piece without me knowing what kind of piece it is, so I want to do something like if ( (PieceX.type)PieceX.isMovePossible() ) { . . . } I don't know if that will work, or if there's not just a better way. Thanks.
BJ Grau
Ranch Hand
Joined: Jul 10, 2001
Posts: 234
posted
0
OK. I understand better now what your trying to do. You need to take advantage of polymorphism. Have your specific pieces subclass piece and override the isMovePossible method. Like this: abstract class Piece { int x; int y; abstract public void isMovePossible(); public void setX(int xValue) { x = xValue; } public void setY(int yValue) { y = yValue; } }; class King extends Piece { public void isMovePossible(){ System.out.println("Calling isMovePossible in a King object at location " + x + " "+y ); } }; class Pawn extends Piece { public void isMovePossible(){ System.out.println("Calling isMovePossible in a Pawn object at location " + x + " "+y ); } }; public class Game { public static void main(String[] args) { //Instantiate some pieces King k = new King(); Pawn p = new Pawn(); //Initialize the pieces with some location data k.setX(1); k.setY(4); p.setX(2); p.setX(2); //Declare an aray of 2 pieces and place //the pieces in the array Piece pieceArray[] = new Piece[2]; pieceArray[0] = k; pieceArray[1] = p; //Now loop over the array and call isMovePossible //for each Piece in the array. //Each pieces method will be called based on what //specific kind of piece it is for (int i =0;i < pieceArray.length;i++ ) { Game.makeMove(pieceArray[i]); }
} static void makeMove(Piece p) { //Here we are being passed a reference //of type piece, but we don't know //which subclass of piece it is, nor //do we care. All we know is we are being passed //something that is Piece or extends Piece //and the specific class's isMovePossible //mehtod will be called p.isMovePossible(); } } The object type will be determined at runtime. No need to cast. Hope this helps.
Adam Pauls
Greenhorn
Joined: Sep 01, 2001
Posts: 3
posted
0
That makes sense, and is what I was planning on doing, but I was under the impression that one could not store anything in an abstract class (i.e. having a Piece[] array shouldn't be possible), but clearly I misunderstood. That'll make things alot easier. Learn something new every day. Thanks Adam