Herança Herança Mecanismo que permite criar novas classes a partir de classes existentes Classe herdeira possui os atributos e métodos da classe herdada Pode acrescentar novos atributos e métodos Pode sobrescrever métodos da classe ascendente Herança Para criar classes derivadas, utiliza-se a palavra reservada extends Exemplo: public class CarroLuxo extends Carro { … } Herança public class Carro { public class CarroLuxo extends Carro { int velocidade; boolean motor; public void acelerar(){ velocidade += 2; } public void ligar(){ } motor = true; } public void acelerar(){ velocidade++; } } Herança Não há limite para hierarquia de herança public class Carro { } public class CarroLuxo extends Carro { } public class CarroInvisivil extens CarroLuxo { } Em Java não existe herança múltipla public class CarroInvisivil extends Veiculo, Aparelho { } Herança Pode haver hierarquias complexas Termos Termos frequentemente usados: Classe base Classe derivada Classe mãe Classe filha Superclasse Subclasse Classe ascendente Classe herdeira Classe genérica Classe específica Sobrescrita A classe herdeira possui “automaticamente” todos os atributos e métodos da classe base Se um atributo ou método for escrito novamente, ele sobrescreve o método da classe base Sobrescrever != sobrecarregar Sobrescrever == sobrepor == override Métodos sobrepostos fazem a mesma tarefa, de um jeito diferente Sobrescrita A assinatura do método sobrescrito deve ser idêntica a do método definido na classe base Método na classe base public void acelerar(int vezes) { … } Método na classe derivada public void acelerar(int vezes) { … } Sobrescrita O modificador e o tipo de retorno podem ser diferentes No entanto, o método da subclasse só pode dar acesso mais amplo e nunca mais restrito Válido – Classe base • – void acelerar( ) {...} Classe derivada • public void acelerar( ) {…} Sobrescrita (cont.) Inválido – Classe base • – public void acelerar( ) {...} Classe derivada • void acelerar( ) {…} Sobrescrita Pergunta: isso pode? Classe base – private void acelerar( ) {...} Classe derivada – public void acelerar( ) {…} Sobrescrita Pergunta: isso pode? Classe base – private void acelerar( ) {...} Classe derivada – public void acelerar( ) {…} Métodos privados não são herdados, portanto este não é um caso de sobrescrita Sobreposição de método public class Carro { public class CarroLuxo extends Carro { int velocidade; boolean motor; public void acelerar(){ velocidade += 2; public void ligar(){ motor = true; } public void acelerar(){ velocidade++; } } } } Construtores Construtores não são herdados, mas são chamados automaticamente quando um objeto da classe filha é instanciado Se um construtor da classe mãe não for chamado explicitamente, o construtor padrão ou o construtor que não recebe argumentos é chamado Para escolher o construtor ou chamar explicitamente, usa-se a palavra reservada super Construtores Classe base não tem construtor Ao instanciar objeto da subclasse, o construtor default é chamado public class Carro { int velocidade; boolean motor; //demais métodos } public class CarroLuxo extends Carro { ArCondicionado arCondicionado; public CarroLuxo( ){ arCondicionado = false; } Construtores Classe base tem construtor “void” Ao instanciar objeto da subclasse, o construtor void é chamado public class Carro { int velocidade; boolean motor; public Carro(){ velocidade =0; motor = true; } public class CarroLuxo extends Carro { ArCondicionado arCondicionado; public CarroLuxo( ){ arCondicionado = true; } Construtores Classe base tem mais de um construtor Ao instanciar objeto da subclasse, o construtor void é chamado public class Carro { int velocidade; boolean motor; public Carro(){ velocidade =0; motor = true; } public Carro(int vel, boolean mot){ Velocidade = vel; motor = mot; } public class CarroLuxo extends Carro { ArCondicionado arCondicionado; public CarroLuxo( ){ arCondicionado = true; } Construtores Classe base tem mais de um construtor O construtor da subclasse pode escolher qual construtor será chamado public class Carro { int velocidade; boolean motor; public Carro(){ velocidade =0; motor = true; } public Carro(int vel, boolean mot){ Velocidade = vel; motor = mot; } public class CarroLuxo extends Carro { ArCondicionado arCondicionado; public CarroLuxo( ){ super(); arCondicionado = true; } Construtores O construtor da subclasse pode escolher qual construtor será chamado Outro exemplo: public class Carro { int velocidade; boolean motor; public Carro(){ velocidade =0; motor = true; } public Carro(int vel, boolean mot){ Velocidade = vel; motor = mot; } public class CarroLuxo extends Carro { ArCondicionado arCondicionado; public CarroLuxo( ){ super(0, true); arCondicionado = true; } Herança - recapitulando As classes derivadas são um subtipo da classe base – Aplicação da herança – Relação “é um” Reuso de implementação Produz relacionamento estático entre as classes – Alteração na superclasse afeta todos os objetos Superclasse Cósmica Object Todas as classes são derivadas da superclasse predefinida Object Object é a classe mais ancestral de todas (raiz da hierarquia) Não é necessário a palavra extends para que a classe herde de Object Superclasse Cósmica Object A nossa classe Carro possuiu o método toString( ), mesmo que não o tenhamos escrito, pois foi herdado de Object Assim: Carro c = new Carro( ); System.out.println(c.toString( )); Herança - Modificador private Atributos private – São herdados mas não são acessíveis na subclasse – Podem ser acessados por métodos público herdados (gets e sets) Métodos private – Não são herdados Herança - Modificador protected O modificador protected é muito relacionado à herança Protected está entre o modificador public e o modificador default Define – Acesso de pacote – Acesso por subclasses, estejam ou não no mesmo pacote Referências Uma referência da superclasse pode ser instanciada com um objeto da classe derivada Carro c = new CarroLuxo(); No entanto, não é possível chamar métodos da classe derivada utilizando a referência c.ligarAr( ); //erro Referências Uma referência da subclasse não pode ser instanciada com um objeto da classe derivada CarroLuxo c = new Carro(); //erro No entanto, é possível fazer casting CarroLuxo c = (CarroLuxo) new Carro(); Exercício Crie uma classe Veiculo que tenha os atributos placa, marca, modelo, ano e valor de mercado e métodos acessores e modificadores além de um método chamado toString( ) que retorna os valores dos atributos. Crie subclasses Automovel e Motocicleta. Para automóveis, armazene a quantidade de portas. Para motocicletas, armazene a quantidade de cilindradas. Crie um método calcularIpva( ): – 3,5% do valor de mercado para veículos – 2,5% do valor de mercado para motocicletas – Se automóvel com mais de 20 anos, ele é Modificadores static e final Modificador static faz com que o atributo e método seja da classe e não da instância Exemplo: public class Conta { static int sequencia; // variável de classe int numero; //variável de instância ... Modificador static Um atributo static é compartilhado por todas as instâncias da classe Exemplo Conta c1 = new Conta( ); Conta c2 = new Conta( ); c1.sequencia = 2; System.out.println(c2.sequencia); // imprime 2 Modificador static Um atributo static geralmente é chamado a partir da classe, e não a partir do objeto Exemplo Conta.sequencia = 2; Modificador static Um método static é um método de classe Podem ser chamados a partir da classe ou de um objeto Geralmente é chamado a partir da classe, e não a partir do objeto Exemplo Classe.metodoX( ); Modificador final O modificador final aplicado a uma classe não permite que ela seja herdada por outra classe O modificador final aplicado a um método, não permite que ele seja herdado por uma subclasse O modificador final aplicado a um atributo não permite que seu valor seja alterado (atribuído mais de uma vez) Modificador final (cont.) Exempo: public class Carro { final int VEL_MAX = 240; public void setVEL_MAX( ) { VEL_MAX = 250; //erro Modificador final (cont.) Isto é válido: public class Carro { final int VEL_MAX=0; public Carro ( ) { VEL_MAX = 240; } Modificador final (cont.) Na prática: public class Carro { public static final int VEL_MAX = 250; O modificador static é colocado para frisar que trata-se de uma constante da classe Além de não poder ser modificado, pode ser acessado sem instanciar um objeto