Herança e Composição/Exercício 02: Porta AND Ternária

From Wiki**3

Problema

Defina uma nova classe que represente uma porta lógica AND com três entradas. Esta classe deve chamar-se AndGate3 e apresenta a mesma funcionalidade que a de duas entradas. A apresentação (toString) é A: valor B: valor C: valor.

A classe AndGate3 deve ser definida reutilizando o conceito AndGate2 (definido no Exercício 1).

Adapte a função main definida anteriormente, por forma a integrar alguns testes com a nova porta lógica.

Solution 1: AndGate3i defined as a subclass of AndGate2

In this solution we observe that the operation is a specialization of the previous one. This allows us to reuse the previous functionality.

'Ficheiro AndGate3i.java'
/** Logical AND gate (inheritance). */
public class AndGate3i extends AndGate2 {
	/** A new input is needed (the other two are inherited). */
	private boolean _c = false;

	/**
	 * Default constructor: false for all inputs.
	 */
	public AndGate3i() {
		//super(); //default: explicit call not needed
	}

	/**
	 * Inputs receive same value.
	 * 
	 * @param v
	 *            the input value.
	 */
	public AndGate3i(boolean v) {
		super(v);
		_c = v;
	}

	/**
	 * Arbitrary input value combinations.
	 * 
	 * @param a
	 *            input value
	 * @param b
	 *            input value
	 * @param c
	 *            input value
	 */
	public AndGate3i(boolean a, boolean b, boolean c) {
		super(a, b);
		_c = c;
	}

	/**
	 * @return third input value.
	 */
	public boolean getC() {
		return _c;
	}

	/**
	 * Set input value.
	 * 
	 * @param c
	 *            input value.
	 */
	public void setC(boolean c) {
		_c = c;
	}

	/**
	 * @return value of logical AND operation.
	 */
	@Override
	public boolean getOutput() {
		return super.getOutput() && _c;
	}

	/**
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object other) {
		if (other instanceof AndGate3i) {
			AndGate3i andGate = (AndGate3i) other;
			return super.equals(other) && _c == andGate.getC();
		}
		return false;
	}

	/**
	 * @see java.lang.Object#toString()
	 */
	@Override
	@SuppressWarnings("nls")
	public String toString() {
		return super.toString() + " C:" + _c;
	}
}

Solução 2: AndGate3c defined as a composition of two AndGate2

In this solution, the 3-input gate is defined as a composition of 2-input gates. Note that the A-input of the second gate is updated whenever the inputs of the first gate are changed.

'Ficheiro AndGate3c.java'
/** Logical AND gate with 3 inputs (composition). */
public class AndGate3c {
	/** The first gate takes inputs 'a' and 'b' */
	private AndGate2 _gate1;

	/**
	 * The second gate takes as inputs the output of the first gate (input 'a')
	 * and 'c' (input 'b')
	 */
	private AndGate2 _gate2;

	/**
	 * Default constructor: false for all inputs.
	 */
	public AndGate3c() {
		_gate1 = new AndGate2();
		_gate2 = new AndGate2(_gate1.getOutput(), false);
	}

	/**
	 * Inputs receive same value.
	 * 
	 * @param v
	 *            the input value.
	 */
	public AndGate3c(boolean v) {
		_gate1 = new AndGate2(v);
		_gate2 = new AndGate2(_gate1.getOutput(), v);
	}

	/**
	 * Arbitrary input value combinations.
	 * 
	 * @param a
	 *            input value
	 * @param b
	 *            input value
	 * @param c
	 *            input value
	 */
	public AndGate3c(boolean a, boolean b, boolean c) {
		_gate1 = new AndGate2(a, b);
		_gate2 = new AndGate2(_gate1.getOutput(), c);
	}

	/**
	 * @return first input value.
	 */
	public boolean getA() {
		return _gate1.getA();
	}

	/**
	 * Set input value.
	 * 
	 * @param a
	 *            input value.
	 */
	public void setA(boolean a) {
		_gate1.setA(a);
		_gate2.setA(_gate1.getOutput());
	}

	/**
	 * @return second input value.
	 */
	public boolean getB() {
		return _gate1.getB();
	}

	/**
	 * Set input value.
	 * 
	 * @param b
	 *            input value.
	 */
	public void setB(boolean b) {
		_gate1.setB(b);
                _gate2.setA(_gate1.getOutput());
	}

	/**
	 * @return second input value.
	 */
	public boolean getC() {
		return _gate2.getB();
	}

	/**
	 * Set input value.
	 * 
	 * @param c
	 *            input value.
	 */
	public void setC(boolean c) {
		_gate2.setB(c);
	}

	/**
	 * Since the two gates are always kept in sync, we only need to ask for the
	 * output of the second gate.
	 * 
	 * @return value of logical AND operation.
	 */
	public boolean getOutput() {
		return _gate2.getOutput();
	}

	/**
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object other) {
		if (other instanceof AndGate3c) {
			AndGate3c ag = (AndGate3c) other;
			return getA() == ag.getA() && getB() == ag.getB() && getC() == ag.getC();
		}
		return false;
	}

	/**
	 * @see java.lang.Object#toString()
	 */
	@Override
	@SuppressWarnings("nls")
	public String toString() {
		return "A:" + getA() + " B:" + getB() + " C:" + getC();
	}
}