Informatik

Qualifikationsphase 1

Komponenten und Klassen

Reaktionstest

Beim Start des Reaktionstestes wird die Ampel auf "rot" geschaltet. Nach einem zufällig vom Rechner bestimmten Zeitraum wird die Ampel auf "grün" umgeschaltet. Sobald dies geschieht, muss eine beliebige Taste gedrückt werden. Die Zeitspanne zwischen Umschalten und Reagieren wird in Millisekunden angegeben.

Reak   Ampel

 

Begriffserklärung Objekte und Klassen

type

{ TMain }

TMain = class(TForm)
BtTestreihe: TButton;
BtReaktionstest: TButton;
EdReaktionsZeit: TEdit;
LblReaktionsZeit: TLabel;
TiReaktion: TTimer;
procedure BtReaktionstestClick(Sender: TObject);
procedure BtTestreiheClick(Sender: TObject);
procedure BtReaktionsTestKeyDown(Sender: TObject; var Key: Word;Shift: TShiftState);
procedure TiReaktionTimer(Sender: TObject);
private
{ private declarations }
Ampel: TAmpel;
Start, Stop: LongInt;
public
{ public declarations }

Betrachten wir zunächst einen Teil des Quelltextes. Das Formular "Main" hat zwei Schaltflächen, ein Textfeld, einen Timer und ein Editierfeld. Diese Komponenten sind Objekte. Auch das Formular ist ein Objekt. Alle Objekte haben Eigenschaften, Attribute und Methoden. Ein Objekt wiederum ist ein Exemplar einer Klasse. Alle Objekte einer Klasse haben gemeinsame Merkmale. Die Klasse ist also die Bauvorschrift für ein Objekt.

Die Komponenten BtTestreihe und BtReaktionstest sind Objekte der Klasse TButton; das Editierfeld EdZeit ist ein Objekt der Klasse TEdit. Die Form Main ist ein Objekt der Klasse TMain. TMain wiederum ist ein Objekt der Klasse TForm. Hier bereits sieht man, dass Klassen von anderen Klassen abgeleitet werden können. Diese Ableitung wird später besprochen.

Attribute sind Objektvariablen und Zustandsvariablen. Hinter den Methoden verstecken sich Prozeduren. Diese werden jedoch nicht innerhalb des Objektes sondern in der dazugehörigen Klasse definiert. Eigenschaften definieren das Aussehen und Verhalten von Objekten. Sie können über den Objektinspektor direkt definiert werden oder zur Laufzeit des Programms verändert werden.

Die Begriffe sollen am Beispiel des Objektes BtTestreihe und an der Klasse TMain verdeutlicht werden. Die Schaltfläche BtTestreihe hat z.B. die Eigenschaft "Caption". Dieser Eigenschaft wird der Text "Neue Testreihe" zugewiesen. Bei einem Klick auf die Schaltfläche wird die Methode "procedure BtTestreiheClick" ausgeführt. Attribute finden wir in der Klasse TButton. Sie regeln z.B. die Funktion des Buttons.

Wie erwähnt werden Attribute nur in Klassen angegeben. Dafür werden in Klassen keine Eigenschaften angegeben. Dies ist verständlich, wenn man sich vergegenwärtigt, dass die beiden Schaltflächen des Formulars unterschiedliche Texte beinhalten sollen. Attribute und Methoden in Klassen werden als Klassendiagramme dargestellt. Für die Klasse TMain sieht das Diagramm wie folgt aus:

TMain Klassenname
BtTestreihe: TButton
BtReaktionstest: TButton
EdReaktionsZeit: TEdit
LblReaktionsZeit: TLabel
TiReaktion: TTimer
Ampel: TAmpel
Start, Stop: LongInt
Attribute (Objektvariablen)
BtReaktionstestClick()
BtTestreiheClick()
BtReaktionstestKeyDown()
TiReaktionTimer()
Methoden

Objektvariablen werden in der Klassendefinition des Hauptformulars TMain festgelegt. Die Objektvariable des Hauptformulars selbst (Main: TMain) ist dagegen im Hauptmodul definiert: var  Main: TMain.

Klassen besitzen die Schutzklassen private und public. Der Benutzer eines Objektes kann nur auf Klassendefinitionen zugreifen, die unter public eingetragen sind. Auf die unter private eingetragenen Attribute und Methoden kann er nicht zugreifen. Eintragungen, die sich aus der Gestaltung eines Formulars mit Hilfe des Objektinspektors ergeben und oberhalb der Schutzklassen stehen, sind immer public. Innerhalb einer Unit kann immer auf alle Bestandteile zugegriffen werden. Betrachten wir die Klassendefinition TAmpel des Objekts Ampel. Ampel ist als Objektvariable im Hauptformular definiert, d.h. das Hauptformular greift auf die Unit Ampel zu. Der Zugriff kann jedoch nur über die in public eingetragenen Methoden erfolgen. Auf die Variable AmpelGruen kann nicht zugegriffen werden. Sie wird vom Objekt Ampel selbst verwaltet.

type

{ TAmpel }

TAmpel = class(TForm)
Shape1: TShape;
Shape2: TShape;
private
{ private declarations }
zGruen: Boolean;
public
{ public declarations }
procedure Rot;
procedure Gruen;
function IstGruen: Boolean;
end;

