Is The Sky Really The Limit? (Site pessoal de Miguel Prego Gaspar)
 
 
Syndication

Categorias
Do site ...

Locations of visitors to this page





Artigos

Artigos actuais

Introdução ao desenvolvimento orientado a objectos
quinta-feira, 19 de Junho de 2008 :: 211 Visualizações :: 0 Comentários :: :: Básicos

Introdução

Neste artigo serão apresentados os conceitos básicos de OOP (Desenvolvimento Orientado a Objectos). No final será apresentado um exemplo prático de um simulador de extracção de bolas do "Euromilhões" com todo o código fonte em Visual Basic .Net.

As classes são templates para objectos

As classes definem os membros de um objecto, definem o seu comportamento e atribuem os seus valores iniciais quando apropriado. Quando uma classe é iniciada é criada em memória uma instância. Esta instância é chamada "Objecto".

Objectos e Membros

Os objectos são compostos por membros, que representam a sua estrutura e funcionalidade. Membros são:   

  • Campos e Propriedades: São membros de informação sobre o objecto.
  • Métodos: São acções que o objecto pode realizar.
  • Eventos: São notificações que o objecto recebe ou envia para outros objectos quando acontece uma actividade.

Num cenário baseado na vida real, podemos considerar um objecto carro. Este objecto tem propriedades tais como: Cor, Marca, Modelo, Idade, etc. Esta informação descreve o estado do objecto.

O objecto carro tem também métodos, como: Acelerar, trocar mudança ou virar. Os métodos representam comportamentos que o objecto pode executar.

Eventos representam notificações. Por exemplo, no caso do objecto carro pode ser por exemplo o sobre aquecimento do motor ou evento "Batida" ao interagir com um objecto árvore.   

Modelo de objectos

Os objectos mais simples podem consistir somente em algumas propriedades, alguns métodos e até talvez um ou dois eventos, mas objectos complexos podem requerer imensos membros e objectos subordinados. Os objectos podem expor outros objectos como membros .

O modelo de Objectos define a hierarquia dos objectos filhos que compõem a estrutura de um objecto.

Voltando ao exemplo do objecto carro, um carro é um único objecto, mas contém outros objectos subordinados, como por exemplo um objecto motor, quatro objectos rodas, etc.

A composição destes objectos subordinados afecta directamente o funcionamento do carro como um todo.

Encapsulamento

Encapsulamento é o conceito de que a implementação de um objecto é independente do seu interface. Ou seja, uma aplicação interage com um objecto através do seu interface, que consiste nas suas propriedades públicas e métodos. Enquanto este interface permanecer constante a aplicação pode interagir com o componente, mesmo que a sua implementação interna seja totalmente reformulada.

Os objectos apenas devem interagir uns com os outros através dos seus métodos e propriedades públicas. Isto significa que os objectos devem conter em si toda a informação e todos os mecanismos para a manipular. A informação e mecanismos internos do objecto nunca devem ser expostos através do interface.

Se um objecto carro interagir com um objecto condutor, o interface deverá consistir em membros como: método avançar, método recuar, método parar, etc. Esta é toda a informação que o objecto condutor necessita para interagir com o objecto carro.

O objecto carro contem um objecto motor, mas o objecto condutor não tem que saber sequer da sua existência.

Se o objecto motor for trocado, o objecto condutor continuará a interagir com o objecto carro exactamente da mesma forma.

Polimorfismo 

Polimorfismo é a capacidade de diferentes classes disponibilizarem implementações diferentes dos mesmos interfaces públicos. Ou seja, o polimorfismo permite que métodos e propriedades de um objecto possam ser chamados, sem conhecimento particular da sua implementação.

O polimorfismo pode ser providenciado de duas formas:   

  • Polimorfismo de interface
  • Polimorfismo de herança

Um objecto condutor pode interagir com um objecto carro através do seu interface público.

Se outro objecto, como camião ou tractor disponibilizar o mesmo interface, o objecto condutor pode interagir com eles sem se preocupar com a implementação especifica.

Polimorfismo de interface 

Um interface é um contrato de comportamento. Essencialmente define quais os membros que a classe vai implementar, mas não diz nada acerca dos detalhes da implementação. Um objecto pode implementar vários interfaces diferentes , e várias classes diferentes podem implementar o mesmo interface.

