Q: Delphi Type Casting I need a clarification on Delphi Type Casting
I wrote an example with two classes: TClassA and TClassB, TClassB derived from TClassA.
the code is as follows:
program TEST;

{$APPTYPE CONSOLE}


uses
  System.SysUtils;

type
  TClassA = class(TObject)
  public
    Member1:Integer;
    constructor Create();
    function ToString():String; override;
  end;

type
  TClassB = class(TClassA)
  public
    Member2:Integer;
    constructor Create();
    function ToString():String; override;
    function MyToString():String;
  end;

{ TClassA }

constructor TClassA.Create;
begin
  Member1 := 0;
end;

function TClassA.ToString: String;
begin
  Result := IntToStr(Member1);
end;

{ TClassB }

constructor TClassB.Create;
begin
  Member1 := 0;
  Member2 := 10;
end;

function TClassB.MyToString: String;
begin
  Result := Format('My Values is: %u AND %u',[Member1,Member2]);
end;

function TClassB.ToString: String;
begin
  Result := IntToStr(Member1) + ' - ' + IntToStr(Member2);
end;


procedure ShowInstances();
var
  a: TClassA;
  b: TClassB;
begin
  a := TClassA.Create;
  b := TClassB(a); // Casting (B and A point to the same Memory Address)
  b.Member1 := 5;
  b.Member2 := 150; // why no error? (1)

  Writeln(Format('ToString: a = %s, a = %s',[a.ToString,b.ToString])); // (2)
  Writeln(Format('Class Name: a=%s, b=%s',[a.ClassName,b.ClassName])); // (3)
  Writeln(Format('Address: a=%p, b=%p',[@a,@b])); // (4)
  Writeln(b.MyToString); // why no error? (5)

  readln;
end;

begin
  try
    ShowInstances;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

The program output is:
ToString: a = 5, a = 5
Class Name: a=TClassA, b=TClassA
Address: a=0012FF44, b=0012FF40
My Values is: 5 AND 150

(1) what's the Member2 address? is this a possible "Access Violation"?
(2) ok, ToString() method point to the same address
(3) why a and b have the same ClassName?
(4) ok, a and b are two different variables
(5) if b is TClassA, why can use "MyToString" method?

A: *

*Member2 has an address that was not allocated by a memory manager. The possible result of writing to Member2 is heap corruption with subsequent access violations in a totally different part of a program. This is a very nasty bug and compiler can't help you here. You must know what are you doing when making unsafe type casting.

*That is because ToString method is virtual, so its address is determined by the actual type of the class instance being created. If you replace virtual method by static (in your case by replacing override directive by reintroduce) the result will be different.

*Because ClassName method is kinda virtual too (not really a member of VMT, but that is insignificant implementation detail).

*Yes, a and b are two references to the same instance.

*Because ToMyString method is static. The actual type of the instance does not matter for static methods.

A: 
(1) what's the Member2 address? is this a possible "Access Violation"?

Yes. AV is possible. In your case you have luck :)

ok, ToString() method point to the same address

Yes as VTable is concerned at creation time.

(3) why a and b have the same ClassName?

same answer as in (2).

(4) ok, a and b are two different variables

Not really. you printed address from stack :)

(5) if b is TClassA, why can use "MyToString" method?

b is TClassB but by mistake points to TClassA instance.
You should use as operator for such casts. In this case it would fail.

A: You're applying a hard type cast over the variable. When you do so, you're telling the compiler you know what you're doing and the compiler trusts you.

(1) what's the Member2 address? is this a possible "Access Violation"?

When you assign a value to a member of the class, the class definition of the variable is used by the compiler to calculate the offset of that member in the memory space, so when you have a  class declaration like this:
type
  TMyClass = class(TObject)
    Member1: Integer; //4 bytes
    Member2: Integer; //4 bytes
  end;

the in-memory representation of this object looks like this:
reference (Pointer) to the object
|
|
--------> [VMT][Member1][Member 2][Monitor]
Offset     0    4        8         12

When you issue a statement like this:
MyObject.Member2 := 20;

The compiler just uses that information to calculate the memory address to apply that assignment to. In this case, the compiler the assignment may be translated to 
PInteger(NativeUInt(MyObject) + 8)^ := 20;

So, your assignment succeeds just because the way the (default) memory manager works. An AV is originated by the operating system when you try to access a memory address that is not part of your program. In this case, your program has taken more memory from the OS than required. IMHO, when you don't get an AV, you, in fact, are unlucky, because your program memory may now be silently corrupted. Any other variable that happens to reside at that address may have changed its value (or meta-data), and it would result in undefined behavior.

(2) ToString() method point to the same address

Since the ToString() method is a virtual one, the address of that method is stored in the VMT and the call is determined at runtime. Take a look at What data does a TObject contain?, and read the referenced book chapter: The Delphi Object Model.

(3) why a and b have the same ClassName?

The class name is also part of the run-time metadata of the object. The fact that you're applying the wrong mold to the object doesn't change the object itself.

(4) a and b are two different variables

Of course, you declared it, look at your code:
var
  a: TClassA;
  b: TClassB;

Well, two different variables. In Delphi, the object variables are references, so, after some lines of code both reference the same address, but that's a different thing.

(5) if b is TClassA, why can use "MyToString" method?

Because you're telling the compiler that's OK, and as said, the compiler trusts you. It is hacky, but Delphi is also a low level language and you're allowed to do a lot of crazy things, if you want, but:
Play safe
If you want (and you surely want most of the time) to be on the safe side, don't apply a hard cast like that in your code. Use the as operator:

The as operator performs checked typecasts. The expression
object as class
returns a reference to the same object as object, but with the type given by class. At runtime, object must be an instance of the class denoted by class or one of its descendants, or be nil; otherwise an exception is raised. If the declared type of object is unrelated to class - that is, if the types are distinct and one is not an ancestor of the other - a compilation error results. 

So, with the as operator, you're safe, both at compile-time and at run-time.
Change your code to:
procedure ShowInstance(A: TClassA);
var
  b: TClassB;
begin
  b := A as TClassB; //runtime exception, the rest of the compiled code 
                     //won't be executed if a is not TClassB
  b.Member1 := 5;
  b.Member2 := 150; 

  Writeln(Format('ToString: a = %s, a = %s',[a.ToString,b.ToString])); 
  Writeln(Format('Class Name: a=%s, b=%s',[a.ClassName,b.ClassName])); 
  Writeln(Format('Address: a=%p, b=%p',[@a,@b])); 
  Writeln(b.MyToString); 

  readln;
end;

procedure ShowInstances();
begin
  ShowInstance(TClassB.Create); //success
  ShowInstance(TClassA.Create); //runtime failure, no memory corrupted.
end;

