MaxG
MaxG

Reputation: 1077

Class inheritance - properly calling methods

I'm coming from a long period of programming in Java. I'm solving a coding problem and trying to write an abstract solution class that will be extended by three classes:

var isValidSudoku = function(board) {
  return new CheckRows(board).isValid()
  // && checkCols(board)
  // && checkBoxes(board);
};

class AbstractSolver {
  constructor(board) {
    this._board = board;
    this._numSet = new Set();
    this._state = {
      x: 0,
      y: 0,
    }
  }

  getCell() {
    const numString = this._board[this._state.y][this._state.x];
    return isNumBetween0And9(numString) ?
      {
        isNum: true,
        num: parseInt(numString, 10),
      } :
      {
        isNum: false,
      };
  }

  nextCell() {}

  nextBlock() {}

  isBlockFinish() {}

  isBoardFinish() {}

  isValid() {
    while (this.isBoardFinish() == false) {
      while (this.isBlockFinish() == false) {
        const {
          isNum,
          num,
        } = this.getCell();
        if (isNum == false) {
          // do nothing
        } else if (this._numSet.has(num)) {
          return false;
        } else {
          this._numSet.add(num);
        }
        this.nextCell();
      }
      this.numSet.clear();
      this.nextBlock();
    }
    return true;
  }
}

function check(a) {
  return f => f(a);
}

function isNumBetween0And9(i) {
  const checkNum = check(i);
  return checkNum(Number.isInteger) && checkNum(x => x >= 0) && checkNum(x => x <= 9);
}

class CheckRows extends AbstractSolver {
  constructor(board) {
    super(board);
    this._boardLen = 9;
  }

  nextCell() {
    this._state = {
      x: this._state.x + 1,
      y: this._state.y,
    };
  }

  nextBlock() {
    this._state = {
      x: 0,
      y: this._state.y + 1,
    };
  }

  isBlockFinish() {
    this._state.x >= this._boardLen;
  }

  isBoardFinish() {
    this._state.x >= this._boardLen && this.state.y >= this._boardLen;
  }
}

const testParam = [
  ["5", "3", ".", ".", "7", ".", ".", ".", "."],
  ["6", ".", ".", "1", "9", "5", ".", ".", "."],
  [".", "9", "8", ".", ".", ".", ".", "6", "."],
  ["8", ".", ".", ".", "6", ".", ".", ".", "3"],
  ["4", ".", ".", "8", ".", "3", ".", ".", "1"],
  ["7", ".", ".", ".", "2", ".", ".", ".", "6"],
  [".", "6", ".", ".", ".", ".", "2", "8", "."],
  [".", ".", ".", "4", "1", "9", ".", ".", "5"],
  [".", ".", ".", ".", "8", ".", ".", "7", "9"]
];
const testParam2 = [
  ["5", "3", "3", ".", "7", ".", ".", ".", "."],
  ["6", ".", ".", "1", "9", "5", ".", ".", "."],
  [".", "9", "8", ".", ".", ".", ".", "6", "."],
  ["8", ".", ".", ".", "6", ".", ".", ".", "3"],
  ["4", ".", ".", "8", ".", "3", ".", ".", "1"],
  ["7", ".", ".", ".", "2", ".", ".", ".", "6"],
  [".", "6", ".", ".", ".", ".", "2", "8", "."],
  [".", ".", ".", "4", "1", "9", ".", ".", "5"],
  [".", ".", ".", ".", "8", ".", ".", "7", "9"]
];
console.log(isValidSudoku(testParam2));

The problem is, when the method isValid of class CheckRows runs, It invokes the method isValid of AbstractSolver which runs Its method isValid and invokes all the unimplemented "abstract" methods of the super class instead of invoking the overridden methods of the sub-class. This would have worked in Java. Is there a way to fix It in JS? And more importantly: Is there a better best practice?

Upvotes: 0

Views: 38

Answers (1)

T.J. Crowder
T.J. Crowder

Reputation: 1074266

The problem isn't that the wrong methods get called (the right ones do), the problem is that the methods don't return a value. Just like in Java, you need the return keyword to return a value from a method:

isBlockFinish() {
  return this._state.x >= this._boardLen;
//^^^^^^
}

isBoardFinish() {
  return this._state.x >= this._boardLen && this.state.y >= this._boardLen;
//^^^^^^
}

Arrow functions have an implicit return if you use a concise function body (for example, () => value), but methods don't.


There are further problems after that (numSet instead of _numSet, an index going out of range), but that's the problem that (presumably) made you think the abstract methods rather than the overridden ones were being called.

Upvotes: 2

Related Questions