Question about Unity serialize system

Hi, i have a question about unity serialization system. these is pseudo code about problem.

[System.Serializable]
public class Parent
{
    public int a;
    public Parent()
    {
        a = 111;
    }
}

[System.Serializable]
public class Child : Parent
{
    public int b;
    public Child()
    {
        b = 222;
    }
}

[System.Serializable]
public class SOTest : ScriptableObject
{
    public List<Parent> _database = new List<Parent>();
}

SOTest class has List field and i add few instances that is child instance as below.

public class test : MonoBehaviour
{
    SOTest _database;

    void OnGUI()
    {
        if (GUILayout.Button("open"))
        {
            // load ScriptableObject
        }
        if (GUILayout.Button("create"))
        {
            // save ScriptableObject
        }
        if (GUILayout.Button("add"))
        {
            Parent test = new Child();
            _database._database.Add(test);
        }
        if (GUILayout.Button("show"))
        {
            for (int i = 0; i < _database._database.Count; i++)
            {
                Child child = _database._database *as Child;*

if (child != null)
{
Debug.Log(child.a + " " + child.b);
}
else
{
Debug.Log(“there is no child”);
}
}
}
}
}
Problem is
2. i try to add child instances to database scriptableobject by push add button on screen.
3. then if i push show button, log shows me “111 222” that is exactly i expected.
4. then i save database object on disk.(serialization)
5. restart unity.
6. Load database object from disk.(deserialization)
7. push “show” button. BUT, Logs are “there is no child”.
i think when i use generic list, deserialization from disk will retrieve exactly type of List. so if i add some kind of derived instance to list then serialization will lose derived class information.
Am i right?
if i am wrong, how can fix this problem
thank you.

This is full code i tested.

[System.Serializable]
public class Parent
{
    public int a;
    
    public Parent()
    {
        a = 111;
    }
}

[System.Serializable]
public class Child : Parent
{
    public int b;

    public Child()
    {
        b = 222;
    }
}

[System.Serializable]
public class SOTest : ScriptableObject
{
    public List<Parent> _database = new List<Parent>();

    public static ScriptableObject Create(string folder, string file)
    {
        string fullPath = folder + "/" + file;

        SOTest database = AssetDatabase.LoadAssetAtPath(fullPath, typeof(SOTest)) as SOTest;
        if (database == null)
        {
            if (!AssetDatabase.IsValidFolder(folder))
            {
                AssetDatabase.CreateFolder(null, folder);
            }

            database = ScriptableObject.CreateInstance<SOTest>() as SOTest;
            AssetDatabase.CreateAsset(database, fullPath);
            AssetDatabase.SaveAssets();
        }

        return database;
    }
}

public class test : MonoBehaviour
{
    string _assetFullPath;
    string _assetFolder;
    string _assetFile;
    SOTest _database;

    void OnGUI()
    {
        if(GUILayout.Button("open"))
        {
            Open();
        }
        if (GUILayout.Button("create"))
        {
            Save();
        }
        if (GUILayout.Button("add"))
        {
            Parent aa = new Child();
            _database._database.Add(aa);
        }
        if(GUILayout.Button("show"))
        {
            for(int i=0; i<_database._database.Count; i++)
            {
                Child child = _database._database *as Child;*

if(child != null)
{
Debug.Log(child.a + " " + child.b);
}
else
{
Debug.Log(“there is no child”);
}
}
}
}

public void Open()
{
_assetFullPath = EditorUtility.OpenFilePanel(“Open Database”, Constants._item_Db_FullPath, “asset”);
if (_assetFullPath != “”)
{
LoadDatabase();
}
}

public void Save()
{
_assetFullPath = EditorUtility.SaveFilePanel(“Create Database”, Constants._item_Db_FullPath, “New Database”, “asset”);
if (_assetFullPath != “”)
{
LoadDatabase();
}
}

public void LoadDatabase()
{
if (_assetFullPath != null)
{
string absolutePath = Path.GetDirectoryName(_assetFullPath);

int index = absolutePath.IndexOf(“Assets”);

_assetFolder = absolutePath.Substring(index);
_assetFile = Path.GetFileName(_assetFullPath);

// DB Load
if (_assetFolder != “” && _assetFile != “”)
{
_database = SOTest.Create(_assetFolder, _assetFile) as SOTest;
}
}
}
}