Parler des classes et des objets dans Delphi
1. Je ne peux pas comprendre plusieurs concepts sans être instruit.
En parlant de classes et d'objets, nous ne pouvons que mentionner les concepts suivants : classes, objets et instances. Personnellement, je pense que ça va
Comprenez-le de cette façon : objet fait référence à un terme général, et toute entité dans la nature peut être considérée comme un objet tandis que classe fait référence ;
Une série de catégories divisées en certaines caractéristiques de ces objets ; une instance fait spécifiquement référence à un objet appartenant à une certaine catégorie.
D'accord, je n'ai pas besoin d'en dire plus sur ces grands principes. Pourquoi ne pas adopter une approche "contraire", utilisons Delphi
code pour expliquer certains concepts avancés par ces étrangers et difficiles à comprendre pour nous chinois :
var
ABtn : TButton ;
Définissez ABtn comme un objet appartenant à la classe TButton, mais ABtn ne peut pas être considéré comme une instance car il n'a pas
est créé, on dit donc qu'un objet est défini Si une instance est définie, plus ou moins.
Certains ne sont pas assez précis. :)
commencer
ABtn:=TButton.Create(Self);//Créer une instance de TButton
ABtn.Caption:='objet';
ABtn.Gratuit ;
fin;
2. L’objet est un véritable pointeur
D'un point de vue physique, l'objet est un espace d'adressage, et le symbole de cet espace d'adressage est ce que nous définissons.
Classe "Variable". Nous pouvons donc considérer un objet comme un pointeur vers une classe. Comme nous le savons tous, pour accéder à un pointeur, il suffit
Le pointeur doit être initialisé. Puisque l'objet est un pointeur, il doit être initialisé. Comment l'initialiser ?
Parlons de l'initialisation des pointeurs. Il existe deux manières d'initialiser un pointeur :
(1) Distribution directe
var
Pinte :^Entier ;
commencer
nouveau (pinte);
Pinte^ :=12 ;
Jeter (pinte);
fin;
(2) Variables pointant vers d'autres espaces alloués
var
Pinte :^Entier ;
je:entier;
commencer
je :=12 ;
Pinte :=@i ;
fin;
Fait intéressant, il existe deux manières d’initialiser des « pointeurs » comme des objets :
(1) Distribution directe
var
Formulaire A : Formulaire T ;
commencer
AForm:=TForm.Create(Self);
AForm.ShowModal;
AForm.Free;
fin;
(2) Pointer vers d'autres instances de l'espace alloué
var
AForm:TForm;
commencer
AForm:=Soi;
AForm.Caption:='Le savez-vous ? Pourquoi cela se produit-il ?
fin;
file://Cet AForm et l'instance de formulaire qu'il pointe pour partager la même unité d'adresse, et toutes les opérations sur l'AForm répondront
file:// vers son instance de formulaire correspondante.
En parlant de cela, nous pouvons facilement expliquer pourquoi les paramètres objets de la procédure (fonction) sont passés dans un format comme celui-ci :
(1)Procédure SetEdit(var Edit:TEdit);
commencer
Edit.Text:='11';
fin;
et
(2) procédure SetEdit(Edit:TEdit);
commencer
Edit.Text:='11';
fin;
L'effet est le même. (1) consiste à transmettre une entité TEdit comme référence de paramètre, (2) consiste à
Passez un "pointeur" d'objet TEdit en tant que paramètre.
3. La classe peut être comprise comme un type de données spécial
Nous savons que les types de données peuvent être forcés à effectuer une conversion puisqu'une classe peut être comprise comme un type de données.
Ensuite, il devrait également être capable d'effectuer une conversion de type de classe. Par exemple, le code suivant est un événement de clic d'un bouton (Button1) :
(un)
procédure TForm1.Button1Click(Expéditeur : TObject);
var
ALégende : Chaîne ;
commencer
ACaption:=TButton(Sender).Caption;//Sender convertit de TObject en TButton
ShowMessage(Format('Vous avez cliqué sur ''%s'' !',[ACaption]));
fin;
Dans ce code, Sender est un objet de type TObject, et nous le convertissons en type TButton. comme toi
Si vous n’y voyez pas clairement, vous pouvez vous référer à notre conversion habituelle de types de données :
(deux)
procédure TForm1.Button1Click(Expéditeur : TObject);
var
S_Str : chaîne ;
P_Str:PChar;
commencer
S_Str:='J'aime la Chine !';
P_Str:=PChar(S_Str);
S_Str:='';
S_Str:=Chaîne(P_Str);
ShowMessage(S_Str);
fin;
Cependant, dans le processus de programmation orientée objet, l'accent est mis sur la sécurité. Par exemple, la conversion de type forcée dans (1) présente de nombreux problèmes.
Sécurité. Le code suivant écrit toujours l'événement Button1.OnClick :
(trois)
procédure TForm1.Button1Click(Expéditeur : TObject);
commencer
TCanvas(Expéditeur).Brush.Color:=clRed;
fin;
Si vous l'exécutez, une erreur se produira. Cela ne viole-t-il pas le but de la programmation orientée objet ? Non, bien sûr
S'il s'agit d'une classe, il devrait y avoir une méthode de coercition de classe spécifique à la classe. La méthode pour modifier (3) est la suivante :
(Quatre)
procédure TForm1.Button1Click(Expéditeur : TObject);
commencer
(Expéditeur en tant que TCanvas).Brush.Color:=clRed;
end;//Utilisez as pour convertir, car cela peut détecter l'erreur et n'affectera pas le fonctionnement normal du programme.
En parlant de cela, permettez-moi de mentionner VB en passant. Si vous avez appris VB, vous trouverez peut-être le tableau de contrôle plus agréable, en particulier dans.
Lors de l'écriture d'un programme comme une calculatrice. Mais que nous apporte Delphi ? La réponse est que Delphi peut également être ouvert de manière rapide et concise.
Émettez un tel programme. Si vous faites ceci : placez une édition et dix boutons sur le formulaire, divisez Button.Caption en
Ne le définissez pas sur « 0 », « 1 », « 2 »,... « 9 », puis écrivez l'événement OnClick d'un bouton comme suit :
(cinq)
procédure TForm1.Button1Click(Expéditeur : TObject);
commencer
Edit1.Text:=Edit1.Text+(Expéditeur en tant que TButton).Caption;
fin;
Associez les événements OnClick des autres boutons à Button1Click et exécutez le programme. Tapez dans vos mains !
Le prototype du programme est maintenant disponible. Nous utilisons la conversion de type de classe de Delphi pour développer une fonction de tableau de contrôle similaire à celle de VB.
Le programme est également génial :)
4. Classe abstraite et ses instances
Il existe une classe dans Delphi appelée classe abstraite, et vous ne pouvez pas en créer naïvement directement une instance. Tels que : TStrings
gentil. Le code suivant :
(un)
var
StrLst : TStrings ;
commencer
StrLst:=TStrings.Create;
StrLst.Add('J'aime le Japon !');
StrLst.Free;
fin;
Ce n'est pas correct. Alors, comment construire des instances de classes abstraites comme TStrings ? La réponse est d'utiliser son système sans pompage
Sous-classe d'éléphants. Nous savons que TStrings possède une sous-classe non abstraite de TStringList. Nous pouvons faire ceci :
(deux)
var
StrLst : TStrings ;
commencer
StrLst:=TStringList.Create;//Subclass StrLst avec l'aide de son constructeur de sous-classe
StrLst.Add('J'aime la Chine !');
StrLst.Free;
fin;
(trois)
var
StrLst:TStringList;
commencer
StrLst:=TStringList.Create;
file://Abandonnez, n'utilisez plus de classes abstraites, utilisez simplement son "fils" pour faire vos affaires
StrLst.Add('J'aime la Chine !');
StrLst.Free;
fin;
5. Les classes sont un mécanisme hautement encapsulant pour les données et les opérations.
(1) Encapsulation des données
unité Unité2 ;
interface
taper
Employé=classe
privé
FNom : Chaîne ;
publique
Constructeur Créer ;
fonction GetName:String;
procédure SetName(AName:String);
fin;
mise en œuvre
{ Employé }
constructeur TEmployee.Create ;
commencer
FName:='Feu flamboyant';
fin;
fonction TEmployee.GetName : chaîne ;
commencer
Résultat :=FName ;
fin;
procédure TEmployee.SetName(AName: String);
commencer
FNom:=ANom;
fin;
fin.
Comme le montre le code ci-dessus, nous utilisons une procédure SetName et une fonction GetName pour définir complètement la variable privée FName.
Encapsulation. C'est tout ce que nous devons faire avec FName :
utilise
unité2 ;
procédure TForm1.Button1Click(Expéditeur : TObject);
var
AEmployé : Employé ;
commencer
AEmployee:=TEmployee.Create;
AEmployee.SetName('Rose');//Utilisez SetName pour définir FName
MessageBox(Handle,PChar(AEmployee.GetName),'Empoyee',0);
file://Utilisez GetName pour accéder à FName
AEmployé.Gratuit ;
fin;
(2) Opération d'encapsulation
unité Unité2 ;
interface
taper
TDivision=Classe
publique
file://polymorphism rend votre programme plus "flexible"
fonction GetDiv(Num1,Num2:Double):Double;surcharge;
fonction GetDiv(Num1,Num2:integer):entier;surcharge;
fin;
mise en œuvre
{ Division }
fonction TDivision.GetDiv(Num1, Num2 : Double) : Double ;
commencer
essayer
Résultat :=Num1/Num2 ;
sauf
Résultat :=0 ;//Fournit un mécanisme de traitement des puces pour gérer la situation où le diviseur est 0
fin;
fin;
fonction TDivision.GetDiv(Num1, Num2 : entier) : entier ;
commencer
essayer
Résultat :=Num1 div Num2 ;
sauf
Résultat :=0 ;//Fournit un mécanisme de traitement des puces pour gérer la situation où le diviseur est 0
fin;
fin;
fin.
Dans le code ci-dessus, nous utilisons le mécanisme de polymorphisme de la classe pour traiter respectivement la division en division entière et en division non entière, et utilisons l'écran de gestion des exceptions
Pour supprimer le cas où le numéro est 0, pour assurer la sécurité de l'opération, lors de l'appel, on peut procéder ainsi :
utilise
unité2 ;
{$R *.dfm}
procédure TForm1.Button1Click(Expéditeur : TObject);
var
Division : Division TD ;
Valeur IV : entier ;
Valeur F : Double ;
commencer
Division:=TDivision.Create;
IValue:=Division.GetDiv(1,2);
FValue:=Division.GetDiv(1.0,2);
IValue:=Division.GetDiv(1,0);
FValue:=Division.GetDiv(1.0,0);
Division.Gratuit ;
fin;
6. Les classes sont un mécanisme de réutilisation de code
Par exemple, en 5, si l'on souhaite ajouter une fonction GetAdd à cette classe pour effectuer des opérations d'addition, on peut utiliser l'héritage de classe. comme
Écrivez simplement :
(un)
unité Unité2 ;
interface
taper
TDivision=Classe
publique
fonction GetDiv(Num1,Num2:Double):Double;surcharge;
fonction GetDiv(Num1,Num2:integer):entier;surcharge;
fin;
taper
TOpération=Classe(TDivision)
publique
fonction GetAdd(Num1,Num2:Double):Double;
fin;
mise en œuvre
{ Division }
fonction TDivision.GetDiv(Num1, Num2 : Double) : Double ;
commencer
essayer
Résultat :=Num1/Num2 ;
sauf
Résultat :=0 ;
fin;
fin;
fonction TDivision.GetDiv(Num1, Num2 : entier) : entier ;
commencer
essayer
Résultat :=Num1 div Num2 ;
sauf
Résultat :=0 ;
fin;
fin;
{TOPOpération}
fonction TOperation.GetAdd(Num1, Num2 : Double) : Double ;
commencer
Résultat :=Num1+Num2 ;
fin;
fin.
Ici, nous héritons d'une sous-classe TOPeration de TDivision. L'opération peut avoir TDivsion
La méthode publique GetDiv possède sa propre méthode unique GetAdd. C'est le cours « prenez le gâteau et mangez-le aussi » que nous propose.
Méthode "Obtenir". Pas mal :)