You can only refer to class properties from a class variable defined by its class type. Let’s look at your initial block line by line.
a = new();
You construct a class object of the class type A. This object has only one class property:i. The object handle is stored in the class variable a.
b = new();
You construct a class object of the class type B. This object has two class property:iand j. The object handle is stored in the class variable b.
a = b;
You assign the class handle stored in the variable b to a. Now both variables reference the same object, the one you constructed of type B. The object handle that used to be stored in variable a of type A is no longer available and that object will be removed.
$cast(b,a);
This checks that the type of the object referenced by a is compatible the type of class variable b. Had you not had the previous a=b; statement above, this would have produced an error. The $cast ensures that variable b contains a handle to an object of type B or any type derived fromB.
b.j = 8;
This statement is always legal as long as b is not null. The compiler assures us that the only kinds of objects that b can reference are of type B or an extension of B. That type of object will always have a class property j.
a.j = 2;
$display(“a is”,a.j);
These statements are always illegal because class variable a has no knowledge of types other than class A. Because the compiler allows only certain kinds of assignments to the variable a, it can’t guarantee that it will always contain a class object with a property j.
Your example is trivial with no conditional branching. The compiler does not look at your code in total and try to prove that a had a type B object at the time it get executed.