0

I am making a chess game and trying to figure out if there is a way to make my abstract class "Piece" have a method that returns a new instance of the concrete implementations like Pawn or Rook.

For example:

static public Piece newNorthPiece(){
        return new Piece(true);
    }

Except instead of returning a Piece I want it to return whatever the class that called the method is. So if I call Pawn.newNorthPiece() I want it to return to me a new Pawn(true). And I would like to do this without having to write a new factory method for every class that extends the Piece class.

Odin Thorsen
  • 269
  • 3
  • 11
  • You need to call a concrete implementation. So either `KnightPiece`, `PawnPiece` etc. Your factory methods should determine which implementation to call. Do you have `Pawn` defined yet? – Obicere Apr 09 '17 at 22:31
  • I am fairly certain this is not possible. The superclass isn't aware of its subclasses. The real question is why you don't want to write a new factory method for every class. – RaminS Apr 09 '17 at 22:32
  • Obicere I'm not sure what you mean by that, but I have made classes for all the pieces already yes. – Odin Thorsen Apr 09 '17 at 22:35
  • @OdinThorsen He is telling you to write a separate factory method for each class. – RaminS Apr 09 '17 at 22:36
  • Gendarme because I try not to repeat myself, and I hoped there would be a way to just make this once in the abstract class, it would be much neater that way – Odin Thorsen Apr 09 '17 at 22:36
  • In rough outline, something like: `public abstract class Piece { public static Piece factory(Class pieceType) { return pieceType.newInstance();} ... }` but as you can see this isn't really buying you anything. Using `new` to create pieces isn't really "repeating yourself", and "I try not to repeat myself" is not necessarily a good engineering principle when repetition is actually inevitable. – Lew Bloch Apr 09 '17 at 22:57
  • You already know you need, say, a `Pawn` or `Rook`. A factory method is for when you only know that you need the supertype. Demanding a particular subtype defeats that anonymity, and leaves you actually writing more than simply `Pawn blackQPawn = new Pawn();`. A factory class as it should be is `Arrays.asList(E ... item)`. You only know that you get back a `List`; you cannot know which subtype. Don't apply "I try not to repeat myself" as a mantra. Think through the engineering problem and determine good logical sense. Factories for specific types aren't. – Lew Bloch Apr 09 '17 at 23:01
  • Thanks for the feedback I appreciate it. I don't mind doing something twice if I have to but if there was an easy way to solve this once I would have liked to know, that's all. – Odin Thorsen Apr 09 '17 at 23:15

3 Answers3

1

Can I make a static factory method in an abstract class?

Yes, you can create a static method inside abstract class and the method will look the below:

public abstract class PieceFactory {

    public static Piece getPiece(String pieceType){
        switch(pieceType) {
            case NorthPiece:  
                  return new NorthPiece();  

            case Pawn: 
                  return new Pawn();  
          }
     }
 }

And you can call the PieceFactory.getPiece("Pawn") whichn returns the instance of Pawn.

Vasu
  • 21,832
  • 11
  • 51
  • 67
0

In Java, you can't do that as super class does not know how many classes are extending it. The closest you can get to it is by implementing the method like this:

class Piece {
    public static Piece getInstance(Class<? extends Piece> clazz) throws InstantiationException, IllegalAccessException{
        return clazz.newInstance();
    }
}

class Pawn extends Piece {

}

You can then call the method and pass Piece's class like this:

Piece piece = Piece.getInstance(Pawn.class);

This will give you the instance of Pawn class, you can use it to get the instance of any other class that extends Piece.

P.S. This depends on a couple of factors (e.g. child class having a public constructor, Piece class having access to child class etc)

Darshan Mehta
  • 30,102
  • 11
  • 68
  • 102
-1

The Piece class is abstract, so you cannot instantiate it. You need to have a concrete implementation of your Piece class.

MigSena
  • 218
  • 2
  • 7