Los campos y métodos de una clase pueden definirse de tipo public, protected y private, por defecto siempre son públicos.
Un método o campo público puede ser accedido desde fuera de la clase.
Una de las ventajas de la programación orientada a objetos es permitir encapsular datos y responsabilidades dentro de una clase.
Cuando uno planea una clase tiene que definir que quiero que se muestre hacia afuera y que quiero que quede oculto.
Normalmente los campos de una clase se definen dentro de la zona private o protected. Los métodos se definen públicos si queremos que sean accesibles desde fuera y privados o protegidos cuando solo quiero que puedan ser llamados desde la misma clase o subclase.
Si bien podemos definir todo público como venimos trabajando en los conceptos anteriores el agregado de estos modificadores nos permitirá crear clases más fáciles de reutilizar.
Resumiendo
Plantear una clase llamada TDado. Definir un campo llamado Valor y tres métodos uno privado que dibuje una línea de asteríscos y otro dos públicos, uno que genere un número aleatorio entre 1 y 6 y otro que lo imprima llamando en este último al que dibuja la línea de asteríscos.
Declarar la clase TDado en una unidad.
Luego de crear el proyecto138 procedemos a crear una unidad como ya vimos en conceptos anteriores:

unit Unit1;
interface
type
TDado = class
private
Valor: Integer;
procedure Separador;
public
procedure Tirar;
procedure Imprimir;
end;
implementation
procedure TDado.Separador;
begin
WriteLn('********************');
end;
procedure TDado.Tirar;
begin
Valor := Random(6) + 1;
end;
procedure TDado.Imprimir;
begin
Separador;
WriteLn(Valor);
Separador;
end;
end.
program Proyecto138;
{$APPTYPE CONSOLE}
uses
Unit1 in 'Unit1.pas';
var
Dado1: TDado;
begin
Randomize;
WriteLn('Prueba del dado');
Dado1 := TDado.Create;
Dado1.Tirar;
Dado1.Imprimir;
Dado1.Free;
ReadLn;
end.
Disponemos de la palabra clave private para indicar que los campos y métodos siguientes solo se podrán acceder dentro de la misma clase:
TDado = class
private
Valor: Integer;
procedure Separador;
Ahora si debemos disponer de la palabra clave public para identificar que métodos serán públicos:
public
procedure Tirar;
procedure Imprimir;
La codificación de los métodos en la zona de la implementation de la unidad no varía en nada a lo ya visto.
Ahora si hay que tener en cuenta que en el archivo Proyecto138.dpr donde definimos un objeto de la clase TDado solo tenemos acceso a los métodos públicos:
var
Dado1: TDado;
begin
Randomize;
WriteLn('Prueba del dado');
Dado1 := TDado.Create;
Dado1.Tirar;
Dado1.Imprimir;
Dado1.Free;
Si intentamos acceder a un campo o método público se genera un error sintáctico:

