Есть разреженные матрицы, которые в основном хранят нули и лишь несколько значимых элементов. <...> С другой — эта операция прямо противоречит всей идеологии разреженных матриц — уменьшение используемой памяти.
toArray() в данном случае, можно понимать как сериализацию, соответственно, то, что вы выдадите массив заполненный сплошными значениями (в том числе и 0), ничего противоестественного не произойдет. Понятно, что хранить и совершать операции пользователь будет над оптимальной структурой.
Разделять матрицы на уровне интерфейса если вы не можете придумать действительно значимые различия, может быть неправильным. Вспомните интерфейс List и имплментации LinkedList и ArrayList. Было бы странно их разделять на уровне интерфейса.