Assuming it's a legacy project that you can not change the class hierarchy without a big impact, I suggest you apply the design pattern: VISITOR.
The intent of VISITOR is to allow you to define a new operation for a hierarchy without changing the hierarchy classes. [ Steven John Metsker, William C. Wake - 2006 , 340 p.]
Trying to respond: Why is the function countingLicensingList is returning 0 . Well, I believe it's because in the hierarchy the parent class does not know what their daughter classes are, but the children know what the father is. The child class has to behave like the parent class:
The Liskov Replacement Principle
New classes must be logical, consistent extensions of their super-classes, but what does it mean to be logical and consistent? A Java compiler will ensure a certain level of consistency, but many principles of consistency will dodge a compiler. One rule that can help improve your projects is the Liskov Substitution Principle [Liskov, Barbara, 1987], which can be paraphrased as follows: An instance of a class should function as an instance of its superclass . [ Steven John Metsker, William C. Wake - 2006 , 295 p.]
No more theory, now in practice:
public interface AlunoVisitor {
void visit(AlunoLicenciatura al);
}
Student.java
public class Aluno {
private int numero;
private String nome;
private boolean isAlunoLicenciatura = false;
public Aluno(){
this.nome="";
this.numero=0;
}
public Aluno(int numero,String nome){
this.nome=nome;
this.numero=numero;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof Aluno) {
Aluno aluno = (Aluno)obj;
if (aluno.numero == this.numero)
return true;
}
return false;
}
protected boolean isAlunoLicenciatura() {
return isAlunoLicenciatura;
}
protected void setAlunoLicenciatura(boolean isAlunoLicenciatura) {
this.isAlunoLicenciatura = isAlunoLicenciatura;
}
}
StudentLicenciatura.java
public class AlunoLicenciatura extends Aluno
implements AlunoVisitor {
private String curso;
private ArrayList<Disciplina> l_dis;
public AlunoLicenciatura(String curso,Aluno a){
super(a.getNumero(),a.getNome());//recebe o numero e o nome de aluno do objecto do tipo aluno ,neste caso, a1 de acordo com o main
this.curso=curso;
this.l_dis=new ArrayList<Disciplina>();
this.visitor(a);
}
@Override
public void visitor(Aluno a) {
a.setAlunoLicenciatura(true);
}
}
P8.java
public class P8 {
public static int contaAlunosLicenciatura(ArrayList<Aluno> a){
int c=0;
for (int i = 0; i < a.size(); i++) {
Aluno aluno = a.get(i);
if(aluno.isAlunoLicenciatura())
c++;
}
return c;
}
public static void main(String[] args) {
Aluno a1 = new Aluno (1, "Gervasio");
Aluno a3 = new Aluno ();
Aluno a4 = new Aluno ();
AlunoLicenciatura al1 = new AlunoLicenciatura("Curso1",a1);
ArrayList<Aluno> v=new ArrayList<Aluno>();
v.add(a1);
v.add(a3);
v.add(a4);
int Stlicen=contaAlunosLicenciatura(v);
System.out.println(Stlicen);
}
}
Important to keep in mind the following:
The VISITOR is a controversial standard. Some developers consistently avoid applying it, while others advocate its use and suggest ways to strengthen it, although such suggestions often add complexity. The fact is that many design problems can follow the VISITOR standard. [ Steven John Metsker, William C. Wake - 2006 , 353 p.]
NOTE : The above suggestion is one of many possible. I know it can add complexity, but implementing a design pattern requires an impact analysis and the associated cost benefits. Do not implement a standard just to implement.
NOTE-2 : Note that I did not implement the function: accept(AlunoVisitor al)
in class AlunoLicenciatura
. This was because it would not make the class Aluno
abstract. This would imply a very large change in the solution and assuming we have access restrictions.
Reference :
[Steven John Metsker, William C. Wake - 2006], Addison-Wesley Professional; 2 edition (April 18, 2006), DESIGN PATTERNS IN JAVATM : Software Patterns Series .
[Liskov, Barbara, 1987]. Data Abstraction and Hierarchy. SIGPLAN Notices, volume 23, number 5. May 1987.