Desenvolvedores.Net - TechBlog

Tag Archives: Herdar

Tipos de Relacionamento (UML)

3
1 Estrela2 Estrelas3 Estrelas4 Estrelas5 Estrelas (5 votos, média: 5,00 de 5)
Loading ... Loading ...
14 de abril de 2011

Para um melhor entendimento deste Artigo veja o Índice (UML)

Neste artigo irei abordar os tipos de relacionamento que a UML tem.

Os relacionamentos  ou associações definem as dependências e ligações entre as classes, objetos, pacotes, tabelas, entre outros que iremos ver no decorrer do artigo.

Vamos à eles:

Associação

É uma conexão entre as classes , tabelas e objetos. Um relacionamento.

Em UML uma associação representa um relacionamento que descreve as ligações entre os objetos ligados.

Uma associação deve ter sempre duas pontas, onde uma é o objeto de início e a outra o objeto final.

Uma associação pode representar a multiplicidade entre os objetos. Podemos ter as seguintes representações de multiplicidade:
0 (zero)
1 (um)
0…1 (zero ou um)
0…* (zero ou mais)
1…* (um para muitos)
* (muitos)

 

Por exemplo, podemos pegar uma Nota Fiscal e seus Itens.

Uma nota fiscal, vários itens.

 

As associações podem ser:

  • Normais:
    • É o tipo mais comum, é representada por uma linha sólida entre as classes. Possui um nome em cada ponta que identifica o que cada uma representa, normalmente é um verbo. Mas fica a critério de cada um para facilitar o entendimento.
  • Recursiva:
    • Indica que uma classe pode conectar-se a ela mesma. Por exemplo. Pegamos o objeto Pessoa. Ele é um objeto que pode ser um Pai, um Filho, um Fornecedor, um Cliente, um Usuário. Mas todos estes são “Pessoas”.
  • Um outro exemplo pode ser um plano de contas, onde podemos ter:

    Fornecedor
        |----> Água;
        |----> Luz;
    Receitas
        |----> Vendas
        |----> Serviços
    Despesas
        |----> Financeiras
        |----> Funcionários

    Neste caso podemos estar colocando todos dentro do mesmo objeto e definir o “pai” como o nível superior de cada conta.

  • Exclusiva:
    • Em alguns momentos precisamos representar que um objeto pode participar apenas de um tipo em determinado momento.
    • Uma associação exclusiva é representada por um linha tracejada entre as associações, entre elas existe a especificação {ou}.
    • Abaixo um exemplo. A pessoa não pode ser Jurídica e Física ao mesmo tempo.
  • Qualificada:
    • As associações qualificadas representam as ligações de 1…* (um para muitos) ou * (muitos).
      O “qualificador” identifica no final da associação qual o objeto está identificado.

Agregação

A agregação é um tipo de associação onde o todo está relacionado com suas partes. É representada com o símbolo de um diamante junto a classe agregadora.

Composição

A composição é muito semelhante a agregação, o objeto “Parte” pode pertencer somente ao objeto “Todo” e normalmente o objeto “Todo” vive e morre com suas “Partes”.

É representada pelo símbolo de um diamante preto na classe agregadora.

Generalização

Generalização é a capacidade de identificar as similaridades entre várias classes, com isso criamos um supertipo que encapsula todas as funcionalidades comuns as demais classes filhas.

Podemos usar a generalização para agrupar os nossos objetos em um tipo comum.

Especialização

A especialização cria uma classe herdada da generalização onde refina o processo definido na classe pai. Como o próprio nome diz, especializa a classe pai para um tipo específico.

Usando a mesma imagem acima da generalização, podemos identificar quem é a generalização “subindo” e quem é a especialização “descendo”.

Realização

A realização é um relacionamento entre os itens que implementa o comportamento especificado por outro.
Um exemplo disso seria as classes abstratas e as interfaces que definem que o objeto “filho” deverá realizar alguma método, propriedade no momento da herança.

Dependência

Este é simples :) é um item (objeto) que depende de outro.

