I know how to implement and use the interfaces, but I can not understand why they exist in C # or Java, since once you extend your class to an interface you need to implement all methods of the interface.
I know how to implement and use the interfaces, but I can not understand why they exist in C # or Java, since once you extend your class to an interface you need to implement all methods of the interface.
Programming facing the interface requires abstracting the idea of implementation. I'll try to summarize it in a very simplistic way:
public class Empresa {
public void efetuaPagamento(CNPJ cnpj, double valor){
String cnpj = cnpj.getNumero();
...
}
public void efetuaPagamento(CPF cpf, double valor){
String cnpj = cpf.getNumero();
...
}
}
The Company class is coupled to NPCs and CPFs. For each new document type, you need to copy the method. To avoid this, we can create an interface.
public interface Documento {
public String getNumero();
}
And then classes can implement them.
public class CNPJ implements Documento {
public String getNumero(){
//implementação
}
public void validaCNPJ(String cnpj){
//implementação
}
}
public class CPF implements Documento {
public String getNumero(){
//implementação
}
public void validaCPF(String cpf){
//implementação
}
}
Simplifying the Enterprise class
public class Empresa {
public void efetuaPagamento(Documento documento, double valor){
String documento = documento.getNumero();
...
}
}
Do not get too attached to the content of the examples, the point is to understand that any change in the implementation will be done in a single point (CNPJ or CPF classes). The Enterprise class is unbound , so it only matters to receive the document number, regardless of the document type. In addition to any new document, simply create a class and implement the Document, which will not affect the Enterprise class at all.
Basically, an interface is a contract, usually established for use between two distinct components, such as a system and a library, for example, or to reduce restrictions on the use of objects.
There are several uses. One of the most interesting is IEnumerable<T>
in C #. The implementation of an enumeration may not be an object, but a generating function. Multiple objects implement IEnumerable<T>
, such as List<T>
, arrays
, Collection<T>
, Queue<T>
, Stack<T>
, and any function whose return is based on yield return
, which accumulates multiple object returns that result in an enumeration by the calling method. This is a case of restriction reduction: when I declare:
IEnumerable<Objeto> lista;
I can assign it any of the objects already mentioned:
lista = new List<Objeto>();
lista = new Collection<Objeto>();
lista = new Queue<Objeto>();
lista = new Stack<Objeto>();
lista = new Objeto[10];
lista = MinhaFuncaoComYieldReturn();
public static IEnumerable<Objeto> MinhaFuncaoComYieldReturn()
{
for (var i = 0; i <= 10; i++)
yield return new Objeto();
}
In addition, Java and C # are two languages that do not support multiple inheritance. Interfaces are a good way of ensuring that a class is a composition of several different implementations.
An emblematic case of this is the SortedDictionary<TKey, TValue>
class, also from C # :
public class SortedDictionary<TKey, TValue> : IDictionary<TKey, TValue>,
ICollection<KeyValuePair<TKey, TValue>>, IEnumerable<KeyValuePair<TKey, TValue>>,
IEnumerable, IDictionary, ICollection, IReadOnlyDictionary<TKey, TValue>,
IReadOnlyCollection<KeyValuePair<TKey, TValue>>
It needs to be a dictionary, an enumeration, a collection, support sorting, and still have read-only methods. This ensures a large number of uses of the same data structure.
Java works the same way.
Finally, it's still worth talking about switching components. Suppose for example that we have a class implemented in a library that for some reason we no longer want to use it:
public class ClasseDaBibliotecaASerRetirada
{
public void Metodo1(int i, int j) { ... };
public int Metodo2() { ... };
public int[] Metodo3(params int[] parametros) { ... };
}
We can extract the interface from it:
public interface IClasseDaBibliotecaASerRetirada
{
void Metodo1(int i, int j) { ... };
int Metodo2() { ... };
int[] Metodo3(params int[] parametros) { ... };
}
And implement another class, without much modification of code dependent on this class:
public class MinhaNovaClasse : IClasseDaBibliotecaASerRetirada
{
public void Metodo1(int i, int j) { ... };
public int Metodo2() { ... };
public int[] Metodo3(params int[] parametros) { ... };
}