Pascal - Orientado a Objetos
Podemos imaginar nosso universo feito de diferentes objetos como sol, terra, lua, etc. Da mesma forma, podemos imaginar nosso carro feito de diferentes objetos como roda, direção, marcha etc. Da mesma forma, existem conceitos de programação orientada a objetos, que assumir tudo como um objeto e implementar um software usando diferentes objetos. Em Pascal, existem dois tipos de dados estruturais usados para implementar um objeto do mundo real -
- Tipos de objeto
- Tipos de classe
Conceitos Orientados a Objetos
Antes de entrarmos em detalhes, vamos definir termos Pascal importantes relacionados ao Pascal Orientado a Objetos.
Object- Um objeto é um tipo especial de registro que contém campos como um registro; entretanto, ao contrário dos registros, os objetos contêm procedimentos e funções como parte do objeto. Esses procedimentos e funções são mantidos como ponteiros para os métodos associados ao tipo do objeto.
Class- Uma classe é definida quase da mesma maneira que um objeto, mas há uma diferença na maneira como são criados. A classe é alocada no heap de um programa, enquanto o objeto é alocado na pilha. É um ponteiro para o objeto, não o próprio objeto.
Instantiation of a class- Instanciação significa criar uma variável desse tipo de classe. Como uma classe é apenas um ponteiro, quando uma variável de um tipo de classe é declarada, há memória alocada apenas para o ponteiro, não para o objeto inteiro. Somente quando ele é instanciado usando um de seus construtores, a memória é alocada para o objeto. As instâncias de uma classe também são chamadas de 'objetos', mas não as confunda com Object Pascal Objects. Neste tutorial, escreveremos 'Object' para Pascal Objects e 'object' para o objeto conceitual ou instância de classe.
Member Variables - Estas são as variáveis definidas dentro de uma classe ou um objeto.
Member Functions - Estas são as funções ou procedimentos definidos dentro de uma classe ou um objeto e são usados para acessar os dados do objeto.
Visibility of Members- Os membros de um objeto ou classe também são chamados de campos. Esses campos têm diferentes visibilidades. Visibilidade se refere à acessibilidade dos membros, ou seja, exatamente onde esses membros estarão acessíveis. Os objetos têm três níveis de visibilidade: público, privado e protegido. As aulas têm cinco tipos de visibilidade: pública, privada, estritamente privada, protegida e publicada. Discutiremos a visibilidade em detalhes.
Inheritance- Quando uma classe é definida herdando funcionalidades existentes de uma classe pai, ela é considerada herdada. Aqui, a classe filha herdará todas ou algumas funções-membro e variáveis de uma classe pai. Os objetos também podem ser herdados.
Parent Class- Uma classe que é herdada por outra classe. Isso também é chamado de classe base ou superclasse.
Child Class- Uma classe que herda de outra classe. Isso também é chamado de subclasse ou classe derivada.
Polymorphism- Este é um conceito orientado a objetos onde a mesma função pode ser usada para diferentes propósitos. Por exemplo, o nome da função permanecerá o mesmo, mas pode ter um número diferente de argumentos e realizar tarefas diferentes. As classes Pascal implementam polimorfismo. Objetos não implementam polimorfismo.
Overloading- É um tipo de polimorfismo em que alguns ou todos os operadores têm implementações diferentes dependendo dos tipos de seus argumentos. Funções semelhantes também podem ser sobrecarregadas com implementações diferentes. As classes Pascal implementam sobrecarga, mas os Objetos não.
Data Abstraction - Qualquer representação de dados em que os detalhes de implementação estão ocultos (abstraídos).
Encapsulation - Refere-se a um conceito em que encapsulamos todos os dados e funções-membro juntos para formar um objeto.
Constructor - Refere-se a um tipo especial de função que será chamada automaticamente sempre que houver uma formação de objeto a partir de uma classe ou de um objeto.
Destructor - Refere-se a um tipo especial de função que será chamada automaticamente sempre que um objeto ou classe for excluído ou sair do escopo.
Definindo Objetos Pascal
Um objeto é declarado usando a declaração de tipo. A forma geral de uma declaração de objeto é a seguinte -
type object-identifier = object
private
field1 : field-type;
field2 : field-type;
...
public
procedure proc1;
function f1(): function-type;
end;
var objectvar : object-identifier;
Vamos definir um Objeto Retângulo que tem dois membros de dados do tipo inteiro - length e width e algumas funções de membro para manipular esses membros de dados e um procedimento para desenhar o retângulo.
type
Rectangle = object
private
length, width: integer;
public
constructor init;
destructor done;
procedure setlength(l: inteter);
function getlength(): integer;
procedure setwidth(w: integer);
function getwidth(): integer;
procedure draw;
end;
var
r1: Rectangle;
pr1: ^Rectangle;
Depois de criar seus objetos, você será capaz de chamar funções de membro relacionadas a esse objeto. Uma função de membro será capaz de processar a variável de membro do objeto relacionado apenas.
O exemplo a seguir mostra como definir comprimentos e larguras para dois objetos retangulares e desenhá-los chamando as funções de membro.
r1.setlength(3);
r1.setwidth(7);
writeln(' Draw a rectangle: ', r1.getlength(), ' by ' , r1.getwidth());
r1.draw;
new(pr1);
pr1^.setlength(5);
pr1^.setwidth(4);
writeln(' Draw a rectangle: ', pr1^.getlength(), ' by ' ,pr1^.getwidth());
pr1^.draw;
dispose(pr1);
A seguir está um exemplo completo para mostrar como usar objetos em Pascal -
program exObjects;
type
Rectangle = object
private
length, width: integer;
public
procedure setlength(l: integer);
function getlength(): integer;
procedure setwidth(w: integer);
function getwidth(): integer;
procedure draw;
end;
var
r1: Rectangle;
pr1: ^Rectangle;
procedure Rectangle.setlength(l: integer);
begin
length := l;
end;
procedure Rectangle.setwidth(w: integer);
begin
width :=w;
end;
function Rectangle.getlength(): integer;
begin
getlength := length;
end;
function Rectangle.getwidth(): integer;
begin
getwidth := width;
end;
procedure Rectangle.draw;
var
i, j: integer;
begin
for i:= 1 to length do
begin
for j:= 1 to width do
write(' * ');
writeln;
end;
end;
begin
r1.setlength(3);
r1.setwidth(7);
writeln('Draw a rectangle:', r1.getlength(), ' by ' , r1.getwidth());
r1.draw;
new(pr1);
pr1^.setlength(5);
pr1^.setwidth(4);
writeln('Draw a rectangle:', pr1^.getlength(), ' by ' ,pr1^.getwidth());
pr1^.draw;
dispose(pr1);
end.
Quando o código acima é compilado e executado, ele produz o seguinte resultado -
Draw a rectangle: 3 by 7
* * * * * * *
* * * * * * *
* * * * * * *
Draw a rectangle: 5 by 4
* * * *
* * * *
* * * *
* * * *
* * * *
Visibilidade dos membros do objeto
Visibilidade indica a acessibilidade dos membros do objeto. Os membros do objeto Pascal têm três tipos de visibilidade -
Sr. Não | Visibilidade e acessibilidade |
---|---|
1 | Public Os membros podem ser usados por outras unidades fora da unidade do programa |
2 | Private Os membros estão acessíveis apenas na unidade atual. |
3 | Protected Os membros estão disponíveis apenas para objetos descendentes do objeto pai. |
Por padrão, os campos e métodos de um objeto são públicos e são exportados fora da unidade atual.
Construtores e destruidores para objetos Pascal -
Constructorssão tipos especiais de métodos, que são chamados automaticamente sempre que um objeto é criado. Você cria um construtor em Pascal apenas declarando um método com um construtor de palavra-chave. Convencionalmente, o nome do método é Init, no entanto, você pode fornecer qualquer identificador válido por conta própria. Você pode passar quantos argumentos quiser para a função do construtor.
Destructorssão métodos chamados durante a destruição do objeto. Os métodos destruidores destroem qualquer alocação de memória criada pelos construtores.
O exemplo a seguir fornecerá um construtor e um destruidor para a classe Rectangle que inicializará o comprimento e a largura do retângulo no momento da criação do objeto e o destruirá quando sair do escopo.
program exObjects;
type
Rectangle = object
private
length, width: integer;
public
constructor init(l, w: integer);
destructor done;
procedure setlength(l: integer);
function getlength(): integer;
procedure setwidth(w: integer);
function getwidth(): integer;
procedure draw;
end;
var
r1: Rectangle;
pr1: ^Rectangle;
constructor Rectangle.init(l, w: integer);
begin
length := l;
width := w;
end;
destructor Rectangle.done;
begin
writeln(' Desctructor Called');
end;
procedure Rectangle.setlength(l: integer);
begin
length := l;
end;
procedure Rectangle.setwidth(w: integer);
begin
width :=w;
end;
function Rectangle.getlength(): integer;
begin
getlength := length;
end;
function Rectangle.getwidth(): integer;
begin
getwidth := width;
end;
procedure Rectangle.draw;
var
i, j: integer;
begin
for i:= 1 to length do
begin
for j:= 1 to width do
write(' * ');
writeln;
end;
end;
begin
r1.init(3, 7);
writeln('Draw a rectangle:', r1.getlength(), ' by ' , r1.getwidth());
r1.draw;
new(pr1, init(5, 4));
writeln('Draw a rectangle:', pr1^.getlength(), ' by ',pr1^.getwidth());
pr1^.draw;
pr1^.init(7, 9);
writeln('Draw a rectangle:', pr1^.getlength(), ' by ' ,pr1^.getwidth());
pr1^.draw;
dispose(pr1);
r1.done;
end.
Quando o código acima é compilado e executado, ele produz o seguinte resultado -
Draw a rectangle: 3 by 7
* * * * * * *
* * * * * * *
* * * * * * *
Draw a rectangle: 5 by 4
* * * *
* * * *
* * * *
* * * *
* * * *
Draw a rectangle: 7 by 9
* * * * * * * * *
* * * * * * * * *
* * * * * * * * *
* * * * * * * * *
* * * * * * * * *
* * * * * * * * *
* * * * * * * * *
Destructor Called
Herança para objetos Pascal
Objetos Pascal podem opcionalmente herdar de um objeto pai. O programa a seguir ilustra a herança em objetos Pascal. Vamos criar outro objeto chamadoTableTop, que é herdado do objeto Rectangle.
program exObjects;
type
Rectangle = object
private
length, width: integer;
public
procedure setlength(l: integer);
function getlength(): integer;
procedure setwidth(w: integer);
function getwidth(): integer;
procedure draw;
end;
TableTop = object (Rectangle)
private
material: string;
public
function getmaterial(): string;
procedure setmaterial( m: string);
procedure displaydetails;
procedure draw;
end;
var
tt1: TableTop;
procedure Rectangle.setlength(l: integer);
begin
length := l;
end;
procedure Rectangle.setwidth(w: integer);
begin
width :=w;
end;
function Rectangle.getlength(): integer;
begin
getlength := length;
end;
function Rectangle.getwidth():integer;
begin
getwidth := width;
end;
procedure Rectangle.draw;
var
i, j: integer;
begin
for i:= 1 to length do
begin
for j:= 1 to width do
write(' * ');
writeln;
end;
end;
function TableTop.getmaterial(): string;
begin
getmaterial := material;
end;
procedure TableTop.setmaterial( m: string);
begin
material := m;
end;
procedure TableTop.displaydetails;
begin
writeln('Table Top: ', self.getlength(), ' by ' , self.getwidth());
writeln('Material: ', self.getmaterial());
end;
procedure TableTop.draw();
var
i, j: integer;
begin
for i:= 1 to length do
begin
for j:= 1 to width do
write(' * ');
writeln;
end;
writeln('Material: ', material);
end;
begin
tt1.setlength(3);
tt1.setwidth(7);
tt1.setmaterial('Wood');
tt1.displaydetails();
writeln;
writeln('Calling the Draw method');
tt1.draw();
end.
A seguir estão os pontos importantes que devem ser anotados -
O objeto Tabletop herdou todos os membros do objeto Rectangle.
Também existe um método de desenho no TableTop . Quando o empate método é chamado usando um TableTop objeto, sorteio de TableTop é invocado.
Existe uma instância implícita chamada self que se refere à instância atual do objeto.
Quando o código acima é compilado e executado, ele produz o seguinte resultado -
Table Top: 3 by 7
Material: Wood
Calling the Draw Method
* * * * * * *
* * * * * * *
* * * * * * *
Material: Wood