Com isto finalizamos este tópico, mas ainda temos muita coisa para ver.
Eu recomendo a leitura de alguns artigos sobre Programação Orientada à Objetos para fixar a idéia e ver a aplicação do que foi aprendido.

  1. Herança
  2. Definições – Avançado
  3. Abstração e Interface

Ver Índice

É isso ai pessoal :)
Até o próximo
♦ Marcelo

About Marcelo

Nascido em Juruaia/MG em uma fazenda de criação de búfalos. Está perdido em São Paulo trabalhando com desenvolvimento de aplicações desde os 17 anos. Atualmente é arquiteto de software, é um cara meia boca que fica entre a equipe de desenvolvimento e o gerente de projetos, no meio da ponte. Para saber mais ... http://desenvolvedores.net/marcelo []'s

Herança (POO)

4
1 Estrela2 Estrelas3 Estrelas4 Estrelas5 Estrelas (2 votos, média: 5,00 de 5)
Loading ... Loading ...
29 de janeiro de 2011
Para um melhor entendimento deste Artigo veja o Índice (Programação Orientada a Objetos)

Herança

Iremos entrar agora em um tópico que teremos muito o que discutir. Tentarei ser o mais simples , claro e objetivo.
Mas antes de falarmos sobre herança, iremos falar sobre a hierarquia das classes.

Hierarquia

Quando vamos trabalhar com muitas classes, temos que ter em mente a hierarquia (ordem) que estas classes deverão seguir.

Por exemplo:

Não poderemos ter os filhos antes dos pais e antes dos avós. A hierarquia correta para este tipo de classe seria:

Avô -> Pai -> Filho



(quando ví esta imagem, não resisti. Serve perfeitamente para o exemplo de hierarquia)

Assim temos a hierarquia bem definida dentro de nossas classes.

Transformando isso em programação teríamos generalização e especialização.

Como foi visto, a classe mais ao topo da hierarquia é a generalização, enquanto a última classe é a mais especializada.
No diagrama de seqüencia abaixo, podemos ver que as classes mais a esquerda são as genéricas e as mais a direita são as especializadas.

Agora vamos tratar dos tipos de herança que podemos ter.

Herança de Implementação

A herança de implementação é aquela onde herdamos todo o código da classe Pai, não precisamos reescrever código para utilizá-lo, estamos falando de reutilização de código.

Caso desejamos subsitituir um método da classe pai devemos usar overriding, como foi discutido em Definição (Intermediário).

Creio que a herança de implementação é a mais usada, pois herda a assinatura e os métodos da classe pai.

Herança de Interface

Caso não conheçam Interface e Abstração leiam este tópico.

A herança de interface é útil quando precisamos:

  • agrupar as nossas classes dentro de um mesmo contexto;
  • Na programação genérica (veja: Tipos Genéricos (Generics) );
  • Outros que vocês irão descobrir com o tempo;

Na herança de interface apenas herdamos as assinaturas de métodos e propriedades ao contrário da herança de implementação que além de herdar  as assinaturas herdamos também seu código, logo, no caso da interface temos que escrever o código do método ou propriedade.

Agregação

A agregação define uma dependência fraca entre as classes, isto quer dizer que os outros objetos continuam existindo mesmo que o todo for removido.
Podemos dizer que uma classe agregada (o todo) é montada com um conjunto de componentes (as partes).

Como exemplo vamos usar um carro.
Em nosso carro (classe agregada, o todo) temos os componentes (as partes), rodas, portas, motor.
Se desmontarmos o carro, as partes (rodas, portas, motor) continuaram a existir e poderão ser usadas em outro carro.

Composição

A composição define uma dependência forte entre as classes, isto quer dizer que se o todo deixar de existir as suas partes também deixaram de existir.

Exemplo:
Uma revista em quadrinhos, ela é composta por suas páginas. Se o todo, a revista, deixar de existir, suas páginas não farão sentido.

Como outro exemplo podemos citar um pedido e seus itens. Esta ligação é forte, logo é uma composição. Os itens não fariam sentido sem o Pedido. Se excluirmos o pedido seus itens serão excluídos. (Isto não te lembra um relacionamento feito em definição de tabelas? 1 para n ON DELETE CASCADE).

