Desenvolvimento - Sistemas

Introdução a Orientação a Objetos

No mundo orientado a objetos, tudo é focado em classes e em objetos. Precisamos então defini-los para podermos entender as diferenças entre os dois e começarmos a entrar realmente no mundo da POO (Programação Orientada a Objetos).

por Marden Menezes



Classes e Objetos

No mundo orientado a objetos, tudo é focado em classes e em objetos. Precisamos então defini-los para podermos entender as diferenças entre os dois e começarmos a entrar realmente no mundo da POO (Programação Orientada a Objetos).

Quando construindo algo, temos duas fases distintas mas que são imprescindíveis ao sucesso do nosso projeto: a formalização do que estamos criando e a transformação da formalização (projeto) em algo físico. Essas duas fases estão representadas no mundo orientado a objetos pela classe (formalização, projeto de algo) e pelo objeto (transformação do projeto em algo físico, ou seja, uma variável na memória).

Vamos imaginar o caso em que temos de construir um computador. Antes de construir o computador, temos que definir suas propriedades, formas, ações que executará. Teríamos então que montar um projeto do computador, o que na orientação a objetos significa criar uma classe. Se pensarmos que um computador possui monitor, mouse, teclado e gabinete, devemos então acrescentar essas características do computador ao nosso projeto. Cada característica de uma classe é chamada de atributo. Devemos então ter uma classe chamada Computador que possui quatro atributos.

Além de declarar as características das classes, devemos também definir as ações que o nosso futuro objeto poderá executar. Essas ações são definidas por meios de métodos, que serão estudados mais adiante.

Vamos então definir uma classe em C# utilizando a palavra chave "class" no início do código e guardando seus atributos com seus respectivos tipos. Os atributos nada mais são que variáveis globais a classe.

Veja no código abaixo a definição da classe Computador:

class Computador
{
		Monitor monitor;
		Teclado teclado;
		Mouse mouse;

		/*abaixo podemos criar vários métodos que definem
		as ações de um computador
		*/
}

Criando Objetos

Agora que já sabemos como definir uma classe, podemos passar ao ponto de criar objetos da classe definida. É importante perceber o fato de que podemos criar vários objetos da mesma classe, não ficando limitado a apenas um objeto.

Quando vamos criar um objeto em C# utilizamos a palavra chave "new" seguindo o seguinte esquema:

<Tipo> <nome> = new <Tipo>()

Veja então um exemplo de criação de um objeto Computador com o nome de comp1:

Computador comp1 = new Computador();

Perceba que na criação do objeto, após o new, chamamos o tipo Computador seguido de parênteses. Essa notação significa que neste momento será executado um método especial da classe Computador chamado construtor.

O construtor é um método que possui o mesmo nome da classe, que não retorna nenhum valor e que é chamado cada vez que um objeto da classe é criado. Por padrão, quando não criamos nenhum construtor (como na classe Computador acima), o construtor vazio, que não recebe nenhum parâmetro e também não executa nenhum código, é criado automaticamente. Após criarmos um construtor o construtor vazio automático não é mais criado, devendo ser criado pelo desenvolvedor caso precise.

Veja a classe Computador modificada com um construtor que recebe 3 strings e preenche os atributos da classe com essas strings:

namespace Construtor
{
	class Computador
	{
		string monitor;
		string teclado;
		string mouse;
		
		public Computador(string m, string t, string r) 
		{
			monitor = m;
			teclado = t;
			mouse = r;
		}

	}

	public class App 
	{
		public static void Main()
		{
			Computador comp1 = new Computador("Monitor","Teclado","Mouse");
			Computador comp2 = new Computador("Monitor2","Teclado2","Mouse2");
			//essa linha daria erro de compilação: new Computador();
		}
	}
}

Nesse código, criar um objeto com o construtor vazio daria um erro de compilação já que, ao criar o construtor que recebe 3 string, "apagamos" o construtor vazio.

Tipos por valor x Tipos por referência.

Os tipos pré-definidos em C# são normalmente conhecidos como tipos por valor. Esses tipos devem permitir um acesso rápido já que são muitas vezes utilizados no código. Dessa forma, os tipos por valor têm guardados na memória apenas o seu valor, sem nenhuma outra informação adicional que poderia causar um gasto desnecessário de memória.

Os tipos criados por classes, os objetos, são conhecidos como tipos "por referência". Essa denominação vem do fato de que esses tipos não guardam o seu valor, mas sim uma referência para um local na memória que contém o valor.

Com essas definições, é importante perceber que, se copiarmos as informações de variáveis de tipos por valor e de variáveis de tipos por referência, teremos comportamentos diferentes. Caso copiemos uma variável por valor, o que ocorre é que uma nova cópia do valor é passada para a outra variável. Isso significa que caso modifiquemos uma das variáveis, nada ocorrerá com a outra.

Em variáveis por referência o que ocorre ao copiarmos para outra variável é que apenas a referência é copiada, não o valor. Após a cópia o que acontece é que teremos duas variáveis apontando para um mesmo valor. Isso significa que, ao modificarmos uma variável, estaremos na realidade modificando o valor para o qual a outra variável também está apontando, significando que o valor da outra variável também será modificado.

Veja o código abaixo e observe o resultado:

class Computador
	{
		public string monitor;
		public string teclado;
		public string mouse;
		
		public Computador(string m, string t, string r) 
		{
			monitor = m;
			teclado = t;
			mouse = r;
		}

		public override string ToString() 
		{
			return this.monitor + " " + this.teclado + " " + this.mouse;
		}

	}

	public class App 
	{
		public static void Main()
		{
			//cria uma variável de tipo por valor
			int valor1 = 10;
			//copia para outra variável
			int valor2 = valor1;
			//adiciona 5 a valor2
			valor2 += 5;
			//imprime o valor das duas:
			Console.WriteLine("valor1: " + valor1);
			Console.WriteLine("valor2: " + valor2);

			//cria um objeto de tipo por referência
			Computador comp1 = new Computador("Monitor1","Teclado1","Mouse1");
			//copia a referência 
			Computador comp2 = comp1;
			//modifica o valor do monitor:
			comp2.monitor = "Modificado!";
			//imprime as duas datas:
			Console.WriteLine("comp1: " + comp1);
			Console.WriteLine("comp2: " + comp2);

		}
	}

Veja o resultado:

Mesmo tendo modificado apenas um dos objetos (o comp2), o comp1 também foi modificado, provando que na verdade os dois objetos referenciam o mesmo endereço na memória.

Perceba que tivemos que modificar a classe Calculadora adicionando a ela o método ToString() para que o Console.WriteLine() pudesse recuperar o valor da comp1 e comp2 autimaticamente para uma string.

Falarei mais de OOP no próximo artigo! Espero ter ajudado aos iniciantes nesse paradigma de programação!

Um grande abraço!

Marden Menezes

Marden Menezes - Líder do maior grupo de usuários do Brasil, o Sharp Shooters (www.sharpshooters.org.br). Marden é Microsoft Certified Professional e Microsoft Student Ambassador, ministrando palestras e cursos em todo o Brasil e difundindo a plataforma .NET nas universidades.
Como representante do comitê de relacionamento com grupos de usuários da INETA (www.ineta.org), Marden vem trabalhando para a difusão dos grupos de usuários .NET no país.