2015-09-12 3 views
1

Я создал класс Matrix в Groovy, и перегружает функцию multiply(), так что я могу легко писать такие вещи, как:от перегрузки BigDecimal в Groovy

Matrix m1 = [[1.0, 0.0],[0.0,1.0]] 
Matrix m2 = m1 * 2.0 
Matrix m3 = m1 * m2 
Matrix m4 = m1 * [[5.0],[10.0]] 

Но теперь, скажем, я пишу:

Matrix m5 = 2.0 * m1 
Matrix m6 = [[5.0,10.0]] * m1 

Эти две линии производят ошибку, потому что классы BigDecimal и ArrayList не может быть умножена на Matrix.

Есть ли способ перегрузить multiply() для этих классов? (Я знаю, что я мог бы просто расширить эти два класса, но есть способ сказать Groovy использовать расширенные классы при компиляции кода?)

ответ

2

Вы можете перегрузить метод multiply() в BigDecimal и ArrayList. Расширение классов не будет работать так, как вам хотелось бы, поскольку Groovy не будет создавать экземпляры ваших подклассов от BigDecimal и List литералов.

Моей первой рекомендацией является просто придерживаться синтаксиса, в котором экземпляр Matrix является приемником метода multiply(). Пример: matrix.multiply (независимо). Это делается для того, чтобы не создавать пучки дубликатов multiply(). Ex. Matrix.multiply (BigInteger) и BigInteger.multiply (матрица).

Пример

Несмотря на это, вот пример того, как добавить матрицы математические методы в BigDecimal и List:

Matrix m1 = [[1.0, 0.0],[0.0,1.0]] 
def m2 = m1 * 2.0 
def m3 = m1 * m2 

use(MatrixMath) { 
    def m4 = 2.0 * m1 
    def m5 = [[5.0,10.0]] * m1 
} 

/* 
* IMPORTANT: This is a dummy Matrix implementation. 
* I was bored to death during this particular 
* math lesson. 
* In other words, the matrix math is all made up! 
*/ 
@groovy.transform.TupleConstructor 
class Matrix { 
    List<List> matrix 

    Matrix multiply(BigDecimal number) { 
     matrix*.collect { it * 2 } 
    } 

    Matrix multiply(Matrix other) { 
     (matrix + other.matrix) 
      .transpose() 
      .flatten() 
      .collate(2) 
      .collect { it[0] * it[1] } 
      .collate(2) 
    } 
} 

class MatrixMath { 
    static Matrix multiply(BigDecimal number, Matrix matrix) { 
     matrix * number 
    } 

    static Matrix multiply(List list, Matrix matrix) { 
     matrix * (list as Matrix) 
    } 
} 

Этот пример использует Groovy категорию. Я выбрал категорию, чтобы сохранить реализации multiply() вместе в одном классе.

Если матрица немного больше, чем List<List>, обратите внимание, что при таком подходе вы действительно можете избавиться от класса Matrix. Вместо этого вы можете поместить все версии multiply() в категорию MatrixMath и использовать в качестве своей матрицы List<List>.

+0

Блестящий, спасибо! Любите придуманную математику :-) –

Смежные вопросы