Это работает, потому что вы находитесь в class Person
- классу разрешено выступывать внутри своего класса. Это действительно помогает, когда вы хотите написать конструктор копирования, например:
class A
{
private:
int x;
int y;
public:
A(int a, int b) x(a), y(b) {}
A(A a) { x = a.x; y = y.x; }
};
Или если мы хотим написать operator+
и operator-
для нашего большого класса чисел.
Если вы сделаете IsHarmfulToEat
контравариантным, следующий код скомпилирует
trait Food
trait Plentiful
trait IsHarmfulToEat[-F <: Food]
object IsHarmfulToEat {
implicit def ignoreSupply[F <: Food]
(implicit isHarmful: IsHarmfulToEat[F]
): IsHarmfulToEat[F with Plentiful] =
new IsHarmfulToEat[F with Plentiful]{}
}
case class Cake() extends Food {}
object Cake {
implicit val isBad: IsHarmfulToEat[Cake] = new IsHarmfulToEat[Cake] {}
}
object FoodTest extends App {
val ignoreSupplyDoesWork: IsHarmfulToEat[Cake with Plentiful] =
IsHarmfulToEat.ignoreSupply[Cake]
val badCake = implicitly[IsHarmfulToEat[Cake]]
val manyBadCakes = implicitly[IsHarmfulToEat[Cake with Plentiful]]
}