Para finalizarmos vamos colocar um diagrama de classes e um código para reforçar a idéia.

Diagrama acima convertido em código:

Interface IPessoa

namespace Heranca
{
    /// <summary>
    /// esta é uma interface.
    /// Percebam que declaramos apenas os métodos,
    /// iremos usar neste caso a herança de interface
    /// </summary>
    interface IPessoa
    {
        void Dancar();
        DateTime DataNascimento { get; set; }
        void Envelhecer();
        void Falar();
        int Idade { get; }
        string Nome { get; set; }
        Sexo Sexo { get;  }
    }
}

Classe Pessoa

namespace Heranca
{
    public enum Sexo
    {
        NaoDefinido,
        Masculino,
        Feminino
    }

    /// <summary>
    /// esta classe é uma classe genérica pra todo tipo de pessoa.
    /// vejam que aqui iremos herdar a interface IPessoa,
    /// neste caso será uma herança de interface.
    /// Devemos escrever código para todo método e propriedade
    /// definido na interface.
    /// </summary>
    abstract class Pessoa : IPessoa
    {
        /// <summary>
        /// esta propriedade poderá ser sobreescrita
        /// nas classes filhas. mas não é obrigatória
        /// </summary>
        public virtual int Idade
        {
            get
            {
                int idade = DateTime.Now.Year - DataNascimento.Year;
                if (DateTime.Now.Month < DataNascimento.Month ||
                (DateTime.Now.Month == DataNascimento.Month &&
                DateTime.Now.Day < DataNascimento.Day))
                    idade--;
                return idade;
            }
        }

        public DateTime DataNascimento { get; set; }

        /// <summary>
        /// esta propriedade deverá obrigatoriamente ser declarada
        /// na classe pai
        /// </summary>
        public abstract Sexo Sexo { get; }

        public virtual String Nome { get; set; }

        public virtual void Envelhecer()
        {
            DataNascimento = DataNascimento.AddYears(1);
            Console.WriteLine("A pessoa envelheceu um ano.");
        }

        public virtual void Dancar()
        {
            Console.WriteLine("A pessoa está dançando");
        }

        public virtual void Falar()
        {
            Console.WriteLine(@"A pessoa disse: visitem

http://desenvolvedores.net");

        }
    }
}

Classe Pai

namespace Heranca
{
    /// <summary>
    /// Aqui iremos herdar a classe pessoa.
    /// vejam que apenas escrevi a propriedade Sexo.
    /// Pois na classe pai (abstrata) estava definido
    /// que as filhas deveria escrever o código para sexo.
    /// Mas as outras propriedades e métodos serão herdados de pessoa
    /// </summary>
    class Pai : Pessoa
    {
        public override Sexo Sexo { get { return Sexo.Masculino; } }

        /// <summary>
        /// este método poderá ser sobreescrito nas classes filhas
        /// neste caso o pai está apenas brincando.
        /// Veremos ele sobreescrito na classe filha
        /// </summary>
        public virtual void Brincar()
        {
            Console.WriteLine("O pai está brincando");
        }
    }
}

Classe Filho

namespace Heranca
{
    /// <summary>
    /// aqui o filho herdou todas as características do pai
    /// </summary>
    class Filho : Pai
    {

        /// <summary>
        /// aqui iremos substituir o método Brincar
        /// </summary>
        public override void Brincar()
        {
            Console.WriteLine("O filho está brincando com seu pai.");
        }
    }
}

Classe Aluno

namespace Heranca
{
    /// <summary>
    /// mais um classe que herda de pessoa
    /// </summary>
    class Aluno : Pessoa
    {
        public override Sexo Sexo
        {
            get { return Sexo.Feminino; }
        }