Todos os objectos que implementam um mesmo interface são capazes de interagir com outros objectos através desse interface.

Utilizando o exemplo anterior, o objecto carro pode implementar o interface "IDrivable" que especifica os métodos avançar e recuar. Outras classes, como camião podem implementar também este interface e assim ser capazes de interagir com o objecto condutor.

Polimorfismo de herança 

A herança permite incorporar a funcionalidade previamente definida numa classe numa nova classe, e implementar novos membros se necessário.

Uma classe que herda de outra classe é designada como classe derivada. Uma classe apenas pode herdar directamente de uma classe (classe base).

A nova classe tem os mesmos membros que a classe base, embora possa adicionar ou alterar o funcionamento dos existentes.

Se a classe carro for uma classe base, uma classe derivada pode ser o CarroDesportivo

Métodos

Os métodos podem ser implementados como: 

  • Procedimentos ("Sub")
  • Funções ("Function")  

Function CompleteName(ByRef FirstName as string, ByVal LastName as string, Optional ByVal title As String = "") As String 
    CompleteName = "" 
    ' Use the title if provided. 
    If title <> "" Then CompleteName = title & " " 
    ' Append first and last name. 
    CompleteName &= FirstName & " " & LastName 
End Function 

Overloading

"Overloading" é a possibilidade de criar vários métodos com o mesmo nome mas com assinaturas diferentes.

A assinatura do método é composta pelos tipos dos seus parâmetros, e pela forma como são passados (ByRef ou ByVal).

O Retorno do método não é relevante para a assinatura (não pode ser utilizado para "Overloading")

Function Item (ByVal index as Integer) as String 
    'Acede a elementos através do index 
End Function 

Function Item (ByVal Key as string) as String 
    'Acede aos elementos através de uma chave "String" 
End Function

 

'Chamada através do primeiro método 
Result=MyObj.Item(1) 

'Chamada através do segundo método
Result=MyObj.Item("teste")

Regras para "Overloading"

  • A palavra reservada "Overloads" pode ser utilizada de forma opcional. Mas se for utilizada num método tem de ser utilizada em todos os métodos da classe.
  • A utilização de "overloading" é facilitada com as capacidades de "intellisence" do Visual Studio.
  • O "Overloading" pode ser uma alternativa melhor para casos em que se utilizem parâmetros opcionais.
  • Quando os tipos dos argumentos não correspondem exactamente à assinatura de nenhum método disponível, o compilador tenta encontrar um método através de "Widening coercion"
  • Casos ambíguos:

A plataforma tem de conseguir resolver um método no momento da compilação, por isso os métodos tem de ter mais alguma diferença para além de parâmetros opcionais.

Como não é possível distinguir dois métodos apenas pelo tipo de retorno, não é permitido o "overloading" de métodos sem parâmetros.

Propriedades

As propriedades podem ser consideradas "Super Fields", pois são manipuladas como os "fields", mas tem código associado.

Public Property BirthDate() as date 
    'Código que implementa a propriedade 
End Property

Tal como os campos e os métodos, as propriedades podem possuir um identificador de "Scope". Por defeito as propriedades são publicas.

Estrutura das propriedades:

Get … End Get -> Define o valor devolvido pela propriedade

Set … End Set -> Define como são assignados valores à propriedade

Dim m_BirthDate As Date 
'...
Public Property BirthDate() As Date
    Get 
        Return m_BirthDate 
    End Get
    Set(ByVal value As Date) 
        m_BirthDate = value 
    End Set
End Property

A partir do Visual Basic 2005 é possível atribuir definições de "Scope" diferentes aos blocos "Set" e "Get", Esta capacidade é importante, por exemplo, quando se pretende que uma propriedade seja só de leitura se chamada fora do "Assembly" e de escrita se chamada de outras classes dentro do mesmo "Assembly":

Private m_ID As Integer 
Public Property ID() As Integer 
    Get 
        Return m_ID 
    End Get
    Friend Set(ByVal value As Integer) 
        If value <= 0 Then Throw New ArgumentException("Valores negativos são inválidos") 
        m_ID = value 
    End Set
End Property

Propriedades com argumentos