Es decir que el objeto Dado1 solo puede llamar a los métodos Tirar e Imprimir que son los públicos.
Tiene grandes ventajas el encapsulamiento, como vemos al no poder asignar un valor al valor del dado desde fuera de la clase, luego si se genera un valor equivocado en el dado el problema se encuentra dentro de la clase TDado.
Lo más común es definir distintas unidades para cada clase, pero si codificamos la clase en el mismo archivo Proyecto138.dpr luego los objetos que definimos en ese archivo tienen acceso a los campos y métodos privados:
program Proyecto138;
{$APPTYPE CONSOLE}
type
TDado = class
private
Valor: Integer;
procedure Separador;
public
procedure Tirar;
procedure Imprimir;
end;
procedure TDado.Separador;
begin
WriteLn('********************');
end;
procedure TDado.Tirar;
begin
Valor := Random(6) + 1;
end;
procedure TDado.Imprimir;
begin
Separador;
WriteLn(Valor);
Separador;
end;
var
Dado1: TDado;
begin
Randomize;
WriteLn('Prueba del dado');
Dado1 := TDado.Create;
Dado1.Valor := 5;
Dado1.Imprimir;
Dado1.Free;
ReadLn;
end.
Este programa no genera error ya que la clase TDado se encuentra definida en el mismo archivo donde definimos el objeto Dado1.
En las últimos versiones de Delphi se ha agregado el modificador strict private y strict protected para salvar las situaciones donde se definen objetos de dicha clase en el mismo archivo:
type
TDado = class
strict private
Valor: Integer;
procedure Separador;
public
procedure Tirar;
procedure Imprimir;
end;
Declarar una clase llamada TCalculadora que disponga de dos métodos para la carga de valores de tipo Double (almacenar los datos en dos campos)
Definir las responsabilidades de sumar, restar, multiplicar, dividir e imprimir.
Declarar luego una clase llamada TCalculadoraCientifica que herede de TCalculadora y añada las responsabilidades de calcular el cuadrado del primer número y la raíz cuadrada.
Declarar las dos clases en una unidad.
Definir los campos Valor1, Valor2 y Resultado en la zona protected de la clase.
unit Unit1;
interface
type
TCalculadora = class
protected
Valor1: Double;
Valor2: Double;
Resultado: Double;
public
procedure Cargar1;
procedure Cargar2;
procedure Sumar;
procedure Restar;
procedure Multiplicar;
procedure Dividir;
procedure Imprimir(mensaje: String);
end;
TCalculadoraCientifica = class(TCalculadora)
procedure Cuadrado;
procedure Raiz;
end;
implementation
procedure TCalculadora.Cargar1;
begin
Write('Ingrese valor:');
ReadLn(Valor1);
end;
procedure TCalculadora.Cargar2;
begin
Write('Ingrese valor:');
ReadLn(Valor2);
end;
procedure TCalculadora.Sumar;
begin
Resultado := Valor1 + Valor2;
end;
procedure TCalculadora.Restar;
begin
Resultado := Valor1 - Valor2
end;
procedure TCalculadora.Multiplicar;
begin
Resultado := Valor1 * Valor2;
end;
procedure TCalculadora.Dividir;
begin
Resultado := Valor1 / Valor2;
end;
procedure TCalculadora.Imprimir(mensaje: String);
begin
WriteLn(mensaje,':', Resultado:0:2);
end;
procedure TCalculadoraCientifica.Cuadrado;
begin
Resultado := Valor1 * Valor1;
end;
procedure TCalculadoraCientifica.Raiz;
begin
Resultado := Sqrt(Valor1);
end;
end.
program Proyecto139;
{$APPTYPE CONSOLE}
uses
Unit1 in 'Unit1.pas';
var
Calculadora1: TCalculadora;
CalculadoraCientifica1: TCalculadoraCientifica;
begin
WriteLn('Uso de la calculadora');
Calculadora1 := TCalculadora.Create;
Calculadora1.Cargar1;
Calculadora1.Cargar2;
Calculadora1.Sumar;
Calculadora1.Imprimir('Suma');
Calculadora1.Restar;
Calculadora1.Imprimir('Resta');
Calculadora1.Multiplicar;
Calculadora1.Imprimir('Multiplicación');
Calculadora1.Dividir;
Calculadora1.Imprimir('Division');
Calculadora1.Free;
WriteLn('Uso de la calculadora científica');
CalculadoraCientifica1 := TCalculadoraCientifica.Create;
CalculadoraCientifica1.Cargar1;
CalculadoraCientifica1.Cargar2;
CalculadoraCientifica1.Sumar;
CalculadoraCientifica1.Imprimir('Suma');
CalculadoraCientifica1.Restar;
CalculadoraCientifica1.Imprimir('Resta');
CalculadoraCientifica1.Multiplicar;
CalculadoraCientifica1.Imprimir('Multiplicación');
CalculadoraCientifica1.Dividir;
CalculadoraCientifica1.Imprimir('Division');
CalculadoraCientifica1.Cuadrado;
CalculadoraCientifica1.Imprimir('Cuadrado del primer valor');
CalculadoraCientifica1.Raiz;
CalculadoraCientifica1.Imprimir('Raiz del primer valor');
CalculadoraCientifica1.Free;
ReadLn;
end.
La clase TCalculadora define en la zona protected los tres campos para que puedan ser accedidos solo por la clase TCalculadora o cualquier sublclase:
TCalculadora = class
protected
Valor1: Double;
Valor2: Double;
Resultado: Double;
public
procedure Cargar1;
procedure Cargar2;
procedure Sumar;
procedure Restar;
procedure Multiplicar;
procedure Dividir;
procedure Imprimir(mensaje: String);
end;
Los métodos de la clase TCalculadoraCientifica pueden acceder a los campos protected de la clase padre:
procedure TCalculadoraCientifica.Cuadrado; begin Resultado := Valor1 * Valor1; end;
Pero los objetos que se definan de la clase TCalculadora y TCalculadoraCientifica solo podrán acceder a los métodos públicos:
WriteLn('Uso de la calculadora');
Calculadora1 := TCalculadora.Create;
Calculadora1.Valor1 := 100; // Error de compilación debido al intento de acceder a un campo protegido
Hay que tener en cuenta que no podemos definir Valor1, Valor2 y Resultado en la zona private ya que esto hará que la subclase TCalculadoraCientifica no tenga acceso a dichos campos.
unit Unit1;
interface
type
TVector = array[1..5] of Integer;
TNumerosAleatorios = class
private
Vector: TVector;
procedure Cargar;
public
constructor Create;
procedure Imprimir;
procedure MostrarMayor;
procedure MostrarMenor;
end;
implementation
procedure TNumerosAleatorios.Cargar;
var
f: Integer;
begin
for f := 1 to 5 do
Vector[f] := Random(10) + 1;
end;
constructor TNumerosAleatorios.Create;
begin
Cargar;
end;
procedure TNumerosAleatorios.Imprimir;
var
f: Integer;
begin
for f:=1 to 5 do
Write(Vector[f],' ');
WriteLn;
end;
procedure TNumerosAleatorios.MostrarMayor;
var
f: Integer;
mayor: Integer;
begin
mayor := Vector[1];
for f:=2 to 5 do
if Vector[f] > mayor then
mayor := Vector[f];
WriteLn('El elemento mayor del vector es:', mayor);
end;
procedure TNumerosAleatorios.MostrarMenor;
var
f: Integer;
menor: Integer;
begin
menor := Vector[1];
for f:=2 to 5 do
if Vector[f] < menor then
menor := Vector[f];
WriteLn('El elemento menor del vector es:', menor);
end;
end.
program Proyecto140;
{$APPTYPE CONSOLE}
uses
Unit1 in 'Unit1.pas';
var
NumerosAleatorios1: TNumerosAleatorios;
begin
Randomize;
NumerosAleatorios1 := TNumerosAleatorios.Create;
NumerosAleatorios1.Imprimir;
NumerosAleatorios1.MostrarMayor;
NumerosAleatorios1.MostrarMenor;
NumerosAleatorios1.Free;
ReadLn;
end.