        public int VerNota()
        {
            return new Random().Next(0, 10);
        }
    }
}

E finalmente o código escrito em uma aplicação do tipo console.
Atenção, prestem bastante atenção aos comentários, eles têm dicas importantes.

namespace Heranca
{
    class Program
    {
        static void Main(string[] args)
        {
            /*
             * aqui vai um dica útil.
             * Cuidado ao declarar o seu tipo de objeto
             * pois as propriedades e métodos que você
             * irá visualizar depende do tipo declarado
             *
             * Vejam aqui, vou declarar como um objeto Pessoa
             * mas vou instanciar como um Aluno
             */

            Pessoa pessoaAluno = new Aluno();

            pessoaAluno.Nome = "Marcelo";

            /*
             * reparem que o método VerNota() só existe
             * na classe Aluno, logo na linha 17,
             * mesmo o objeto sendo instanciado como
             * new Aluno() seus métodos só existirão
             * através do seu tipo definido Pessoa
             */

            Console.WriteLine(pessoaAluno.Nome);

            /*
             * Mas, e se precisarmos acessar
             * os dados de Aluno?
             * Simplesmente faça um cast (conversão)
             * de um objeto para outro
             * Vejam:
             */

            Aluno aluno = pessoaAluno as Aluno;

            Console.WriteLine(aluno.VerNota());

            /*
             * A dica acima é válida tambem para os tipos
             * interfaces
             */

            IPessoa pessoaFilho = new Filho();
            pessoaFilho.Falar();

            Filho filho = pessoaFilho as Filho;
            filho.Brincar();

            /*
             * Abaixo um exemplo do override em filho
             */

            Pai pai = new Pai();

            //aqui chamamos o método brincar de Pai
            pai.Brincar();

            //aqui chamamos o método brincar que foi substituido
            Filho meuFilho = new Filho();
            meuFilho.Brincar();

            /*
             * Legal. Mas posso chamar o método
             * Brincar da classe base?
             */

            pai = filho as Pai;
            pai.Brincar();

            /*
             * Não. Não podemos.
             * Apesar da instrução acima não dar erro
             * o método que será chamado é sempre
             * o método substituído.
             *
             * Mas a afirmação acima não é 100% correta.
             * Se em nossa classe Filho o método tivesse
             * sido declarado assim:
             * public new void Brincar()
             * O método chamado seria o da classe Pai,
             * pois neste caso não substituimos o método
             * e sim criamos um novo.
             *
             * Vejam as duas declarações juntas para comparar
             *
             * public new void Brincar()
             * public override void Brincar()
             */

            Console.ReadKey();

        }
    }
}

Ver Índice

É isso ai pessoal :)
Até o próximo
♦ Marcelo

About Marcelo

Nascido em Juruaia/MG em uma fazenda de criação de búfalos. Está perdido em São Paulo trabalhando com desenvolvimento de aplicações desde os 17 anos. Atualmente é arquiteto de software, é um cara meia boca que fica entre a equipe de desenvolvimento e o gerente de projetos, no meio da ponte. Para saber mais ... http://desenvolvedores.net/marcelo []'s

Programação Orientada a Objetos (POO)

14
1 Estrela2 Estrelas3 Estrelas4 Estrelas5 Estrelas (3 votos, média: 5,00 de 5)
Loading ... Loading ...
13 de dezembro de 2010
Olá Pessoal.Agora vou iniciar uma série de artigos sobre Programação Orientada a Objetos (POO) ou Object-Oriented Programming (OOP).Na medida do possível irei mostrar como programar cada explicação em alguma linguagem.Este primeiro artigo irá servir como um índice para os outros, sempre que eu postar um item deste índice, irei modificar este artigo fazendo um link daqui para a explicação e vice-versa.Então vamos lá, mãos à obra e vamos ver o que teremos :)
É isso ai pessoal :)
Até o próximo
♦ Marcelo

About Marcelo

Nascido em Juruaia/MG em uma fazenda de criação de búfalos. Está perdido em São Paulo trabalhando com desenvolvimento de aplicações desde os 17 anos. Atualmente é arquiteto de software, é um cara meia boca que fica entre a equipe de desenvolvimento e o gerente de projetos, no meio da ponte. Para saber mais ... http://desenvolvedores.net/marcelo []'s