Dim m_Addresses(3) As String ' Até 4 linhas 
Public Property Addresses(ByVal index As Integer) As String
    Get 
        If index < 0 Or index > UBound(m_Addresses) Then 
            Throw New IndexOutOfRangeException("Indice inválido.") 
        End If 
        Return m_Addresses(index) 
    End Get 
    Set(ByVal value As String) 
        If index < 0 Or index > UBound(m_Addresses) Then 
            Throw New IndexOutOfRangeException("Indice inválido.") 
        End If 
        m_Addresses(index) = value 
    End Set 
End Property

Propriedades "Default"

Um tipo pode expor uma propriedade por defeito, para que possa ser chamada sem que seja necessário utilizar o seu nome, desde que seja uma propriedade com argumentos:

Default Public Property Addresses(ByVal index As Integer) As String 
'(…) 
End Property

'Utilizar a propriedade:
Dim MyPerson as new person
MyPerson.name="Ana"
MyPerson(0)="Avenida da casa amarela" 
MyPerson(1)="Nº149 – Lisboa"

Construtores

Um construtor é um método especial que é executado sempre que é criada uma instância de uma classe. Em VB o construtor é sempre chamado "Sub New":

Class Person 
    Private CreateTime as date 
    Public Sub New() 
        ' Display a diagnostic message. 
        Console.WriteLine("A new instance of Person is being created.") 
        ' Remember when this instance was created. 
        CreateTime = Now 
    End Sub 
End Class

Quando a execução chega ao construtor, todos os campos com um iniciador já foram iniciados:

Class Person 
    Public Pais as string="Portugal" 
    Public Sub New()
        Console.writeline(Pais) '->Portugal 
    End Sub 
End Class

Um construtor pode aceitar argumentos, normalmente para obrigar à definição de valores indispensáveis para a criação e funcionamento correcto do objecto:

Class Person 
    Public FirstName as String
    Public LastName as String 
    Public Sub New(ByVal FirstName as String, ByVal LastName as String)
        Me.FirstName=FirstName
        Me.LastName=LastName 
    End Sub 
End Class

'Instanciação
Dim MyPerson as new Person ("João","Teixeira") 

Construtores "OverLoad"

Tal como todos os restantes métodos, o "sub New" pode ser "Overloaded", o que significa que podem ser dadas várias opções para a criação de um objecto.

Public Sub New(ByVal name As String) 
    ' chama o outro construtor, passando o default do segundo argumento . 
    Me.New(name, 0) 
End Sub 

Public Sub New(ByVal name As String, ByVal id As Integer) 
    Me.Name = name 
    Me.Id = id 
End Sub

Membros estáticos ("Shared"):

São membros (Campos, Propriedades ou métodos) que pertencem à classe e não à instância.

Através da palavra reservada "Shared" um método fica marcado como estático, podendo ser chamado sem ser necessário criar uma instância do objecto:

Public Class Triangle 
    Dim a, b, c As Double 
    Public Shared Function GetPerimeter(ByVal a As Double, ByVal b As Double, ByVal c As Double) As Double
        Return a + b + c 
    End Function 
    Public Shared Function GetArea(ByVal a As Double, ByVal b As Double, ByVal c As Double) As Double 
        Dim halfP As Double = (a + b + c) / 2 
        Return Math.Sqrt(halfP * (halfP - a) * (halfP - b) * (halfP - c)) 
    End Function 
End class

