Difference between revisions of "Herança e Composição/Definição Simples de Superclasse e Subclasse"

From Wiki**3

< Herança e Composição
(Cenário A)
(Classe "Aplication")
 
(14 intermediate revisions by the same user not shown)
Line 1: Line 1:
 
{{TOCright}}
 
{{TOCright}}
O exemplo aqui apresentado ilustra o processo de especialização de uma classe por outra, de si derivada. Além do processo de especialização, o exemplo permite ver ainda aspectos como a iniciação de atributos [[Palavras chave da linguagem Java#final|final]] e a invocação explícita de construtores de superclasses (i.e., a sequência de iniciação de um objecto de uma classe derivada de outra).
+
O exemplo aqui apresentado ilustra o processo de especialização de uma classe por outra, de si derivada. Além do processo de especialização, o exemplo permite ver ainda aspectos como a iniciação de atributos '''final''' e a invocação explícita de construtores de superclasses (i.e., a sequência de iniciação de um objecto de uma classe derivada de outra).
  
A aplicação exemplo ilustra ainda o processo de ''upcasting'', i.e., utilizar uma referência de um tipo mais geral que o do objecto que refere.
+
A aplicação exemplo ilustra ainda o processo de ''upcasting'', i.e., utilizar uma referência de um tipo mais geral que o do objecto que refere.
  
== Classe <code>SuperClasse</code> ==
+
== Classe "SuperClasse" ==
  
A classe <code>SuperClasse</code> representa o conceito mais geral, que irá ser posteriormente especializado.
+
A classe '''SuperClasse''' representa o conceito mais geral, que irá ser posteriormente especializado.
  
São apresentados dois cenários para ilustrar o comportamento na iniciação de um atributo declarado <tt>final</tt>.
+
São apresentados dois cenários para ilustrar o comportamento na iniciação de um atributo declarado '''final'''.
  
 
=== Cenário A ===
 
=== Cenário A ===
  
No cenário A, o atributo é declarado, mas não tem um iniciador por omissão explícito. Por isso, é possível definir no construtor o seu valor.
+
No cenário A, o atributo é declarado, mas não tem um iniciador por omissão explícito. Por isso, é possível definir no construtor o seu valor.
  
<java5>
+
<source lang="java">
 
   public class SuperClasse {
 
   public class SuperClasse {
     private         int _a = 78;
+
     private       int _a = 78;
 
     protected final int _x;        // cenário A
 
     protected final int _x;        // cenário A
 
    
 
    
Line 36: Line 36:
 
    
 
    
 
   }
 
   }
</java5>
+
</source>
  
 
=== Cenário B ===
 
=== Cenário B ===
  
No cenário A, o atributo é declarado, mas já tem um iniciador por omissão explícito. Por isso, já não é possível definir no construtor o seu valor.
+
No cenário B, o atributo é declarado, mas já tem um iniciador por omissão explícito. Por isso, já não é possível definir no construtor o seu valor.
 
+
<source lang="java">
 
   public class SuperClasse {
 
   public class SuperClasse {
 
     private        int _a = 78;
 
     private        int _a = 78;
Line 63: Line 63:
 
    
 
    
 
   }
 
   }
 +
</source>
  
== Classe <code>SubClasse</code> ==
+
== Classe "SubClasse" ==
  
A classe <tt>SuibClasse</tt> corresponde a uma especialização da superclasse e redefine o método <tt>getX</tt>.
+
A classe '''SubClasse''' corresponde a uma especialização da superclasse e redefine o método '''getX'''.
  
Note-se a sintaxe de invocação do construtor da superclasse, utilizando a palavra chave [[Palavras chave da linguagem Java#super|super]]: esta chamada é necessária, pois a não existência de um construtor sem argumentos na superclasse faz com que o comportamento por omissão do construtor da subclasse (na iniciação da porção do objecto correspondente à superclasse) não possa ser executado.
+
Note-se a sintaxe de invocação do construtor da superclasse, utilizando a palavra chave '''super''': esta chamada é necessária, pois a não existência de um construtor sem argumentos na superclasse faz com que o comportamento por omissão do construtor da subclasse (na iniciação da porção do objecto correspondente à superclasse) não possa ser executado.
  
 +
<source lang="java">
 
   public class SubClasse extends SuperClasse {
 
   public class SubClasse extends SuperClasse {
 
    
 
    
Line 84: Line 86:
 
    
 
    
 
   }
 
   }
 +
</source>
  
 
== Aplicação Exemplo ==
 
== Aplicação Exemplo ==
  
Note-se o processo de ''upcasting'' (em <code>myD</code>): a referência é para <code>SuperClasse</code> e o objecto é do tipo <code>SubClasse</code>.
+
Note-se o processo de ''upcasting'' (em '''myD'''): a referência é para '''SuperClasse''' e o objecto é do tipo '''SubClasse'''.
  
=== Classe <code>Aplicação</code> ===
+
=== Classe "Aplication" ===
  
Note-se que a chamada a <code>getA</code> ([[Palavras chave da linguagem Java#final|final]]) é sempre executada fazendo do uso do código da superclasse (o facto de o método ser <code>final</code> impede a redefinição pelas subclasses).
+
Note-se que a chamada a '''getA''' ('''final''') é sempre executada fazendo do uso do código da superclasse (o facto de o método ser '''final''' impede a redefinição pelas subclasses).
 
+
<source lang="java">
   public class Aplicação {
+
   public class Aplication {
 
     public static void main(String args[]) {
 
     public static void main(String args[]) {
 
       SuperClasse myS = new SuperClasse(8);  // ok: mesmo tipo
 
       SuperClasse myS = new SuperClasse(8);  // ok: mesmo tipo
Line 103: Line 106:
 
     }
 
     }
 
   }
 
   }
 +
</source>
  
=== Saída da Aplicação ===
+
=== Saída da Aplicação ===
  
   $ java Aplicação
+
   $ '''java Aplication'''
 
    
 
    
 
   -- calling SuperClasse.SuperClasse(8)
 
   -- calling SuperClasse.SuperClasse(8)
Line 120: Line 124:
 
   -- calling SubClasse.getX() returns 5
 
   -- calling SubClasse.getX() returns 5
 
   in main: myD.getX() = 5
 
   in main: myD.getX() = 5
 +
 +
 +
[[category:PO]]
 +
[[category:PO Exemplos]]
 +
[[category:Ensino]]

Latest revision as of 14:36, 29 September 2020

O exemplo aqui apresentado ilustra o processo de especialização de uma classe por outra, de si derivada. Além do processo de especialização, o exemplo permite ver ainda aspectos como a iniciação de atributos final e a invocação explícita de construtores de superclasses (i.e., a sequência de iniciação de um objecto de uma classe derivada de outra).

A aplicação exemplo ilustra ainda o processo de upcasting, i.e., utilizar uma referência de um tipo mais geral que o do objecto que refere.

Classe "SuperClasse"

A classe SuperClasse representa o conceito mais geral, que irá ser posteriormente especializado.

São apresentados dois cenários para ilustrar o comportamento na iniciação de um atributo declarado final.

Cenário A

No cenário A, o atributo é declarado, mas não tem um iniciador por omissão explícito. Por isso, é possível definir no construtor o seu valor.

  public class SuperClasse {
    private        int _a = 78;
    protected final int _x;         // cenário A
  
    SuperClasse(int x) {
      System.out.println("-- calling SuperClasse.SuperClasse(" + x + ")");
      _a = (int)(100*Math.random());
      _x = x;  // ok:   cenário A
    }
  
    final int getA() {
      System.out.println("-- calling SuperClasse.getA() returns " + _a);
      return _a;
    }
  
    protected int getX() {
      System.out.println("-- calling SuperClasse.getX() returns " + _x);
      return _x;
    }
  
  }

Cenário B

No cenário B, o atributo é declarado, mas já tem um iniciador por omissão explícito. Por isso, já não é possível definir no construtor o seu valor.

  public class SuperClasse {
    private         int _a = 78;
    protected final int _x = 93;    // iniciação
  
    SuperClasse(int x) {
      System.out.println("-- calling SuperClasse.SuperClasse(" + x + ")");
      _a = (int)(100*Math.random());
      //_x = x;  // erro: já está iniciada
    }
  
    final int getA() {
      System.out.println("-- calling SuperClasse.getA() returns " + _a);
      return _a;
    }
  
    protected int getX() {
      System.out.println("-- calling SuperClasse.getX() returns " + _x);
      return _x;
    }
  
  }

Classe "SubClasse"

A classe SubClasse corresponde a uma especialização da superclasse e redefine o método getX.

Note-se a sintaxe de invocação do construtor da superclasse, utilizando a palavra chave super: esta chamada é necessária, pois a não existência de um construtor sem argumentos na superclasse faz com que o comportamento por omissão do construtor da subclasse (na iniciação da porção do objecto correspondente à superclasse) não possa ser executado.

  public class SubClasse extends SuperClasse {
  
    SubClasse() {
      super(4);
      System.out.println("-- calling SubClasse.SubClasse()");
    }
  
    protected int getX() {
      int result = 1 + super.getX();
      System.out.println("-- calling SubClasse.getX() returns " + result);
      return result;
    }
  
  }

Aplicação Exemplo

Note-se o processo de upcasting (em myD): a referência é para SuperClasse e o objecto é do tipo SubClasse.

Classe "Aplication"

Note-se que a chamada a getA (final) é sempre executada fazendo do uso do código da superclasse (o facto de o método ser final impede a redefinição pelas subclasses).

  public class Aplication {
    public static void main(String args[]) {
      SuperClasse myS = new SuperClasse(8);  // ok: mesmo tipo
      SuperClasse myD = new SubClasse();     // ok: upcasting
      System.out.println("in main: myS.getA() = " + myS.getA());
      System.out.println("in main: myS.getX() = " + myS.getX());
      System.out.println("in main: myD.getA() = " + myD.getA());
      System.out.println("in main: myD.getX() = " + myD.getX());
    }
  }

Saída da Aplicação

 $ java Aplication
 
 -- calling SuperClasse.SuperClasse(8)
 -- calling SuperClasse.SuperClasse(4)
 -- calling SubClasse.SubClasse()
 -- calling SuperClasse.getA() returns 46
 in main: myS.getA() = 46
 -- calling SuperClasse.getX() returns 8
 in main: myS.getX() = 8
 -- calling SuperClasse.getA() returns 9
 in main: myD.getA() = 9
 -- calling SuperClasse.getX() returns 4
 -- calling SubClasse.getX() returns 5
 in main: myD.getX() = 5