Поговорим о классах и объектах в Delphi
1. Не могу понять некоторые понятия без образования.
Говоря о классах и объектах, нельзя не упомянуть следующие понятия: классы, объекты и экземпляры. Я лично думаю, что это нормально
Поймите это так: объект относится к общему термину, и любая сущность в природе может рассматриваться как объект, а класс относится к;
Ряд категорий, которые разделены на определенные характеристики этих объектов; экземпляр относится конкретно к объекту, принадлежащему определенной категории.
Хорошо, мне не нужно больше говорить об этих важных принципах. Почему бы не использовать «противоположный» подход, давайте использовать Delphi
код для объяснения некоторых концепций, выдвинутых этими иностранцами, которые нам, китайцам, трудно понять:
вар
ABtn:TButton;
Определите ABtn как объект, принадлежащий классу TButton, но нельзя сказать, что ABtn является экземпляром, поскольку он не имеет
создается, поэтому мы говорим, что объект определен, если более или менее определен экземпляр.
Некоторые из них недостаточно точны. :)
начинать
ABtn:=TButton.Create(Self);//Создаем экземпляр TButton
ABtn.Caption:='объект';
ABtn.Free;
конец;
2. Объект представляет собой полный указатель.
С физической точки зрения объект представляет собой адресное пространство, и символ этого адресного пространства — это то, что мы определяем.
Класс «Переменная». Таким образом, мы можем думать об объекте как об указателе на класс. Как мы все знаем, чтобы получить доступ к указателю, просто
Указатель должен быть инициализирован. Поскольку объект является указателем, его необходимо инициализировать. Как его инициализировать?
Давайте поговорим об инициализации указателей. Существует два способа инициализации указателя:
(1) Прямое распространение
вар
Пинта:^Целое число;
начинать
новый (Пинта);
Пинт^:=12;
Удалить (Пинта);
конец;
(2) Переменные, указывающие на другие выделенные места.
вар
Пинта:^Целое число;
я: целое число;
начинать
я:=12;
Пинта:=@i;
конец;
Интересно, что существует два способа инициализации «указателей», таких как объекты:
(1) Прямое распространение
вар
АФорма:ТФорма;
начинать
AForm:=TForm.Create(Self);
AForm.ShowModal;
AForm.Бесплатно;
конец;
(2) Укажите на другие экземпляры выделенного пространства.
вар
АФорма:ТФорма;
начинать
AForm:=Я;
AForm.Caption:='Знаете ли вы? Почему это происходит»;
конец;
file://Этот AForm и экземпляр формы, на который он указывает, используют одну и ту же адресную единицу, и все операции над AForm будут отвечать
file:// в соответствующий экземпляр формы.
Говоря об этом, мы легко можем объяснить, почему параметры объекта процедуры (функции) передаются в таком формате:
(1) PROcedure SetEdit (var Edit:TEdit);
начинать
Edit.Text:='11';
конец;
и
(2) процедура SetEdit(Edit:TEdit);
начинать
Edit.Text:='11';
конец;
Эффект тот же. (1) — передать объект TEdit в качестве ссылки на параметр, (2) —
Передайте «указатель» объекта TEdit в качестве параметра.
3. Под классом можно понимать особый тип данных.
Мы знаем, что типы данных можно принудительно преобразовать. Поскольку класс можно понимать как тип данных, то.
Тогда он также сможет выполнять преобразование типов классов. Например, следующий код представляет собой событие нажатия кнопки (Button1):
(один)
процедура TForm1.Button1Click(Отправитель: TObject);
вар
AЗаголовок:Строка;
начинать
ACaption:=TButton(Sender).Caption;//Отправитель преобразует TObject в TButton
ShowMessage(Format('Вы нажали ''%s'' !',[ACaption]));
конец;
В этом коде Sender является объектом типа TObject, и мы приводим его к типу TButton. как ты
Если вы не можете ясно видеть, вы можете обратиться к нашему обычному преобразованию типов данных:
(два)
процедура TForm1.Button1Click(Отправитель: TObject);
вар
S_Str:Строка;
P_Str:PChar;
начинать
S_Str:='Я люблю Китай!';
P_Str:=PChar(S_Str);
S_Str:='';
S_Str:=String(P_Str);
ПоказатьСообщение(S_Str);
конец;
Однако в процессе объектно-ориентированного программирования упор делается на безопасность. Например, принудительное преобразование типов в (1) имеет множество проблем.
Безопасность. Следующий код по-прежнему записывает событие Button1.OnClick:
(три)
процедура TForm1.Button1Click(Отправитель: TObject);
начинать
TCanvas(Sender).Brush.Color:=clRed;
конец;
Если вы его выполните, произойдет ошибка. Не нарушает ли это цель объектно-ориентированного программирования? Нет, конечно
Если это класс, должен быть метод приведения класса, специфичный для класса. Метод изменения (3) следующий:
(Четыре)
процедура TForm1.Button1Click(Отправитель: TObject);
начинать
(Отправитель как TCanvas).Brush.Color:=clRed;
end;//Используйте as для преобразования, так как можно отловить ошибку и это не повлияет на нормальную работу программы.
Кстати говоря, позвольте мне упомянуть VB. Если вы изучили VB, вам может показаться, что массив элементов управления в нем более приятен, особенно в .
При написании программы типа калькулятора. Но что нам дает Delphi? Ответ в том, что Delphi также можно открыть быстро и лаконично.
Выпустите такую программу. Если вы сделаете это: поместите Edit и десять кнопок на форму, разделите Button.Caption на
Не устанавливайте для него значение «0», «1», «2»,... «9», а затем напишите событие OnClick кнопки следующим образом:
(пять)
процедура TForm1.Button1Click(Отправитель: TObject);
начинать
Edit1.Text:=Edit1.Text+(Отправитель как TButton).Caption;
конец;
Свяжите события OnClick других кнопок с Button1Click и запустите программу. Хлопайте в ладоши Этот калькулятор!
Прототип программы уже доступен. Мы используем преобразование типов классов Delphi для разработки функции управляющего массива, аналогичной той, что есть в VB.
Программа тоже отличная! :)
4. Абстрактный класс и его экземпляры
В Delphi есть класс, называемый абстрактным классом, и вы не можете по наивности создать его экземпляр напрямую. Например: TStrings
добрый. Следующий код:
(один)
вар
СтрЛст: TStrings;
начинать
StrLst:=TStrings.Create;
StrLst.Add('Я люблю Японию!');
СтрЛст.Бесплатно;
конец;
Это неправильно. Так как же создать экземпляры абстрактных классов, таких как TStrings? Ответ - использовать его ненакачивающий
Подкласс слонов. Мы знаем, что у TStrings есть неабстрактный подкласс TStringList. Мы можем сделать это:
(два)
вар
СтрЛст: TStrings;
начинать
StrLst:=TStringList.Create;//Подкласс StrLst с помощью конструктора его подкласса
StrLst.Add('Я люблю Китай!');
СтрЛст.Бесплатно;
конец;
(три)
вар
СтрЛст: TStringList;
начинать
StrLst:=TStringList.Create;
file://Сдавайтесь, больше не используйте абстрактные классы, просто используйте его «сына» для своего бизнеса
StrLst.Add('Я люблю Китай!');
СтрЛст.Бесплатно;
конец;
5. Классы представляют собой механизм с высокой степенью инкапсуляции данных и операций.
(1) Инкапсуляция данных
блок Unit2;
интерфейс
тип
TEmployee=класс
частный
Имя Ф:Строка;
общественный
Конструктор Создать;
функция GetName:String;
процедура SetName(AName:String);
конец;
выполнение
{ Сотрудник }
конструктор TEmployee.Create;
начинать
FName:='BlazingFire';
конец;
функция TEmployee.GetName: String;
начинать
Результат:=FName;
конец;
процедура TEmployee.SetName(AName: String);
начинать
FName:=AName;
конец;
конец.
Как показано в приведенном выше коде, мы используем процедуру SetName и функцию GetName, чтобы полностью установить частную переменную FName.
Инкапсуляция. Это все, что нам нужно сделать с FName:
использует
блок2;
процедура TForm1.Button1Click(Отправитель: TObject);
вар
AEmployee:TEmployee;
начинать
AEmployee:=TEmployee.Create;
AEmployee.SetName('Rose');//Используйте SetName для установки FName
MessageBox(Handle,PChar(AEmployee.GetName),'Сотрудник',0);
file://Используйте GetName для доступа к FName
AСотрудник.Свободно;
конец;
(2) Инкапсуляция операций
блок Unit2;
интерфейс
тип
TDivision=Класс
общественный
file://polymorphism делает вашу программу более «гибкой»
функция GetDiv(Num1,Num2:Double):Double;перегрузка;
функция GetDiv(Num1,Num2:целое число):целое число;перегрузка;
конец;
выполнение
{ Разделение }
функция TDivision.GetDiv(Num1, Num2: Double): Double;
начинать
пытаться
Результат:=Число1/Число2;
кроме
Result:=0;//Предоставляет механизм обработки маркеров для обработки ситуации, когда делитель равен 0
конец;
конец;
функция TDivision.GetDiv(Num1, Num2: целое число): целое число;
начинать
пытаться
Результат:=Num1 div Num2;
кроме
Result:=0;//Предоставляет механизм обработки маркеров для обработки ситуации, когда делитель равен 0
конец;
конец;
конец.
В приведенном выше коде мы используем механизм полиморфизма класса для обработки деления на целочисленное и нецелочисленное деление соответственно и используем экран обработки исключений.
Чтобы исключить случай, когда число равно 0, чтобы обеспечить безопасность операции при вызове, мы можем сделать это следующим образом:
использует
блок2;
{$R *.dfm}
процедура TForm1.Button1Click(Отправитель: TObject);
вар
Подразделение: TDivision;
Значение IV: целое число;
FValue:Double;
начинать
Отдел:=TDivision.Create;
IValue:=Division.GetDiv(1,2);
FValue:=Division.GetDiv(1.0,2);
IValue:=Division.GetDiv(1,0);
FValue:=Division.GetDiv(1.0,0);
Отдел.Бесплатно;
конец;
6. Классы — это механизм повторного использования кода
Например, в версии 5, если мы хотим добавить в этот класс функцию GetAdd для выполнения операций сложения, мы можем использовать наследование классов. нравиться
Просто напишите:
(один)
блок Unit2;
интерфейс
тип
TDivision=Класс
общественный
функция GetDiv(Num1,Num2:Double):Double;перегрузка;
функция GetDiv(Num1,Num2:целое число):целое число;перегрузка;
конец;
тип
TOperation=Класс(TDivision)
общественный
функция GetAdd(Num1,Num2:Double):Double;
конец;
выполнение
{ Разделение }
функция TDivision.GetDiv(Num1, Num2: Double): Double;
начинать
пытаться
Результат:=Число1/Число2;
кроме
Результат:=0;
конец;
конец;
функция TDivision.GetDiv(Num1, Num2: целое число): целое число;
начинать
пытаться
Результат:=Num1 div Num2;
кроме
Результат:=0;
конец;
конец;
{TOPperation}
функция TOperation.GetAdd(Num1, Num2: Double): Double;
начинать
Результат:=Число1+Число2;
конец;
конец.
Здесь мы наследуем подкласс TOPeration от TDivision. TOoperation может иметь TDivsion
Открытый метод GetDiv имеет свой собственный уникальный метод GetAdd. Это урок «возьми свой торт и съешь его тоже».
«Достать» метод неплохо.