Im Unterricht haben wir keine Shapes benutzt: die Ampeln wurden direkt auf ein Canvas gezeichnet. Dabei ergab sich jedoch das Problem, dass die Ampeln nicht nachgezeichnet wurden, wenn ein anderes Fenster die Ampel überlagert. Durch Nutzung des OnPaint- oder OnResize-Ereignisses lassen sich die Ampeln jedoch problemlos auf ein Canvas zeichnen. Im folgenden ist ein funktionsfähiges Programm gelistet.

unit Reaktionstest;

(* Die folgende Zeile gilt nur für Lazarus *)
{$mode objfpc}{$H+}

interface

(* Die folgende uses-Anweisung gilt fürt Delphi *)
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ExtCtrls, StdCtrls, Ampel;

(* Die folgende uses-Anweisung gilt fürt Lazarus *)
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
ExtCtrls,Ampel,LCLIntf;

type
TMain = class(TForm)
BtTestreihe: TButton;
BtReaktionstest: TButton;
TiReaktion: TTimer;
EdReaktionszeit: TEdit;
LblReaktionszeit: TLabel;
procedure BtTestreiheClick(Sender: TObject);
procedure BtReaktionsTestClick(Sender: TObject);
procedure BtReaktionstestKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState)
procedure TiReaktionTimer(Sender: TObject);
private
Ampel: TAmpel;
Start, Stop: Longint;
public
{ Public-Deklarationen }
end;

var Main: TMain;

implementation

(* Die folgende Zeile gilt für Delphi *)
{$R *.DFM}

(*Die folgende Zeile gilt für Lazarus *)
{$R *.lfm}

procedure TMain.BtTestreiheClick(Sender: TObject);
begin
Ampel := TAmpel.Create (Main);
Ampel.Show;
Ampel.Rot;
BtReaktionstest.Enabled := True;
end;

procedure TMain.BtReaktionsTestClick(Sender: TObject);
begin
EdReaktionszeit.Text := '';
Ampel.Rot;
TiReaktion.Interval := 2000 + Random(3000);
TiReaktion.Enabled := True;
end;

procedure TMain.TiReaktionTimer(Sender: TObject);
begin
Ampel.Gruen;
Start := GetTickCount;
TiReaktion.Enabled := False;
end;

procedure TMain.BtReaktionsTestKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
Stop := GetTickCount;
if BtReaktionstest.Enabled
then if Ampel.IstGruen
then EdReaktionszeit.Text := ' ' + IntToStr(Stop-Start) + ' ms';
end;

end.

__________________________________________________________________________________________________________________________________

unit Ampel;

(* Die folgende Zeile gilt nur für Lazarus *)
{$mode objfpc}{$H+}

interface

(* Die folgende uses-Anweisung gilt fürt Delphi *)
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;

(* Die folgende uses-Anweisung gilt fürt Lazarus *)
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
ExtCtrls;

type
TAmpel = class(TForm)
procedure FormResize(Sender: TObject);
procedure FormPaint(Sender: TObject);
private
XRot, YRot, XGruen, YGruen: Integer;
AmpelBreite: Integer;
zGruen: Boolean;
procedure AmpelZeichnen;
public
constructor Create (Sender: TComponent);
procedure Rot;
procedure Gruen;
function IstGruen: Boolean;
end;

implementation

(* Die folgende Zeile gilt für Delphi *)
{$R *.DFM}

(*Die folgende Zeile gilt für Lazarus *)
{$R *.lfm}

constructor TAmpel.Create (Sender: TComponent);
begin
inherited Create (Sender);
Canvas.Pen.Width := 3;
end;

procedure TAmpel.Rot;
begin
zGruen := False;
AmpelZeichnen
end;

procedure TAmpel.Gruen;
begin
zGruen := True;
AmpelZeichnen
end;

function TAmpel.IstGruen: Boolean;
begin
IstGruen := zGruen
end;

procedure TAmpel.FormResize (Sender: TObject);
var Raster: Integer;
begin
ClientHeight := ClientWidth * 2;
Raster := ClientWidth div 10;
AmpelBreite := 8 * Raster;
XRot := Raster;
YRot := 9 * Raster;
XGruen := Raster;
YGruen := 18 * Raster;
AmpelZeichnen;
end;

procedure TAmpel.AmpelZeichnen;
begin
with Canvas do begin
Brush.Color := clWhite;
Rectangle (-3,-3,Width+3,Height+3);
if zGruen
then begin
Brush.Color := clLime;
Ellipse (XGruen,YGruen,XGruen+AmpelBreite,YGruen-AmpelBreite);
Brush.Color := clGray;
Ellipse(XRot,YRot,XRot+AmpelBreite,YRot-AmpelBreite);
end
else begin
Brush.Color := clRed;
Ellipse(XRot,YRot,XRot+AmpelBreite,YRot-AMpelBreite);
Brush.Color := clGray;
Ellipse (XGruen,YGruen,XGruen+AmpelBreite,YGruen-AmpelBreite);
end
end
end;

procedure TAmpel.FormPaint (Sender: TObject);
begin
AmpelZeichnen
end;

end.

 

V.Berg • Bergisch Gladbach • ImpressumHaftungsausschluss