Tag: PA-1920-Cap-06-polimorfismo.pdf

Programação avançada – capitulo 6

O upcasting:
serve para realizar a conversão de tipo, de uma classe derivada para uma classe base
permite assim converter um tipo mais restrito num tipo mais alargado

O polimorfismo:
“O mecanismo de polimorfismo consiste na qualidade de poder decidir a operação que vai ser executada num dado instante , em função dos objetos específicos envolvidos na operação”

As classes abstractas:
um método é abstracto, se o seu prototípico for escrito precedido da palavra abstract
uma classe que tenha um método abstracto tem que ser declarada como abstracta
não se podem criar objectos em classes abstractas
uma classe pode ser abstracta, mesmo não tendo qualquer método abstracto (caso de uma classe derivada de uma abstracta)
uma classe derivada não é abstracta se tiver definidos todos os métodos da classe abstracta
uma classe derivada é abstracta se não tiver pelo menos um método da classe base

exemplo (especialização: do topo para a base, generalização: da base para o topo (sentido das setas)):

package e16;

abstract class Veiculo {
    abstract int calculaCarro();
    abstract int calculaAutocarro();
}

//errada esta classe Carro.. se é abstracta só deveria ter protótipos das funções
abstract class Carro extends Veiculo {
    private int km;
    private int custo = 5;

    public Carro(int k) {
        this.km = k;
    }
    int calculaCarro() {
        int valor = this.km * custo;
        return valor;
    }
    public String toString() {
        return "despesa do carro: " + calculaCarro();
    }
}

class Autocarro extends Veiculo {
    private int km;
    private int custo = 4;

    public Autocarro() { //importante - parte1
    }
    public Autocarro(int k) {
        this.km = k;
    }
    int calculaAutocarro() {
        int valor = this.km * custo;
        return valor;
    }
    int calculaCarro() {
        int valor = this.km * custo;
        return valor;
    }
    public String toString() {
        return "despesa do autocarro: " + calculaAutocarro();
    }
}

class MiniAutocarro extends Autocarro {
    private int km;
    private int custo = 1;

    public MiniAutocarro() { //importante - parte2
    }
    public MiniAutocarro(int k) {
        this.km = k;
    }
    int calculaMiniAutocarro() {
        int valor = this.km * custo;
        return valor;
    }
    public String toString() {
        return "despesa do mini-autocarro: " + calculaMiniAutocarro() + " , " + super.toString();
    }
}

public class e16 {

    public static void main(String args[]) {
        System.out.println("\n Classe abstracta:"); //sout+tab
        Veiculo v1;
        v1 = new Autocarro(100);
        System.out.println(v1.toString());
        Veiculo v2;
        v2 = new MiniAutocarro(200);
        System.out.println(v2.toString());
    }
}

As interfaces:
é outra forma de trabalhar com classes abstractas
a interface pode conter: constantes, ou métodos
para definir uma classe que tem um ou mais interfaces, faz-se uso da expressão implements
os membros variáveis são implicitamente: public, final ou static (e é redundante usar estas expressões)
os métodos são public (e é redundante indicar)
uma classe só deriva de outra classe, e pode ter vários interfaces
várias classes podem implementar um interface

package e17;

interface Livro {
    void oLivro(int paginas);
}

interface Comic {
    void acerca(int paginas);
}

class Policial implements Livro {
    public void oLivro(int p) {
        System.out.println("\nChamada com " + p + " no Policial");
    }
    void maisInformacao() {
        System.out.println("\nOutras informacações no Policial");
    }
}

class Marvel extends Policial implements Comic{
    public void acerca(int p){
        System.out.println("\nOutras informacações na Marvel: " +p);
    }
}

public class e17 {
    public static void main(String args[]) {
        Marvel v = new Marvel();
        v.acerca(2);
        v.maisInformacao();
        
        Policial p = new Policial();
        p.oLivro(10);
        p.maisInformacao();
    }
}

Podem existir referências para um interface, é usado o mecanismo de polimorfismo, e nele podem ser referidos objetos de uma classe que o implementem, e faz uso apenas dos métodos da classe declarados na interface
se uma classe for interface, e não forem definidos todos os métodos que são abstractos, essa classe passa a ser abstracta

package e18;

interface Jogos {
    void precoJogos(int preco);
    void qualidadeJogos(int qualidade);
}

