:orphan:

Method parameters
=======================================

For one of the assignments, we developed a class called ``Window`` with methods that drew the following pattern::

  +===+===+
  |   |   |
  |   |   |
  |   |   |
  +===+===+
  |   |   |
  |   |   |
  |   |   |
  +===+===+
  
The class (`available on Github <https://github.com/lgreco/IntroProgramming/blob/main/Loops/src/Window.java>`__) uses methods ``frame`` and ``glassPanes`` to draw the ``+===+===+`` and ``|   |   |`` parts respectively. These methods rely on class constants that determine the ``SIZE`` of the shape (that looks like a `sash window <https://en.wikipedia.org/wiki/Sash_window>`__), and the symbols used to draw it. Character ``+`` is used as the ``CORNER`` element, ``=`` as the ``HORIZONTAL`` element, ``|`` as ``VERTICAL`` and the space as the ``GLASS`` element. Using these constants we developed loops based on the following observations.

The horizontal frame is derived by the following pattern:

.. math::

   \left( 2\ \text{times}\ \left( \texttt{CORNER}\ \text{followed by}\ \texttt{SIZE}\ \text{times}\ \texttt{HORIZONTAL} \right)\right) \  \text{followed by}\  \texttt{CORNER}

while the glassy part is generated by the pattern:

.. math::

   \left( 2\ \text{times}\ \left( \texttt{VERTICAL}\ \text{followed by}\ \texttt{SIZE}\ \text{times}\ \texttt{GLASS} \right)\right) \  \text{followed by}\  \texttt{VERTICAL}
   
There is similarity in these two patterns. Basically they are following the same formula:

.. math::

   \left( 2\ \text{times}\ \left( \texttt{C1}\ \text{followed by}\ \texttt{SIZE}\ \text{times}\ \texttt{C2} \right)\right) \  \text{followed by}\  \texttt{C1}
   
All that changes is the value of characters ``C1`` and ``C2``. These similar patterns are also evident in the code highlighted below.

.. code-block:: java
   :emphasize-lines: 2-8, 14-21

   public static void frame() {
     for (int pane = 0; pane < PANES; pane++) {
       System.out.print(CORNER);
         for (int i = 0; i < SIZE; i++) {
           System.out.print(HORIZONTAL);
         }
     }
     System.out.println(CORNER);
   }  


   public static void glassPanes() {
     for (int height = 0; height < SIZE; height++) {
       for (int pane = 0; pane < PANES; pane++) {
         System.out.print(VERTICAL);
         for (int i = 0; i < SIZE; i++) {
           System.out.print(GLASS);
         }
       }
     System.out.println(VERTICAL);
     }
   }  

In both methods above, the outer loop runs ``PANES`` times. The inner loop runs ``SIZE`` times. The only difference between them is the characters printed. Such similarity, in fact duplication of code, is an opportunity to simplify things. Simplification, here, means extracting the duplicate code in a separate method, and replace the code with that new method. The new method must recognize what characters we want to print. We provide that information as arguments when we call the method. The need for these arguments is specified in the method header as parameters.

Let's call the new method, that will simplify the code above, ``printCharacters``:

.. code-block:: java

   public static void printCharacters(char C1, char C2) {
     for (int pane = 0; pane < PANES; pane++) {
       System.out.print(C1);
       for (int i = 0; i < SIZE; i++) {
         System.out.print(C2);
       }
     }
     System.out.println(C1);
   }

Using this new method, we can simplify methods ``frame`` and ``glassPanes``:


.. code-block:: java
   :emphasize-lines: 2, 8

   public static void frame() {
     printCharacters(CORNER, HORIZONTAL);
   }  


   public static void glassPanes() {
     for (int height = 0; height < SIZE; height++) {
       printCharacters(VERTICAL, GLASS);
     }
   }  


So far we have been writing methods with no parameters, i.e., the name of the method was followed by an empty pair of parentheses. Only the main method had parameters passed to it. That was not our choice but a language requirement. Now, we begin to write methods, like ``printCharacters`` above that accept parameters. These parameters are listed in the method header. A *method parameter* is defined by its data type and an variable name. A method can have multiple parameters. Good design practices suggest a maximum of 5-10 parameters.

When we use a parametric method, we provide values that match the position and the data type of its parameters. These values are called the arguments of the call (to the method).

In the example above, the parameters of ``printCharacters`` are ``char C1`` and ``char C2``. When the method is called from within ``frame``, it is given the arguments ``CORNER`` and ``FRAME``. These arguments take the place of ``C1`` and ``C2`` respectively, as the called method is executed.

The name of the method together with the number of its parameters, their data types, and their order or appearance constitute the **signature of the method.** In the examples above, the signatures are as follows:

+---------------------+----------------------+--------------------------------------+
| method name         | number of parameters | types and order of appearance        |
+---------------------+----------------------+--------------------------------------+
| ``frame``           | 0                    |                                      |
+---------------------+----------------------+--------------------------------------+
| ``glassPanes``      | 0                    |                                      |
+---------------------+----------------------+--------------------------------------+
| ``printCharacters`` | 2                    | ``char``, ``char``                   |
+---------------------+----------------------+--------------------------------------+