Regras para a implementação de membros estáticos

  • O Código incluído dentro de um método estático ("Shared") apenas pode aceder a outros membros estáticos. Não pode aceder a campos, propriedades ou métodos de instância.
     
  • Normalmente são criados dois tipos de classes que só contém membros estáticos:  
    1. Uma classe que funciona como um contentor biblioteca de membros estáticos, como por exemplo o "System.Math".
       
    2. Um tipo que apenas assume a forma de um objecto único (uma única instância) , como por exemplo o "System.Console" (São chamadas Singletons") .

Se uma classe apenas contém membros estáticos, não é necessário proceder à sua instanciação.

Para garantir que uma classe não é instanciada de todo, deve ser criado um construtor privado, para evitar que o VB construa um automaticamente:

Public Class Mylibrary 
    Private Sub New 
        'Nada 
    End Sub 
End class 

Uma propriedade identificada como "Shared"

Public Shared ReadOnly Property NextInvoiceID() As Long 
    Get 
        Return InstanceCount + 1 
    End Get 
End Property

Construtores estáticos ("Shared")

  • Um construtor "Shared" e sem parâmetros é chamado automaticamente antes da primeira instância da classe ser criada ("Static Constructor" ou "Type constructor").
  • Um construtor estático é tipicamente utilizado para iniciar de forma correcta campos estáticos, quando é necessária uma lógica mais elaborada que um simples iniciador.
  • Um construtor estático pode ser utilizado para aceder a recursos partilhados por todas as instâncias de um objecto, como por exemplo, um ficheiro.
  • O construtor estático é executado antes do construtor de instância para a primeira instância.
  • Um construtor estático é implicitamente Privado.
  • O construtor estático é o único local onde é possível assignar um valor a um campo "Shared" e "ReadOnly".

Public Shared ReadOnly InitialDir as String 
Shared Sub New 
    InitialDir=Directory.GetCurrentDirectory() 
End Sub

Caso prático

Esta pequena aplicação pretende aplicar na prática os conhecimentos adquiridos em desenvolvimento orientado a objectos.

O objectivo será criar um modelo realista do funcionamento de um mecanismo de extracção de bolas para o jogo "EuroMilhões".

A aplicação, ao ser executada, deverá apresentar uma chave (5 números entre 50 mais 2 números entre 9), bem como a seguinte informação:   

  • Listagem de todas as bolas que saíram na tômbola grande (incluindo valor e cor)
  • Listagem de todas as bolas que saíram na tômbola pequena (incluindo valor e cor)
  • Listagem de todas as bolas que ficaram na tômbola grande (incluindo valor e cor)
  • Listagem de todas as bolas que ficaram na tômbola pequena (incluindo valor e cor)   

Regras para desenvolvimento   

  • Criar um novo projecto com o template "Console Application"
  • Criar uma estrutura "Bola" com as seguintes características:
    • Propriedade "valor" do tipo "Integer" (deverá ser preenchida com um valor recebido no construtor)
    • Propriedade "Cor" do tipo "String" (Deverá ser preenchida no construtor, através da formula: valor entre 1 e 10 = Amarela, entre 11 e 20 = Vermelha, entre 21 e 30 = Azul, entre 31 e 40 = Verde, entre 41 e 50 = Laranja.
  • Criar uma classe "Tômbola" com as seguintes características:
    • Propriedade do tipo "Integer" chamada "Capacidade" (Capacidade máxima da tômbola)
    • Propriedade só de leitura do tipo "integer" chamada "Capacidade ocupada" (Com a capacidade actualmente ocupada da tômbola. Deve ser actualizada sempre que o conteúdo da tômbola seja alterado).
    • Propriedade só de leitura do tipo "Bola" com argumentos por índice, chamada "ConteúdoTombola" (Através de um índice, retorna a bola correspondente existente na tômbola).
    • Método "enche", sem retornos. Recebe um "array" de bolas e coloca no conteúdo na tômbola.
    • Método "BaralhaBolas", sem retornos. Baralha o conteúdo da tômbola (Implementar com um método privado chamado "BaralhaBolasArray".
    • Método "ExtraiBola", que retira uma bola da tômbola e devolve esse objecto. (Implementar com um método privado chamado "RemoveBolaArray".
  • No modulo da "console Application" realizar os seguintes passos:
    • Criar 50 instâncias de objectos "Bola" (Definir o valor no momento de construção. Os valores deverão ser de 1 a 50)
    • Criar um objecto do tipo "Tômbola" chamado "TombolaGrande" e definir a sua capacidade.
    • Colocar as bolas dentro da tômbola (método "Enche")
    • Baralhar a tômbola (Método "BaralhaBolas")
    • Retirar 5 bolas da tômbola (Método "ExtraiBola". A tômbola deverá ser baralhada entre cada saída de uma bola).
    • Repetir os passos, com 9 bolas e um objecto "Tômbola" chamado "TombolaPequena"
    • Apresentar no ecrã a informação pedida.

    Solução



     
     
powered by metaPost

Rating

Comentários
Ainda não existem comentários. Seja o primeiro a colocar um!
Clique aqui para colocar um comentário.
 
 
   
ankaa.net@2008