Проблема 0: В PHP нет перегрузки операторов и магических методов как в Пайтоне под такое дело
Вариант 1: Условно функциональный
Можно например так (если конечно вам подойдет)
$a() - $b()
Тогда надо просто __invoke() реализовать в каждом из классов
Плюс такого, что в $a или $b может быть не только класс, но callable
<?php
class N {
private int $n;
public function __construct(int $n = 0) {
$this->n = $n;
}
public function __invoke(): int {
return $this->n;
}
}
$a = new N(5);
$b = fn() => 100;
var_dump($a() - $b()); // -95
И даже на лету передавать аргументы, например мультипликатор:
<?php
class N {
private int $n;
public function __construct(int $n = 0) {
$this->n = $n;
}
public function __invoke(int $multiplier = 1): int {
return $multiplier * $this->n;
}
}
$a = new N(5);
$b = fn(int $multiplier = 1) => $multiplier * 100;
var_dump($a(100) - $b()); // 400
sandbox.onlinephpfunctions.com/code/331eef7f9ad530...
А можно передавать еще callable :) Крч вот вариант функциональный очень гибкий
Или наоборот в конструкторе зашить мультипликатор, а сами числа передавать на лету, по-разному можно сделать
Вариант 2: Value Object
Можно посомтреть как сделан интерфейс например у объекта DateTime и увидеть, как работает diff() (разница времени) и можно сделать похожий интерфейс
<?php
interface NumericInterface {
public function add(Numeric $second): NumericInterface;
public function toInt(): int;
}
class Numeric implements NumericInterface {
private $n;
public function __construct($n = 0) {
$this->n = $n;
}
public function add(Numeric $second): self {
return new self($second->n + $this->n);
}
public function toInt(): int {
return $this->n;
}
}
$num1 = new Numeric(10);
$num2 = new Numeric(18);
$result = $num1->add($num2)->toInt();
var_dump($result); // 28