There are many situations where you need to extend certain functionality of an existing class. There may be several specializations for a particular behavior.
Of course, this can be done by simply changing the original class, perhaps by setting if
to each new situation that arises.
But this is not good practice from a modeling point of view. The code is getting confusing and the chance of new errors appearing is great.
In an ideal class model you would never need to change an existing class to add new functionality or more specific behavior. It would suffice to extend a class.
Although there are several practical examples, not all of them work out of context. I'll work with some below.
Practical constructor example
Suppose you have class Pessoa
:
class Pessoa
def initialize(nome)
@nome = validarNome(nome)
end
def validarNome(nome)
...
end
end
And now a specialization PessoaFisica
:
class PessoaFisica < Pessoa
def initialize(nome, cpf)
super(nome)
@cpf = validarCpf(cpf)
end
def validarCpf(cpf)
...
end
end
And one more level of expertise Funcionario
:
class Funcionario < PessoaFisica
def initialize(nome, cpf, pis)
super(nome, cpf)
@pis = validarPis(pis)
end
def validarPis(pis)
...
end
end
In the examples above, the superclass constructor takes care of the validation of the attribute it has.
Subclasses add new attributes and invoke the constructor of their superclass by delegating the initialization and validation of inherited attributes.
This is a way to maintain existing functionality, add new features and ensure the correct behavior of the program by reusing what already exists, without duplicating code.
Example of a "decorative" method
Imagine that you have a class that returns a message:
class GeradorMensagem
def getMensagem
"Olá mundo!"
end
end
Now you need to create a specialization of this message for display on a web page. It could do something like:
class GeradorMensagemHtml < GeradorMensagem
def getMensagem
"<div>" + super + "</div>"
end
end
Example of specialized behavior
Given a class Cliente
like this:
class Cliente
def limiteCredito
#consulta limite de crédito
end
end
There may be ClienteEspecial
which, in addition to the normal limit, has a special value. The limit would then be the sum of both. Let's see how this can be implemented with reuse:
class ClienteEspecial < Cliente
def limiteCreditoEspecial
#consulta limite de crédito especial
end
def saldo
limiteCredito + limiteCreditoEspecial
end
end