photo
+ Responder ao Tópico
Resultados de 1 a 1 de 1

Thread: Herança

  1. #1 Fechar a publicação
    Senior Member usuarioforum's Avatar usuarioforum's Avatar
    Data de afiliação
    Aug 2018
    Postagens
    579
    Obrigado
    166
    Agradecimentos 661 Tempos em 388 Postagens
    AssinarAssinar
    subscritar: 0

    Herança

    O principal característica da OOP é o incentivo à reutilização de código através de herança. Uma nova classe é feita a partir de uma já existente, que é chamada de classe base. A classe derivada usa os membros da classe base, mas também pode modificar e complementá-los.

    Muitos tipos são variações de tipos já existentes. É muitas vezes tedioso desenvolver um novo código para cada um deles. Além disso, um novo código implica em novos erros. A classe derivada herda a descrição da classe base, assim qualquer re-desenvolvimento e re-teste de código é desnecessário. As relações de herança são hierárquicas.

    Hierarquia é um método que permite copiar os elementos em toda a sua diversidade e complexidade. Ela introduz a classificação de objetos. Por exemplo, a tabela periódica de elementos tem gases. Eles possuem propriedades inerentes a todos os elementos periódicos.

    Gases inertes constituem a próxima importante subclasse. A hierarquia é que o gás inerte, como árgon, é um gás, e um gás, por sua vez, é parte do sistema. Tal hierarquia permite interpretar o comportamento dos gases inertes com facilidade. Sabemos que seus átomos contêm prótons e elétrons, o que é verdade para todos os outros elementos.

    Sabemos que eles estão no estado gasoso à temperatura ambiente, como todos os gases. Sabemos que nenhum gás da subclasse de gases inertes entra usualmente em reações químicas com outros elementos, e isso é uma propriedade de todos os gases inertes.

    Considere um exemplo de herança de formas geométricas. Para descrever a completa variedade de formas simples (círculos, triângulos, retângulos, quadrados, etc.), a melhor forma é criar uma classe base (ADT), que é o predecessor de todas as classes derivadas.

    Vamos criar uma classe base CShape, que contém apenas a maioria dos membros comuns que descrevem a forma. Estes membros descrevem propriedades que são características de qualquer forma - o tipo da forma e as coordenadas do ponto de ancoragem principal.

    Exemplo:

    //--- A classe base da forma (Shape)
    class CShape
    {
    protected:
    int m_type; // Tipo de Forma
    int m_xpos; // X - coordenada do ponto base
    int m_ypos; // Y - coordenada do ponto base
    public:
    CShape(){m_type=0; m_xpos=0; m_ypos=0;} // construtor
    void SetXPos(int x){m_xpos=x;} // define X
    void SetYPos(int y){m_ypos=y;} // define Y
    };

    Sem seguida, criamos novas classes derivadas da classe base, nas quais adicionaremos campos necessários, cada um especificando uma certa classe. Para a forma Círculo, é necessário adicionar um membro que contém o valor do raio. A forma Quadrado é caracterizada pelo valor do lado. Portanto, classes derivadas, herdadas da classe base CShape, serão declaradas como se segue:

    //--- A classe derivada círculo (Circle)
    class CCircle : public CShape // Depois de um dois pontos, nós definimos a classe base
    { // a partir da qual a herança é feita
    private:
    int m_radius; // raio do círculo

    public:
    CCircle(){m_type=1;}// construtor, tipo 1
    };

    Para a classe do Quadrado, a declaração é semelhante:

    //--- a classe derivada quadrado (Square)
    class CSquare : public CShape // Depois de um dois pontos, nós definimos a classe base
    { // a partir da qual a herança é feita
    private:
    int m_square_side; // lado do quadrado

    public:
    CSquare(){m_type=2;} // construtor, tipo 2
    };

    Deve-se notar que enquanto um objeto é criado, o construtor da classe base é chamado primeiro, e então o construtor da classe derivada é chamado. Quando um objeto é destruído, primeiro o destrutor da classe derivada é chamado, e então o destrutor da classe base é chamado.

    Assim, ao declarar a maioria do membros gerais na classe base, podemos acrescentar membros adicionais nas classes derivadas que especificam uma classe particular. A herança permite criar bibliotecas de código poderosas que podem ser reutilizadas muitas vezes.

    A sintaxe para criar uma classe derivada a partir de uma classe já existente é a seguinte:

    class class_name :
    (public | protected | private) opt base_class_name
    {
    declaração de membros de classe
    };



    Um dos aspectos da classe derivada é a visibilidade (abertura) de seus sucessores membros (herdeiros). As palavras-chave public, protected e private são usadas para indicar quão disponíveis os membros da classe base estarão disponíveis para a classe derivada. A palavra-chave public após um dois pontos no cabeçalho de uma classe derivada indica que os membros protegidos e públicos da classe base CShape devem ser herdados como membros protegidos e públicos da classe derivada CCircle.

    Os membros privados da classe base não são disponíveis para a classe derivada. A herança pública também significa que classes derivadas (CCircle e CSquare) são CShapes. Isto é, o Quadrado (CSquare) é uma Forma (CShape), mas a Forma não necessariamente tem que ser um Quadrado.

    A classe derivada é uma modificação da classe base, ele herda os membros protegidos e públicos da classe base. Os construtores e destrutores da classe base não podem ser herdados. Além de membros da classe base, novos membros são adicionados em uma classe derivada.

    A classe derivada pode incluir a implementação de funções membro, diferentes da classe base. Isso não tem nada a ver com uma sobrecarga, quando o significado de um mesmo nome de uma função pode ser diferente para diferentes assinaturas.

    Em herança protegida, membros públicos e protegidos da classe base tornam-se membros protegidos da classe derivada. Em herança privada, os membros públicos e protegidos da classe base tornam-se membros privados da classe derivada.

    Em herança protegida e privada, a relação "o objeto de uma classe derivada é objeto da classe base" não é verdade. Os tipos protegido e privado de herança são raros, e cada um deles precisam ser usados com cautela.

    Deve ser entendido que o tipo de herança (public, protected ou private) não afeta a forma de acessar os membros de classes base na hierarquia de herança a partir de uma classe derivada. Para qualquer tipo de herança, somente membros da classe base declarados com especificadores de acesso public e protected estarão disponíveis fora das classes derivadas. Vamos verificar isso no seguinte exemplo:

    #property copyright "Copyright 2011, MetaQuotes Software Corp."
    #property link "https://www.mql5.com"
    #property version "1.00"
    //+------------------------------------------------------------------+
    //| Exemplo de classe com alguns tipos de acesso |
    //+------------------------------------------------------------------+
    class CBaseClass
    {
    private: //--- O membro privado não é disponível a partir de classe derivada
    int m_member;
    protected: //--- O método protegido é disponível a partir da classe base e suas classes derivadas
    int Member(){return(m_member);}
    public: // O construtor de classe é disponível para todos os membros
    CBaseClass(){m_member=5;return;};
    private: //--- Um método particular para atribuir um valor para m_member
    void Member(int value) { m_member=value;};

    };
    //+------------------------------------------------------------------+
    //| Classe derivada com erros |
    //+------------------------------------------------------------------+
    class CDerived: public CBaseClass // especificação da herença pública pode ser omitido, uma vez que é predefinido
    {
    public:
    void Func() // Na classe derivada, defina uma função com chamadas aos membros da classe base
    {
    //--- Uma tentativa de alterar um membro privado da classe base
    m_member=0; // Erro, o membro privado da classe base não é disponível
    Member(0); // Erro, o método privado da classe base não é disponível em classes derivadas
    //--- Leitura do membro da classe base
    Print(m_member); // Erro, o membro privado da classe base não é disponível
    Print(Member()); // Sem erro, método protegido é acessível a partir da classe base e suas classes derivadas
    }
    };

    No exemplo acima, CBaseClass tem apenas um método público - o construtor. Construtores são chamados automaticamente na criação de um objeto de classe. Portanto, o membro privado m_member e o método protegido Member() não podem ser chamados do lado de fora. Mas no caso de herança pública, o membro Member() da classe base estará disponível a partir de classes derivadas.

    No caso de herança protegida, todos os membros da classe base com acessos público e protegido tornam-se protegidos. Isso significa que membros de dados e métodos públicos da classe base, com herança protegida eles passam a ser disponíveis somente a partir de classes derivadas e de suas derivadas seguintes.

    //+------------------------------------------------------------------+
    //| Exemplo de classe com alguns tipos de acesso |
    //+------------------------------------------------------------------+
    class CBaseMathClass
    {
    private: //--- O membro privado não é disponível a partir de classe derivada
    double m_Pi;
    public: //--- Obtendo e definindo um valor para m_Pi
    void SetPI(double v){m_Pi=v;return;};
    double GetPI(){return m_Pi;};
    public: // O construtor de classe é disponível para todos os membros
    CBaseMathClass() {SetPI(3.14); PrintFormat("%s",__FUNCTION__);};
    };
    //+------------------------------------------------------------------+
    //| Uma classe derivada, em que m_Pi não pode ser modificada |
    //+------------------------------------------------------------------+
    class CProtectedChildClass: protected CBaseMathClass // Herança protegida
    {
    private:
    double m_radius;
    public: //--- Métodos públicos na classe derivada
    void SetRadius(double r){m_radius=r; return;};
    double GetCircleLength(){return GetPI()*m_radius;};
    };
    //+------------------------------------------------------------------+
    //| Função de inicialização de script |
    //+------------------------------------------------------------------+
    void OnStart()
    {
    //--- Ao criar uma classe derivada, o construtor da classe base será chamada automaticamente
    CProtectedChildClass pt;
    //--- Especifica o raio
    pt.SetRadius(10);
    PrintFormat("Length=%G",pt.GetCircleLength());
    //--- Se comentar a string abaixo, obteremos um erro na etapa de compilação, já que SetPi() é agora protegida
    // pt.SetPI(3);

    //--- Agora declare um variável da classe base e tente definir a constante Pi igual a 10
    CBaseMathClass bc;
    bc.SetPI(10);
    //--- Aqui está o resultado
    PrintFormat("bc.GetPI()=%G",bc.GetPI());
    }

    O exemplo mostra que os métodos SetPI() e GetPI() na classe base CBaseMathClasse estão abertos e disponíveis para chamadas a partir de qualquer lugar do programa. Mas ao mesmo tempo, para CProtectedChildClasse, que é derivada dela, estes métodos podem ser chamados somente a partir de métodos da classe CProtectedChildClass ou suas classes derivadas.

    No caso de herança privada, todos os membros da classe base com acesso público e protegido tornam-se privados, e chamá-los torná-se impossível em herança posterior.

    MQL5 não tem herança múltipla.

    Though trading on financial markets involves high risk, it can still generate extra income in case you apply the right approach. By choosing a reliable broker such as InstaForex you get access to the international financial markets and open your way towards financial independence. You can sign up here.


  2. Os seguintes 2 Usuários Dizem Obrigado o a usuarioforum por este post útil:

    Não registrado (2 )

+ Responder ao Tópico

Permissões de postagens

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts