0

I want to expand the method setValueAt(int row, int col, int value) from the superclass NumberBoard in my subclass Sudoku.

In Sudoku the value is empty or 1 to 9, but in the superclass NumberBoard the value may be empty or >= 0. How can I change it in my subclass Sudoku?

The superclass NumberBoard (I can't change the superclass):

public class NumberBoard {

/** Value of an empty cell. */
public static final int EMPTY = -1;

/** The board's state. */
private int[][] board;

/**
 * Sets the value of the given cell.
 * 
 * @param row
 *            the cell's row, starting at 0.
 * @param col
 *            the cell's column, starting at 0.
 * @param value
 *            the cell's value. Must be {@code >= 0} or {@link #EMPTY}.
 */
public void setValueAt(int row, int col, int value) {
    if (isInRange(row, col) && (value == EMPTY || value >= 0)) {
        board[row][col] = value;
    }
}


/**
 * Checks if the given coordinates identify a valid cell on the board.
 * 
 * @param row
 *            the cell's row, starting at 0.
 * @param col
 *            the cell's column, starting at 0.
 * @return {@code true} if the coordinate is in range, {@code false}
 *          otherwise.
 */
protected final boolean isInRange(int row, int col) {
    return 0 <= row
            && row < board.length
            && 0 <= col
            && col < board[row].length;
  }
}

And my Code for my subclass Sudoku (Unfortunately without a point) :

public class Sudoku extends NumberBoard {


public void setValueAt(int row, int col, int value) {
    super.setValueAt(row, col, value);      
    }
  }
  • What does it mean to "expand a method"? – byxor Dec 15 '16 at 18:51
  • 1
    You don't need to redefine `setValueAt`. But you probably want to override `isInRange()`. – Kayaman Dec 15 '16 at 18:52
  • You shouldn't use inheritance. Since a Sudoku can't do all that a NumberBoard is supposed to do, it doesn't satify the Liskov principle, and should thus not inherit from NumberBoard. Use delegation instead. *Use* a NumberBoard inside Sudoku. – JB Nizet Dec 15 '16 at 18:52
  • I want to change things in it. For example the value for my Sudoku. – McJohnny OWhite Dec 15 '16 at 18:53

4 Answers4

1

check for value in subclass like

public class Sudoku extends NumberBoard {

    public void setValueAt(int row, int col, int value) {
        if(value <= 9 && value >= 1 ) {
            super.setValueAt(row, col, value);      
        } else {
           throw IllegalArgumentException ("value can be empty or between 1 & 9 (inclusive)")
        }

    }
}

Here you can accept null as int wont allow null values.

StackFlowed
  • 6,664
  • 1
  • 29
  • 45
1

After reading your question a few times, I finally understood what you want. If do not want to run the implementation inherited from the superclass, you can override the method:

public class Sudoku extends NumberBoard {

    @Override
    public void setValueAt(int row, int col, int value) {
        //do not invoke super.setValueAt() here
        //Write your new implementation here
    }
}

Your override setValueAt() by writing a new set of implementation in it.

user3437460
  • 17,253
  • 15
  • 58
  • 106
1

In Sudoku the value is empty or 1 to 9, but in the superclass NumberBoard the value may be empty or >= 0. How can I change it in my subclass Sudoku?

You could create your own exception to handle the error case :

public class IncorectValueException extends Exception{
  public IncorectValueException(){
    super();
  }
}

Besides, in NumberBoard class, in setValueAt() method you perform too many unitary processings which should be grouped in a specific method if you want to redefine the behavior of checking valid data according to the class :

`isInRange(row, col) && (value == EMPTY || value >= 0)`

could be a new method : isAcceptableValue(int row, int col, int value)

Change it :

public void setValueAt(int row, int col, int value) throws IncorectValueException{
    if (isInRange(row, col) && (value == EMPTY || value >= 0)) {
        board[row][col] = value;
    }
}

to :

public void setValueAt(int row, int col, int value) throws IncorectValueException{
    if (!isAcceptableValue(row, col)) {
       throw new IncorectValueException();             
    }
      board[row][col] = value;
}

public boolean isAcceptableValue(int row, int col, int value){
   if(isInRange(row, col) && (value == EMPTY || value >= 0)){
     return true;
   }
   return false;
}

Now, the Sudoku class could be like that :

public class Sudoku extends NumberBoard {
     ...
public boolean isAcceptableValue(int row, int col, int value){ 
   if(isInRange(row, col) && (value==EMPTY || (value >= 1 && value <= 9))) {
      return true;             
    }       
    return false;
}
davidxxx
  • 125,838
  • 23
  • 214
  • 215
1

I think you are looking for an Override here, to redefine the range of values that 'value' can take.

You could go for an Override as shown below,

public class Sudoku extends NumberBoard {

  @Override
  public void setValueAt(int row, int col, int value) {
    if (value > 0 && value <= 9) { // Considering EMPTY just means 0 as int is primitive
      super.setValueAt(row, col, value);
    } else {
      throw new IllegalArgumentException("Value cannot be negative or greater than 9");
    }
  }
}

However, a better design would be to have, may be a separate EnhancedNumberBoard class (local inner class, if required) override the method and use it as a member variable by object composition.

Prathap
  • 178
  • 1
  • 1
  • 9