複素数と実数と整数と

TForm is-a TControl is-a TObject, 例をVCLから出しますけどそういうもんだと思ってください。
TForm.InstanceSize >= TControl.InstanceSize >= TObject.InstanceSize, フィールド追加していくわけですから当然ですね?
サブクラスは機能の追加と同時に部分集合、だから列挙型を含むスカラーの「継承」は新しい要素を追加するのではなく部分範囲となる…OK?…これはややこしいかもですね。TControlへはTFormの全てが代入できるのに対し逆は不可。IntegerへはByteの全てが代入できるのに対し逆は不可。そういうことです。いいですね?
じゃあ複素数

type Complex = class Re: Real; Im: Imaginary; end;

そしてそのサブクラスである実数。

type Real = class(Complex) invaliants Im = 0; end; {突然Chromeの文法を混ぜる, なお演算子は適当にオーバーロードされてると思いねえ}

ついでに整数。

type Integer = class(Real) invaliants Re = Trunc(Re); end;

さらについでに虚数

type Imaginary = class(Complex) invaliants Re = 0; end;

さて、このオブジェクト群は使用可能なのか?
RealをCreateしても、値を格納するためには、そのスーパークラスのComplexのReフィールドに値を入れなければならないわけで、でもそれはまたRealなので…。
二元数ではなく複素数として全ての実数を含む集合と定義してしまった数学の…まあ数学に文句を言っても始まりません。
個人的には部分範囲型のサイズがヒントっぽいとは思っています。
Byte is-a Integerなのに、サイズは勿論Byteのほうが小さいんですよね。最初に見ましたInstanceSizeの関係とは逆です。変です。
これは、ByteやInteger等、スカラー型の変数は実際はポインタのようなものである、と理解できると考えています。何をポイントしてるのか?数直線上の一点です。
数直線上には数の実体が並んでいて、スカラー型の変数は位置を格納している。Byteのほうがポイント先の範囲が狭いので、16ビット時代のnearポインタで済む、Integerはセグメントを越えた先もポイントしないといけないのでfarポインタが必要、と、そんなイメージです。スーパークラスにサブクラスを値として代入しようとするとスライシングが起こってしまいますが、Integer型変数にByte値を代入するのは、nearポインタをfarポインタとして代入するのに等しいので、スライシングとは逆にセグメントが補われる、もとい、符号拡張が行われる、というわけです。
なかなかいい感じではないでしょうか。
この延長で、複素数と実数の関係も、なんとか理解できたらいいんですが…。
数直線を拡張して、スカラー型の変数は、複素平面上の一点を指している、と考えます。今度は虚数軸がセグメントなので実数のほうが変数のサイズは小さい。
いやまぁそれだけだったらいいんですよ…。
問題は、複素数は、同時に、実数と虚数を含む構造化型でもあるっぽい、という点です。
構造化型ということは、各部分を別個の値として扱えないといけません。
ところが、虚数に、その実数部と虚数部を別個に扱う能力を持たせてしまうと、サブクラスであるところの実数と虚数は、同じ能力を継承しないといけません。
すると先のように自分で自分を要素に持つ羽目になってしまうわけで…。
うーん、先の例はフィールドとして記述したからであって、あるいはこうか?
まず値とポインタを区別できるようにobject型で書きます。

type ComplexPlain = object
  function Re: Real; virtual; {自身へのポインタ(32bit)から下位16bit切り出して返す}
  function Im: Imaginary; virtual; {自身へのポインタ(32bit)から上位16bit切り出して返す}
end;
type Complex = ^ComplexPlain; {32bit}
type RealLine = object(ComplexPlain)
  function Re: Real; virtual; {自身へのポインタ(16bit)を返す}
  function Im: Imaginary; virtual; {常に0を示すImaginaryLineのインスタンスへのポインタ(16bit)を返す}
end;
type Real = ^RealLine; {16bit}
type ImaginaryLine = object(ComplexPlain)
  function Re: Real; virtual; {常に0を示すRealLineのインスタンスへのポインタ(16bit)を返す}
  function Im: Imaginary; virtual; {自身へのポインタ(16bit)を返す}
end;
type Imaginary = ^ImaginaryLine; {16bit}

インスタンスのサイズはVMTを考えなければ全部0というかFPUが拡張精度浮動小数点の値として区別できる最小の面積で、それが複素平面状に敷き詰められていて、位置だけで区別されるイメージです。
一見矛盾は無さそうではありますが…。整数を派生させてみましょうか。

type IntegerLine = object(RealLine) {略} end;
type Integer = ^IntegerLine;

変数のサイズは、実数部と虚数部を分けたように、整数部と小数部で分けて取り扱うようにすれば、減らせるとして。
…。
あ、あれ?
この考え方でいい…のかな?
「快刀乱麻の解答を持ってる人がいたら是非教えてください」とか書こうとして書き始めたはずなのに、何が引っかかってたか忘れた。い、いや、典型的な、書いてみたら考えがすっきりまとまった例か?