Explorando a herança na linguagem de programação Java
Herança é um dos principais conceitos da programação orientada a objetos. Em programação, a palavra herança representa um relacionamento no qual uma classe filha assume o estado e o comportamento de uma classe pai.
O objetivo da herança no desenvolvimento de software é facilitar a reutilização de software seguro e confiável. Um dos principais benefícios de usar herança é que ela elimina código redundante em seus programas.
Como funciona a herança
A ideia por trás da herança é que muitas classes ou objetos têm alguns do mesmo conjunto de atributos e métodos. Portanto, no espírito de produzir software confiável, novas classes agora podem ser extraídas de classes relacionadas pré-existentes e, se necessário, expandir os estados e comportamentos existentes.
Um exemplo do mundo real de como funciona a herança seria considerar frutas. Este é um rótulo amplo que serve para encapsular uma variedade de itens diferentes.
Uma maçã é uma fruta e uma laranja também. No entanto, uma laranja não é uma maçã, então você não teria frutas como um de seus itens de estoque se tivesse uma loja. Talvez você pudesse ter uma seção de frutas em seu inventário e, sob essa seção, itens mais específicos, como maçãs e laranjas.
É assim que funciona a herança.
Usando herança em Java
A herança pode ser usada em qualquer linguagem de programação que use o paradigma de programação orientado a objetos . No entanto, a maneira exata em que a herança é usada depende da linguagem de programação específica.
Por exemplo, C ++ também é uma linguagem de programação orientada a objetos . C ++ suporta o que é conhecido como herança múltipla, enquanto Java suporta apenas herança única.
O que isso significa é que em Java uma classe pai pode ter muitas classes filhas, mas cada classe filha só pode ter uma única classe pai (herança única). No entanto, existe uma maneira de obter herança múltipla indireta em Java, criando um relacionamento de avô, pai e filho.
Criação da classe pai em Java
O processo de seleção de uma classe pai de um documento de requisitos de software é conhecido como análise orientada a objetos. Durante este processo, a frase “é um” é freqüentemente usada para identificar possíveis relacionamentos de herança. Com base em nosso exemplo acima, você deve ser capaz de ver que a fruta seria nossa classe pai.
Exemplo de classe parente de frutas
public class Fruit {
//Variable Declaration
protected String seed;
protected String skinColor;
protected String taste;
//Default Constructor
public Fruit(){
seed = "";
skinColor ="";
taste ="";
}
//Primary Constructor
public Fruit(String seed, String skinColor, String taste){
this.seed = seed;
this.skinColor = skinColor;
this.taste = taste;
}
//getters and setters
public String getSeed() {
return seed;
}
public void setSeed(String seed) {
this.seed = seed;
}
public String getSkinColor() {
return skinColor;
}
public void setSkinColor(String skinColor) {
this.skinColor = skinColor;
}
public String getTaste() {
return taste;
}
public void setTaste(String taste) {
this.taste = taste;
}
//eat method
public void eat(){
//general code on how to eat a fruit
}
//juice method
public void juice() {
//general code on how to juice a fruit
}
}
Um dos aspectos mais notáveis da classe pai acima é o modificador de acesso que é usado com cada declaração de variável. O modificador de acesso “protegido” é ideal para uso em classes pai porque evita que classes não filhas obtenham acesso aos atributos de dados da classe pai.
Mais adiante no código, você é apresentado aos construtores, getters e setters que são blocos de construção gerais para qualquer classe Java. Finalmente, você será apresentado a dois métodos (suco e comer) que são criados na classe pai de nosso programa porque eles são universais para todas as frutas – todas as frutas podem ser comidas e espremidas.
Criação de classes filhas em Java
As classes filhas são geralmente chamadas de classes especializadas ou derivadas porque herdam o estado e o comportamento de um pai e geralmente personalizam esses atributos para serem mais específicos.
Continuando com nosso exemplo, você deve ser capaz de ver por que laranja seria uma classe infantil adequada da classe de frutas acima.
Exemplo de classe infantil laranja
public class Orange extends Fruit{
//variable declaration
private int supremes;
//default constructor
public Orange() {
supremes = 0;
}
//primary constructor
public Orange(String seed, String skinColor, String taste, int supremes){
super(seed, skinColor, taste);
this.supremes = supremes;
}
//getters and setters
public int getsupremes() {
return supremes;
}
public void setsupremes(int supremes) {
this.supremes = supremes;
}
//eat method
public void eat(){
//how to eat an orange
}
//juice method
public void juice() {
//how to juice and orange
}
//peel method
public void peel(){
//how to peel an orange
}
}
Há uma diferença entre a aparência de uma declaração de classe Java regular e o que temos em nosso código acima. A palavra-chave “extends” é usada em Java para tornar a herança possível.
Em nosso exemplo acima, a classe filha (laranja) estende a classe pai (fruta). Portanto, o estado e o comportamento da classe fruta agora podem ser acessados e modificados pela classe laranja.
O atributo único que nossa classe laranja possui é identificado com o nome de variável supremes (que é o nome oficial dos pequenos segmentos encontrados nas laranjas). É aqui que a especialização entra em jogo; nem todas as frutas têm supremas, mas todas as laranjas têm, portanto, reservar a variável supremas para a classe laranja é lógico.
Adicionar o método “descascar” aos métodos preexistentes “comer” e “sumo” também é lógico porque, embora nem todas as frutas possam ser descascadas, as laranjas costumam ser descascadas.
Você deve ter em mente que, se não pretendêssemos alterar os métodos existentes de “comer” e “suco”, não precisaríamos incluí-los em nossa classe de laranja. Os métodos da classe orange substituem qualquer método semelhante na classe fruit. Portanto, se todas as frutas fossem comidas e espremidas da mesma maneira, não precisaríamos criar esses métodos na classe laranja.
Os construtores de papéis desempenham na herança
Por padrão, os construtores da classe pai são herdados por classes filho. Portanto, se um objeto de classe filho for criado, isso significa que um objeto de classe pai também é criado automaticamente.
Voltando ao nosso exemplo, cada vez que um novo objeto laranja é criado, um objeto fruta também é criado porque uma laranja é uma fruta.
Nos bastidores, quando um objeto de classe filho é criado, o construtor da classe pai é chamado primeiro, seguido pelo construtor da classe filha. Em nossa classe filha laranja acima, se um objeto laranja for criado sem nenhum parâmetro, nosso construtor de classe de frutas padrão será chamado, seguido por nosso contratante de classe laranja padrão.
O método “super” em nosso construtor primário acima é necessário porque especifica que o construtor primário – e não o construtor padrão – da classe da fruta pai deve ser chamado sempre que um objeto laranja com parâmetros é criado.
Agora você pode usar herança em Java
Com este artigo, você aprendeu o que é herança, como funciona e por que é um conceito tão importante na programação. Agora você pode criar seus relacionamentos de herança usando a linguagem de programação Java. Além disso, agora você sabe como contornar a regra de herança única do Java criando um relacionamento de avós.
Crédito da imagem: Andreas Wohlfahrt / Pexels