If only a Administrador
can create a Colaborador
, it means that no one else can create it, meaning its constructors can not be public. Remove the public
from the constructors of Colaborador
and its subclasses:
public abstract class Colaborador extends Funcionario {
// construtor sem "public"
Colaborador(String nome, String cpf) {
super(nome, cpf);
}
}
public class Entregador extends Colaborador {
// construtor sem "public"
Entregador(String nome, String cpf) {
super(nome, cpf);
}
}
Thus, only classes within the same package "see" the constructors. And since Administrador
is the only one that can create these classes and it's in the same package ( com.trabalho1
), that's exactly what we need.
So, the only point at which a Colaborador
can be created is within classes that are in the same package - and Administrador
is one of them. And if only Administrador
can create these classes, then you create a public method in this class, which will be responsible for creating collaborators.
In addition, Colaborador
is an abstract class, and you can not instantiate it. We can only instantiate its subclasses. So one way to do it would be to have a method that would receive the type of collaborator to be instantiated, in addition to the information needed to build it (in this case, the name and CPF).
In the example below I'm using int
as the type of collaborator, but in those cases I prefer to use a enum
(as I do not know if you already know enum
, I'll leave the example with int
first ):
public class Administrador extends Funcionario {
public Colaborador criaColaborador(int tipo, String nomeColaborador, String cpfColaborador) {
if (tipo == 1) {
return new Entregador(nomeColaborador, cpfColaborador);
} else if (tipo == 2) {
// retorna outro tipo de colaborador (Secretaria, Gerente, etc)
}
// vários if's, para cada tipo de colaborador
// tipo desconhecido, retorna null (ou algum valor default)? lança exception? você decide
return null;
}
}
If you already know enum
, it looks like this:
public enum TipoColaborador {
SECRETARIA, GERENTE_VENDA, ENTREGADOR;
}
public class Administrador extends Funcionario {
public Colaborador criaColaborador(TipoColaborador tipo, String nomeColaborador, String cpfColaborador) {
if (tipo == TipoColaborador.ENTREGADOR) {
return new Entregador(nomeColaborador, cpfColaborador);
} else if (tipo == TipoColaborador.GERENTE_VENDA) {
// retorna outro tipo de colaborador (Secretaria, Gerente, etc)
}
// vários if's, para cada tipo de colaborador
// retorna null (ou algum valor default)? lança exception? você decide
return null;
}
}
I prefer to use enum
because this makes it clear which values can be passed in the type. If I use int
, I can inadvertently pass some number that has nothing to do with the type, for example.
Remembering that this is just a way to do it. It is also possible to have a method for each type ( criarEntregador
, criarSecretaria
, etc), use Map
to map types and their classes ( Map<TipoColaborador, Class<? extends Colaborador>>
), among others (besides the obvious "use% instead of switch
", if you already know).
But the general idea for your problem is this. By not letting the class have public constructors, you limit and control who can create instances of it. In this case, the only place these constructors are called is in the public method which is in if
, which means that only this class can create instances of Administrador
.
To create your instances, it would look like this:
Administrador admin = new Administrador("Admin", "12345678909");
Colaborador col = admin.criaColaborador(TipoColaborador.ENTREGADOR, "Fulano de Tal", "11122233396");