Open jemluz opened 10 months ago
Temos uma classe genérica (mais para o topo da hierarquia) chamada Pessoa. E duas classes especializadas (mais para a base da hierarquia) chamadas, Professor e Aluno.
Tanto a classe Professor, quanto Aluno, herdam as características da classe Pessoa.
package people;
// This is a basic example about classes and objects
public class People {
// must has an name, old and id
String name;
int old;
String id;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getOld() {
return old;
}
public void setOld(int old) {
this.old = old;
}
String showMeThisPerson() {
return "This is " + name + ", she/he has " + old + " years old and her/his ID is " + id;
}
}
package people;
public class Teacher extends People {
private String salary;
public String getSalary() {
return salary;
}
public void setSalary(String salary) {
this.salary = salary;
}
}
package people;
public class Student extends People {
private String matricullation;
public String getMatricullation() {
return matricullation;
}
public void setMatricullation(String matricullation) {
this.matricullation = matricullation;
}
}
package people;
public class TestPeople {
public static void main(String[] args) {
// instance of People class
People peopleObjectP1 = new People();
peopleObjectP1.name = "John Doe";
peopleObjectP1.old = 32;
peopleObjectP1.id = "000.000.000-01";
System.out.println(peopleObjectP1);
System.out.println(peopleObjectP1.showMeThisPerson());
People peopleObjectP2 = new People();
peopleObjectP2.name = "Mary Jane";
peopleObjectP2.old = 22;
peopleObjectP2.id = "000.000.000-02";
System.out.println(peopleObjectP2);
System.out.println(peopleObjectP2.showMeThisPerson());
// instance of teacher
Teacher teacherObj1 = new Teacher();
// People teacherObj1 = new Teacher();
teacherObj1.setId("000.000.000-03");
teacherObj1.setName("Carlitos");
teacherObj1.setOld(28);
teacherObj1.setSalary("28.000");
// instance of student
Student studentObj1 = new Student();
// People teacherObj1 = new Teacher();
studentObj1.setId("000.000.000-03");
studentObj1.setName("Carlitos");
studentObj1.setOld(28);
studentObj1.setMatricullation("823741");
}
}
Muitos dos métodos dos carros são comuns em vários automóveis. Tanto um carro quanto uma motocicleta são classes cujos objetos podem acelerar, parar, acender o farol etc, pois são coisas comuns a automóveis. Podemos dizer, então, que ambas as classes "carro" e "motocicleta" são "automóveis".
Utilizamos uma interface para definir um contrato, e isso é o que uma classe já faz, porem a interface faz de modo mais subjetivo ainda. Pois a interface não permite a criação de instancias como a classe permite.
Então é como se a interface fosse mais um lembrete, uma régua para definir com mais rigidez o conteúdo de uma classe. Como se a interface obrigasse a classe a obedecê-la.
Gosto de pensar na classe como um tipo de dado complexo, em contraponto aos tipos de dados primitivos. Já que quando você declara a variavel de um tipo, ela é obrigada a obedecer a forma desse tipo. E da mesma forma quando você declara uma classe que implementa uma interface, ela é obrigada a obedecer a forma daquela interface.
Quando falamos de classes que irão usar interfaces como referência na sua declaração, não usamos o termo herança, e sim o termo implementação. Mas mas mas, uma interface pode herdar de outra interface, criando uma hierarquia de interfaces.
Isso se reflete no uso da palavra reservada implements
no lugar de extends
na hora de vincular uma classe a uma interface
public interface Automovel {
void acelerar();
void frear();
void acenderFarol();
}
public class Carro implements Automovel {
/* ... */
@Override
public void acelerar() {
this.mecanismoAceleracao.acelerar();
}
@Override
public void frear() {
/* código do carro para frear */
}
@Override
public void acenderFarol() {
/* código do carro para acender o farol */
}
/* ... */
}
public class Moto implements Automovel {
/* ... */
@Override
public void acelerar() {
/* código específico da moto para acelerar */
}
@Override
public void frear() {
/* código específico da moto para frear */
}
@Override
public void acenderFarol() {
/* código específico da moto para acender o farol */
}
/* ... */
}
class Automovel():
def acelerar(self):
raise NotImplementedError()
def frear(self):
raise NotImplementedError()
def acenderFarol(self):
raise NotImplementedError()
class Carro(Automovel):
# ...
def acelerar(self):
# Codigo para acelerar o carro
def frear(self):
# Codigo para frear o carro
def acenderFarol(self):
# Codigo para acender o farol do carro
# ...
class Moto(Automovel):
# ...
def acelerar(self):
# Codigo para acelerar a moto
def frear(self):
# Codigo para frear a moto
def acenderFarol(self):
# Codigo para acender a moto
# ...
Sucessão patrimonial entre as classes
Quando dizemos que uma classe A é um tipo de classe B, dizemos que a classe A herda as características da classe B e que a classe B é mãe da classe A, estabelecendo então uma relação de herança entre elas.
No caso do carro, dizemos então que um Honda Fit "Cross" é um tipo de Honda Fit, e o que muda são alguns atributos (paralama reforçado, altura da suspensão etc), e um dos métodos da classe (acelerar, pois agora há tração nas quatro rodas), mas todo o resto permanece o mesmo, e o novo modelo recebe os mesmos atributos e métodos do modelo clássico.
Exemplo em Java
Exemplo em Python