Classes Internas (Java)/Carros e Motores: Difference between revisions

From Wiki**3

< Classes Internas (Java)
Line 89: Line 89:


== Classe externa deriva de classe interna ==
== Classe externa deriva de classe interna ==
* Duas classes externas não directamente relacionadas entre si: <code>Carro</code> e <code>MotorEl&eacute;ctrico</code>.
* Duas classes externas não directamente relacionadas entre si: '''Carro''' e '''MotorEléctrico'''.
* Uma das classes externas (<code>MotorEl&eacute;ctrico</code>) deriva de uma classe interna (<code>Motor</code>).
* A classes externa '''MotorEléctrico''' deriva da classe interna '''Motor'''.


Note-se que a criação de instâncias da classe que deriva da classe interna só pode ser feita se algum dos seus construtores fornecer o contexto necessário à criação de instâncias da sua superclasse (i.e., é necessário um carro para se poder criar um motor).
Note-se que a criação de instâncias da classe que deriva da classe interna só pode ser feita se algum dos seus construtores fornecer o contexto necessário à criação de instâncias da sua superclasse (i.e., é necessário um carro para se poder criar um motor).


=== Carro ===
=== Carro ===

Revision as of 12:55, 24 October 2016

Os exemplos seguintes apresentam algumas possibilidades de extensão (herança) de classes internas e externas.

Classes externas e internas

  • Duas classes externas relacionadas entre si: Carro e CarroEléctrico (esta subclasse da primeira).
  • Duas classes internas relacionadas entre si, mas pertencendo cada uma a sua classe externa.

Note-se que não há qualquer problema em reutilizar nomes de classes internas em múltiplas classes externas, uma vez que a sua identificação se faz de forma relativa ao contexto em que são definidas.

Carro

<java5>

public class Carro {
  protected String _estado;

  abstract class Motor {
    abstract void ligar();
    abstract void desligar();
  }

  class Motor0 {
   Motor0(String estado) {
      _estado = estado;
      System.out.println("Motor0 criado (" + _estado + ")");
    }
  }

  Carro()      { System.out.println("Carro criado"); }
  void andar() { System.out.println("andar");        }
}

</java5>

Carro Eléctrico

<java5>

public class CarroEléctrico extends Carro {

  class Motor extends Motor0 {
    Motor() { super("LIGADO"); }
    void ligar()    { _estado = "LIGADO";    System.out.println("Motor " + _estado); }
    void desligar() { _estado = "DESLIGADO"; System.out.println("Motor " + _estado); }
  }

  CarroEléctrico() { System.out.println("Carro eléctrico criado"); }

  void andar() {
    super.andar();
    Motor m = new Motor();
    m.ligar();
    System.out.println("andar eléctrico");
    m.desligar();
  }

}

</java5>

Teste

<java5>

public class Teste7 {
  public static void main(String[] args) {

    Carro c = new Carro();
    c.andar();

    Carro e = new CarroEléctrico();
    e.andar();
  }
}

</java5>

Resultados

 $ java Teste7
 Carro criado
 andar
 Carro criado
 Carro eléctrico criado
 andar
 Motor0 criado (LIGADO)
 Motor LIGADO
 andar eléctrico
 MotorDESLIGADO
 $ ls
 Carro.java Carro.class Carro$Motor.class Carro$Motor0.class
 CarroEléctrico.java CarroEléctrico.class CarroEléctrico$Motor.class
 Teste7.java Teste7.class

Classe externa deriva de classe interna

  • Duas classes externas não directamente relacionadas entre si: Carro e MotorEléctrico.
  • A classes externa MotorEléctrico deriva da classe interna Motor.

Note-se que a criação de instâncias da classe que deriva da classe interna só pode ser feita se algum dos seus construtores fornecer o contexto necessário à criação de instâncias da sua superclasse (i.e., é necessário um carro para se poder criar um motor).

Carro

<java5>

public class Carro {
  protected String _estado;
  protected Motor  _motor;

  abstract class Motor {
    Motor(String estado) {
      _motor  = this;
      _estado = estado;
      System.out.println("Motor criado (" + _estado + ")");
    }
    void ligar()    { _estado = "LIGADO";    System.out.println("Motor " + _estado); }
    void desligar() { _estado = "DESLIGADO"; System.out.println("Motor " + _estado); }
  }

  Carro() { System.out.println("Carro criado"); }

  void andar() {
    _motor.ligar();
    System.out.println("andar");
    _motor.desligar();
  }
}

</java5>

Motor Eléctrico

<java5>

public class MotorEléctrico extends Carro.Motor {

  private MotorEléctrico(Carro c, String estado) {
    c.super(estado);
    System.out.println("Carro eléctrico pré-criado");
  }

  MotorEléctrico(Carro c) {
    this(c, "LIGADO");
    System.out.println("Carro eléctrico criado");
  }

  void ligar() {
    super.ligar();
    System.out.println("Motor eléctrico ligado");
  }

  void desligar() {
    super.desligar();
    System.out.println("Motor eléctrico desligado");
  }

}

</java5>

Teste

<java5>

public class Teste8 {
  public static void main(String[] args) {
    Carro c = new Carro();
    new MotorEléctrico(c);
    c.andar();
  }
}

</java5>

Resultados

 $ java Teste8
 Carro criado
 Motor criado (LIGADO)
 Carro eléctrico pré-criado
 Carro eléctrico criado
 Motor LIGADO
 Motor eléctrico ligado
 andar
 Motor DESLIGADO
 Motor eléctrico desligado
 $ ls
 Carro.java Carro.class Carro$Motor.class
 MotorEléctrico.java MotorEléctrico.class
 Teste8.java Teste8.class

Especialização de classe interna

Este exemplo apresenta quatro classes: duas internas e duas externas. A relação entre as classes internas é de herança; a relação entre as classes externas também é de herança.

Pretende-se demonstrar a utilização de classes internas quando há reutilização por herança. Note-se que cada classe externa utiliza sempre as suas classes internas, independentemente de o objecto em causa ser de uma subclasse.

Carro

<java5>

public class Carro {

  protected class Motor {
    Motor() { System.out.println("Motor"); }
  }

  public Carro() {
    System.out.println("Carro");
    Motor m = new Motor();
  }
}

</java5>

Carro Eléctrico

<java5>

public class CarroEléctrico extends Carro {

  protected class Motor extends Carro.Motor {
    Motor() { System.out.println("Motor eléctrico"); }
  }

  public CarroEléctrico() {
    System.out.println("Carro eléctrico");
    Motor m = new Motor();
  }
}

</java5>

Teste

<java5> public class Teste9 {

  public static void main(String[] args) {
    new CarroEléctrico();
  }
}

</java5>

Resultados

 $ java Teste9
 Carro
 Motor
 Carro eléctrico
 Motor
 Motor eléctrico
 $ ls
 Carro.java Carro.class Carro$Motor.class
 CarroEléctrico.java CarroEléctrico.class CarroEléctrico$Motor.class
 Teste9.java Teste9.class