Segui i seguenti esempi, che sono stati abbreviati:
BasicButton:
public class BasicButton
{
private var m_fOnClick:Function;
public function BasicButton(pOnClick:Function)
{
m_fOnClick = pOnClick;
}
.
.
.
// when the button has been clicked:
m_fOnClick();
.
.
.
}
DirectionalButton:
public final class DirectionalButton extends BasicButton
{
private var m_eDirection:int;
private var m_fOnClick:Function;
public function DirectionalButton(pDirection:int, pOnClick:Function)
{
m_eDirection = pDirection;
m_fOnClick = pOnClick;
super(onClick);
}
private function onClick():void
{
m_fOnClick(m_eDirection);
}
}
La lista dei parametri del callback è una violazione del Principio di sostituzione di Liskov? So che i costruttori non lo violano, a seconda del modo in cui il settore interpreta questo principio, ma se fare casino con la lista dei parametri del callback costituisce una mutazione di un output comune o qualsiasi cosa sembra essere un po 'meno chiara.
Da un lato, entrambe le classi utilizzano una funzione chiamata pOnClick
che viene chiamata ogni volta che viene cliccato e il codice di creazione dell'istanza è in grado di passare in qualsiasi funzione a cui si vuole riferire pOnClick
. D'altra parte, poiché i costruttori tendono ad essere astratti da LSP, questi due parametri di pOnClick
nei due costruttori potrebbero essere interpretati come riferiti a cose molto diverse.
Anche se i due parametri pOnClick
sono interpretati come due input separati, c'è ancora qualche ambiguità su quanto il pOnClick
delle sottoclassi effettivamente sovrascriva o distrugge la superclasse (in un senso strettamente virtuale, pubblicamente esposto), e come molto invece semplicemente passa - in un senso molto virtuale - l'equivalente di null
al% ancora esistente della superclassepOnClick
.
È un po 'difficile trovare le parole esatte per quello che sto descrivendo, ma in generale, dove si trova LSP in questo? Questa è una violazione? In tal caso, si può rimediare semplicemente riscrivendo DirectionalButton.onClick
come segue?
private function onClick():void
{
try
{
m_fOnClick(m_eDirection);
}
catch (e:Error)
{
m_fOnClick(); // This is not how I would set this up in real life.
}
}