class jogoTabuleiro implements Jogos {
    public void precoJogos(int p) {
        System.out.print("\njogo de tabueliro" + p);
    }
    public void qualidadeJogos(int q) {
        System.out.print("\njogo de tabueliro" + q);
    }
}

abstract class jogoDigital implements Jogos {
    void oJogoDigital(int j) {
        System.out.print("\njogo de tabueliro" + j);
    }
}

class jogoDigitialOficial extends jogoDigital {

    public void oJogoDigital() {
        System.out.print("\njogo digital");
    }

    public void precoJogos(int preco) {
    }; //obrgatorio
    public void qualidadeJogos(int qualidade) {
    } //obrgatorio
}

public class e18 {
    public static void main(String args[]) {
        jogoDigitialOficial jd = new jogoDigitialOficial();
        jd.oJogoDigital();
    }
}

Nas interfaces podem surgir os métodos default
O default define uma implementação por omissão desse métodos, para todas as classes que implementam o interface e que não definam a sua própria implementação
Um método defualt não pode ser abstract nem static

package e19;

interface jogosDigitais {

    void contaJogadores(int n);

    default void precoAtual(int preco) {
        int conta = preco * 2;
        contaJogadores(conta); //pode fazer uso de outros métodos da interface
    }
}

class RTS implements jogosDigitais {

    private int jogadores;

    public void contaJogadores(int ct) {
        this.jogadores = ct;
    }
    
    //redefinição do métdo default
    public void precoAtual(int p){
        contaJogadores(10);
    }
    

    public String toString() {
        return "resultado " + jogadores;
    }
}

public class e19 {
    public static void main(String args[]) {
        jogosDigitais jd1 = new RTS();
        jd1.precoAtual(4);
        System.out.print(jd1);
        jd1.toString(); //nao entendo porque este método não é reproduzido
    }
}

Nas interfaces podem surgir os métodos static
um método static numa interface tem que definir uma implementação
não existe overide nas classes que implementam uma interface com métodos static
o static pode ser usado na interface, para incluir métodos utilitários

package e20;

interface Quadro {

    void ilustrar(int il);

    static void calculo(int valor) {
        valor = valor * 1;
    }
}

class corRGB implements Quadro {

    private int corRGB = 123;

    corRGB() {
        this.corRGB = corRGB;
    }

    public void ilustrar(int i) {
        this.corRGB = i * i * i;
    }

    public String toString() {
        return "do quadro surge " + corRGB;
    }
}

public class e20 {

    public static void main(String args[]) {
        Quadro q1 = new corRGB();
        q1.ilustrar(20);
        System.out.print(q1);
    }
}

Nas interfaces podem surgir constantes que são utilizadas, como utilitárias nas classes derivadas

package e21;

interface valores {
    int EURO = 2;
    int DOLAR = 1;
}

class banco implements valores {

    private int contas;

    banco() {
        this.contas = EURO + DOLAR;
    }
    public String toString() {
        return "das contas surge " + contas;
    }
}

public class e21 {

    public static void main(String args[]) {
        banco b1 = new banco();
        System.out.print(b1);
        b1.toString(); // não é executada e não compreendo do porquê!
    }
}

E também uma interface pode derivar de outras interfaces:
a interface derivada que tenha constantes com o mesmo nome da interface herdada, a que é herdade não é “escondida”
a interface derivada herda todos os métodos abstract e default
a interface derivada não herda os métodos que forem static

package e22;

interface Mae {

    int valor = 10;
    int total = -10;

    static int fala() {
        return valor * 2;
    }

    default int comida() {
        return valor * 3;
    }

    abstract int correr();
}

interface Pai {

    int valor = 20;
    int total = -20;

    static int fala() {
        return valor * 2;
    }

    default int comida() {
        return valor * 3;
    }

    abstract int correr();
}

interface Filha extends Pai, Mae {

    int comida();
}

class Neto implements Filha {

    public int comida() {
        return Mae.valor + Pai.total;
    }

    public int correr() {
        return Mae.total + Pai.valor;
    }
}

public class e22 {

    public static void main(String args[]) {
        Filha f1 = new Neto();
        System.out.println("estatico " + f1.correr()); //20
        System.out.println("estatico " + f1.comida());//-10

    }
}

Como sempre gostei de gráficos aqui fica:

+infos(fonte dos gráficos): LINK

Tags : , , ,