Дак объясни наконец что такое матакласс. Никогда не пользовался.
Как известно, в типизированных языках объекты называют другими словами экземплярами классов. Метакласс - это класс классов, по отношению к которому уже классы являются экземплярами метакласса. Так сказать, класс второго порядка.
Например, в Java есть класс Class, который, как и всякий класс, является потомком класса Object, но класс Class есть такой класс, экземплярами которого являются все прочие классы (в том числе и Object, и даже сам класс Class) - т.е. класс Class фактически является метаклассом, хотя формально он тоже класс (тип данных) в языке.
Тоже самое в языках .NET: есть класс Type, экземпляры которого описывают другие классы (и могут описывать самого себя) - т.е. класс Type фактически является метаклассом, хотя формально является классом. Объекты типа Type играют важную роль в механизме reflections, при использовании которого код программы можно обрабатывать (другим кодом) как данные.
Для чего это нужно? Для того, чтобы была возможность передать информацию о типе во время исполнения как данные. В этом случае класс рассматривается не как синтаксическая конструкция времени программирования и компиляции, а как данные (экземпляр метакласса) времени исполнения со всеми нужными свойствами (в частности, ссылкой на конструктор, возможно, коллекциями ссылок на методы, свойства и т.д., перечнем реализуемых интерфейсов, ссылкой на класс-предок и т.д. - зависит от конкретного языка программирования).
Пример из .NET, аналогичный примеру из Delphi, будет таким:
using System;
using System.Reflection;
namespace Program
{
class Program
{
class A
{
public A()
{
Console.WriteLine("A");
}
}
class B: A
{
public B()
{
Console.WriteLine("B");
}
}
static A CreateA(Type type)
{
// Извлекаем из описания класса информацию о его конструкторе.
// Выбираем из всех конструкторов по их сигнатурам конструктор без параметров -
// конструктор по умолчанию.
Type[] constructorArgumentsTypes = new Type[0];
ConstructorInfo constructor = type.GetConstructor(constructorArgumentsTypes);
// Вызываем конструктор по умолчанию неизвестного класса и получаем объект этого
// неизвестного класса.
object[] constructorArguments = new object[0];
object instance = constructor.Invoke(constructorArguments);
// Пытаемся привести объект неизвестного класса к классу A, если неудачно, то возвращаем null.
return instance as A;
}
static void Main(string[] args)
{
A a;
a = CreateA(typeof(A));
Console.ReadLine();
a = CreateA(typeof(B));
Console.ReadLine();
}
}
}
В результате получаем:
A
A
B
Если отказаться от приведения к A, то таким образом можно создать любой объект любого типа, но "виртуальности" конструкторов в явном виде здесь нет, в отличие от Object Pascal.
В Object Pascal конструктор нужно объявлять "виртуальным" по всей видимости лишь для того, чтобы указатель на него попал в таблицу виртуальных методов, а эта таблица используется как данные в экземпляре метакласса.
Для чего вообще передавать информацию о классах как данные? Это вопрос философский
Лично я пользовался reflections только пару раз в качестве "противопожарного" средства - заплатки, когда нужно было сделать быстроее решение, а времени на перепроектирование иерархии классов не было. Может быть полезно, когда в чужой dll-ке без исходного кода определены типы, которые нельзя уже переделать, встроить в свою иерархию классов, но очень хочется - тогда можно взять reflections
чтоб не трудно было про оба языка сразу говорить
"Оба" - это ты оптимист. Всё ещё только начинается