How to Implement Undo/Redo in Java

Undoing and redoing can be implemented in your programs by using the Command pattern. The Command pattern is a design pattern where objects represent commands. That is, objects contain some statements to be executed. These statements operate on some data to change its state.

To add undo functionality, add another set of statements changing the state of the data to the way it was before. This is easy to do and can be done in a few steps.

 

1.     Make an interface with two methods, undo() and redo().

Example:

interface UndoableCommand
 {
        void undo();
        void redo();
 }

 

2.     Create a class implementing it, which does your desired command. For example, UndoableListAdd, which undoes adding to a List. Any command you wish is acceptable, except that the data that is operated on must be mutable (that is, objects and not primitives).

Example: a class that will erase an element from an array, with what variables it should hold.

class UndoableErase implements UndoableCommand
 {
        //variables saving array, index to erase, and element.
        Object[] array;
        int index;
        Object oldval;
 }

 

3. In constructor, assign the data to instance variable(s).

Example: the constructor for my class would save array and its state details of old element and index to erase and apply erase operation (unset array slot at index). It takes an array and an index as arguments to the constructor.

        UndoableErase(Object[] array, int index)
        {
               //save the array and index to erase.
               this.index = index;
               this.array = array;
               this.oldval = array[index];
 
               //erase.
               array[index] = null;
        }

 

4. In undo(), set saved data to its old state (before the command).

Example: the undo() command for my class sets the array to old state (set element at index to old element).

        public void undo()
        {
               array[index] = oldval;
        }

 

5. In redo(), set saved data to its new state (after the command).

Example: the redo() for my class would set the array to new state (unset array slot at index).

        public void redo()
        {
               array[index] = null;
        } 

(Note: executing the command is the same as calling redo())

My example put together looks like this:

class UndoableErase implements UndoableCommand
 {
        //fields saving array, index to erase, and element.
        Object[] array;
        int index;
        Object oldval;
 
        UndoableErase(Object[] array, int index)
        {
               //save the array and index to erase.
               this.index = index;
               this.array = array;
               this.oldval = array[index];
 
               //erase.
               array[index] = null;
        }
 
        public void undo()
        {
               array[index] = oldval;
        }
 
        public void redo()
        {
               array[index] = null;
        }
 }

The tester for my example looks like this:

class Tester
{
    public static void main(String[] args)
    {
         //make array.
         Object[] array = new Object[] {1, 2, 3};
 
         //apply operation on it.
         UndoableOp op = new UndoableErase(array, 1);
         System.out.println(Arrays.toString(array)); //[1, null, 3]
 
         //undo that.
         op.undo();
         System.out.println(Arrays.toString(array)); //[1, 2, 3]
 
         //redo that.
         op.redo();
         System.out.println(Arrays.toString(array)); //[1, null, 3]
     }
}
Please like & share:

Enumerators

Enumerators are symbols (like DIME, NICKEL) used to represent values, which values cannot be represented well by other types like int or boolean.

Enumerator types are limited in values (just like how type boolean has only 2 values).

Enumerators are Objects that are set by the compiler to be non-modifiable.

Purpose is for keeping your code readable and therefore less buggy.

 

Enumerator Definition

enum Enumerator
{
     value1, value2, 
}

This creates an enumerator called Enumerator, with values (and only those values).

Enumerators cannot be modified after definition.

Example:

enum Status
{
     SINGLE, MARRIED
}

 

Testing for equals

Enumerators can be tested for equals just like how booleans can, too.

Example:

Status status = Status.SINGLE;
if (status == Status.SINGLE)
     return;
Please like & share:

Graphical Interfaces

Nimbus_Normal

Graphical User Interfaces (GUI) are visible menus you can interact with.

Purpose is for taking input from users or pop up info to them.

Graphic objects are found in the swing folder of the built in Java files.

A recommended way to build graphical interfaces is to use Netbeans, which builds these interfaces faster by using a visual editor that also automatically generates your code.

 

Making a window

UDD_Java_Frame

Use the JFrame class to create a window.

Show this window by using the method setVisible(True).

Example:

JFrame frame = new JFrame("title"); //create frame with title
frame.setVisible(true); //show frame

Set its size by setSize(), or pack() to set it to whatever size its contents take. Example:

frame.setSize(100, 100); //size it 100 pixels width, 100 pixels height
frame.pack(); //pack it down to its contents

 

Adding components

add(component);

This adds graphical objects into one another.

Every object in the swing folder is a Container, which means they can be contained in one another.

Example:

JFrame frame = new JFrame();
JLabel label = new JLabel("label"); //make label
frame.add(label); //add it to frame
frame.pack();
frame.setVisible(true);

 

Positioning components

Add_JToggleButton_to_each_part_of_a_border_layout_in_Java_Example

Classes inheriting LayoutManager (from java.awt package) help you position component positions more precisely:

LayoutManager Description
AbsoluteLayout Absolute positioning of objects given by coordinates
BorderLayout (JFrame default) Separates container into 5 areas: center, north, west, south, and east
BoxLayout Bottom to top layout
CardLayout Creates layers of panels where each can be brought to front by an action
FlowLayout (JPanel default) Left to right layout
Group Layout Groups containers; designed for use by visual editors like NetBeans
GridLayout Arranges components in a grid, each same sized, with a fixed number of rows and columns
GridBagLayout Like Grid Layout, but columns can have different sizes, and one component can span multiple columns
null No layout; each object needs to set their own rectangular bounds to show up correctly
OverlayLayout Back to front layout (overlapping objects)

Use setLayout() method to change the layout.

Example:

JFrame frame = new JFrame(); //make window
frame.setLayout(new GridLayout()); //set to grid layout
List list = new ArrayList();
for (int i = 0; i < 5; i++) //make list of buttons
        list.add(new JButton("test"));
for (JButton button : list) //add buttons to window
        frame.add(button);
frame.pack(); //auto-size window
frame.setVisible(true); //show window

 

ActionListeners

Button-Listener-Window

ActionListeners are objects that listen for a trigger in a component and run a list of statements when it is triggered.

ActionListeners implement the ActionListener interface.

Each component has a unique trigger:

Component Trigger
JButton Clicked
JComboBox An option is clicked
JRadioButton Clicked
JCheckBox Clicked
JTextBox Pressed enter when focused
JToggleButton  Clicked

To make a customized ActionListener with your own statements to run, make a new class implementing it and write your statements in the inherited method actionPerformed(). Example:

class Listener implements ActionListener
{
     public void actionPerformed(ActionEvent event)
     {
          //statements run when component is triggered
     }
}

Then call this method from a component to add an ActionListener to a component.

addActionListener(listener);

Example:

class Listener implements ActionListener
{
     public void actionPerformed(ActionEvent event)
     {
          System.out.println(“Triggered!”); //print something
     }
}
class Tester
{
     public static void main(String[] args)
     {
          JFrame frame = new JFrame(); //make window
          JButton button = new JButton(“click me”); //make button
          button.addActionListener(new Listener()); //add new listener
          frame.add(button); //add it to frame
          frame.pack();
          frame.setVisible(true);
     }
}
Common Error: forgetting to add an ActionListenerActionListener-less objects do nothing when you click on them, so beware that you do not forget them.
Please like & share:

Generics

Generics are classes, interfaces, methods, or constructors that use special variables called type variables.

ArrayList is an example of a generic class.

 

Type Variables

These are special variables that can be assigned types (the variables we normally use can be called value variables, because they are assigned values).

Purpose is to be used to declare value variables.

Example:

type var; //if type is a type variable, var will be declared with that type

 

Generic Class Definitions

class Class<type>
{
     ...
}

This creates a class with a type variable named type.

Type variables are accessible within the body, like how normal variables are.

Example:

//box that holds contents of a type.
class Box<type>
{
     type contents;
     Box(type contents)
     {
          this.contents = contents;
     }
}

Variables assigned generic class objects are declared and instantiated with angle brackets, having types to be passed to the constructor. Example (try it):

Box<String> stringbox = new Box<String>(“string”);

 

Generic Method Definitions

<type, type2, ...> return-type method()
{
     ...
}

This defines a method with type variables type, type2, ….

To be able to pass types to the method, make parameters preceded by type variables and write those type variables inside angle brackets.

Example:

<type> boolean equals(type a, type b)
{
     return a == b;
}

Modifiers (like static, public, etc.) must go before the angle brackets.

 

Constraining type variables

<type extends another-type>

This constrains what type can be to only types that extend another-type.

Example:

//test whether two Number values are identical.
<type extends Number> void test(type a, type b)
{
     System.out.println(a == b);
}

One can also use the keyword super to limit the type to be parent of another-type:

<type super another-type>

If you do not need to know nor use the passed type, you can change type to ? instead, for simplifying purposes:

<? super another-type> //cannot know ?

 

Naming conventions

I made my own names for type parameters in simplicity, like “type”. But these are the usual names people give to type parameters:

  • E – Element (used extensively by the Java Collections Framework)
  • K – Key
  • N – Number
  • T – Type
  • V – Value
  • S,U,V etc. – 2nd, 3rd, 4th types
Please like & share:

Maps

mapping

Maps are objects that hold values like ArrayLists, but their values can be indexed by objects instead of just integers.

The indexing set of objects is called the keys. The indexed set of objects is called the values.

Import from java.util.Map from the built-in Java library to use Map.

 

Creating Maps

Map map = new Map-type();

This creates a map of Map-type but used as Map. Map is an interface, so it cannot be instantiated, so another class must implement it, which we’ll call Map-type.

Here, map accepts both keys and values as Objects.

Map-type can be the following:

  • java.util.HashMap – Uses a special technique called hashing for faster indexing.
  • java.util.TreeMap – Automatically sorts elements in a given order as they are added.
  • And more, but these are the most used ones

Example:

Map map = new HashMap();

 

Constraining types

Map<KeyClass, ValueClass> map = new Map-type<KeyClass, ValueClass>();

This creates a map called map and limits the types of accepted keys to KeyClass, and the types of accepted values to ValueClass.

Example (try it):

Map<String, Integer> map = new HashMap<String, Integer>();
map.put("price", 10);
map.put("quantity", 5);

 

Adding Associations

map.put(key, value)

This associates key to value in map.

Keys cannot be duplicate, but values can.

The associations are represented by the class Entry.

Example (try it):

map.put("key", "value");

 

Retrieving values

map.get(key)

This retrieves the value associated to key.

The returned value will be of the declared type for map’s values (if no type was declared, it returns an Object).

Example (try it):

System.out.println(map.get("key")); //prints "value"

 

Retrieving Keys

Use the method keySet() to retrieve a set of keys (of class Set).

Then you can call toArray() to retrieve the keys in an Array.

Example (try it):

Set set = map.keySet();
set.toArray();

 

Sorting by Keys

We do this several ways, each needing an implementation of the Comparator interface, like so:

class KeyComparator implements Comparator
{
    public int compare(Object a, Object b) 
    {
        if ((char) a > (char) b)
             return 1;
        else
             return -1;
    }
}

Then we can:

  • Use Treemap from the very beginning, which sorts entries as they are added (try it):
Map map = new TreeMap(new KeyComparator());
map.put('B', 3);          
map.put('A', 1);
map.put('C', 2);
  • Or make a TreeMap out of your unsorted map, which automatically sorts it (try it):
Map sortedmap = new TreeMap(new KeyComparator());
sortedmap.putAll(map);
  • Or sort a copy of the key list and extract each association by that sorted key order, like so (try it):
  //make map.
  Map map = new HashMap(); 
  map.put('B', 3);          
  map.put('A', 1);
  map.put('C', 2);
  
  //get keylist and sort it.
  List keylist = new ArrayList(map.keySet());
  Collections.sort(keylist, new KeyComparator());
  
  //extract associations and put in a new map.
  Map sortedmap = new HashMap();
  for (Object key: keylist)
       sortedmap.put(key, map.get(key));

 

Sorting by Values

One way to do this is putting your unsorted map into a new TreeMap, passing a comparator to it.

Difference from KeyComparator above is that this comparator must remember the map.

Example (try it):

import java.util.*;

class ValueComparator implements Comparator
{
     Map map;
     ValueComparator(Map map) 
     {
         this.map = map;
     }

     public int compare(Object a, Object b) 
     {
         if ((double) map.get(a) > (double) map.get(b)) 
             return 1;
         else 
             return -1;
     }
}

class Tester
{
     public static void main(String[] args) 
     {
         //make map.
         Map map = new HashMap(); 
         map.put("Beltre", .324);
         map.put("Martinez", .335);
         map.put("Alluve", .341);
         map.put("Brantley", .327);
         System.out.println("Unsorted: " + map);

         //put in a TreeMap.
         Comparator comparator = new ValueComparator(map); 
         Map sortedmap = new TreeMap(comparator);
         sortedmap.putAll(map);
         System.out.println("Sorted: " + sortedmap);
     }
}

A comparator is not truly needed if comparing strings, characters, or numbers, as Java knows how to sort them, but I used one for demonstration purposes.

Please like & share:

Type Conversions

 

conversion

Converting something means using a value or a substitute value as a different type.

Converting values is done by “casting.”

 

Casting

(type) value-to-convert

For primitives, this returns a new value of type that represents value-to-convert.

For objects, this allows a variable to be set to a value that has been assigned to another variable declared as a different type. Example:

//object conversion.
Object object = new Integer(1);
Integer integer = (Integer) object;

/primitive conversion.
int i = 1;
double d = (double) i;
System.out.println(d); //1.0

Rounding errors occur when an exact conversion between numbers is not possible. Example:

double d = 1.2;
int i = (int) d;
System.out.println(i) //1; discarded .2

 

Wrapping

Wrapping is creating something representing another. Wrappers are objects representing primitives where objects are required (example: ArrayList elements, which can only be objects).

List of primitives and their corresponding wrappers, along with what needs to be passed to the wrapper class constructor to create a wrapper:

Primitive type Wrapper class Constructor Argument type
byte Byte byte or String
short Short short or String
int Integer int or String
long Long long or String
float Float floatdouble or String
double Double double or String
char Character char
boolean Boolean boolean or String

Example:

Integer i = new Integer(1);

Wrapper objects can also be obtained by casting. Example:

int i = 1;
Integer wrapper = (Integer) i;

 

Autowrapping

Automatically wrapping occurs when ArrayLists, which can only take primitives as elements, are added of primitives.

Example:

ArrayList list = new ArrayList();
list.add(1); //create wrapper representing 1, then add the wrapper

(The above is actually equivalent to the steps of:)

ArrayList list = new ArrayList();
list.add(new Integer(1));

 

Converting String to other types

Wrapper classes often have a method beginning with parse, to convert a string into a certain primitive. Example:

int i = Integer.parseInt("100"); //i is now set to 100

 

Converting other types to String

Both object and primitive types have their own way to be converted to a String:

Objects have a method called toString(), which gives a String representation of the object. Example:

Object object = new Object();
String s = object.toString();

Primitives need to be converted to wrapper objects to do it. Example:

int I = 10;
Integer I = new Integer(i); //wrapping I so we can call toString()
String s = i.toString();

You can define your own way to convert an object to a string. Just define a method called toString in your class definition. Example:

public String toString()
{
     return “test”;
}
Please like & share:

Error Handling

Errors in Java are represented by objects holding error information.

These objects are generated when errors occur.

Errors are handled by a programmer’s statements and these error objects.

 

Handling Errors

try
{
     statements
}
catch(Throwable-type error)
{
     statements
}

In the above, the try{} block tries to run statements that can err.

The catch{} block catches its errors and handles them with statements.

Example (try it):

try
{
     int x = 1 / 0; //generate an error here
}
catch (ArithmeticException error) //catch it
{
      System.out.println(error);
}

 

Throwing Errors

method() throws Throwable=type
{
     ...
}

When you do not want to handle an error, you can throw it.

throws reserved word throws (passes off) all of a type of error that happens in a block to the calling method of the currently running method to handle it.

No try block is needed in the throwing method.

The calling method must either catch it or throw it again (think “hot potatoes”).

Example:

class Tester
{
       static void err() throws ArithmeticException //erring method
       {
              int x = 1 / 0;
       }
 
       static void catchError() //calls above and catches its error
       {
              try
              {
                     err();
              }
              catch (ArithmeticException error)
              {
                                   System.out.println(error); //prints “/ zero” error

              }
       }
 
       public static void main(String[] args)
       {
                        catchError();

       }
}

 

Checked & Unchecked

Blue - checked Red - unchecked

Some of the most well-known errors. Blue – checked, red – unchecked

Checked errors (meaning “errors checked by compiler”) are errors that are required by the compiler to be handled, or your program will terminate.

Unchecked errors are errors that do not need to be handled or are fatal (which cannot be handled anyway).

 

Finally

finally
{
     statements
}

Finally blocks follow try/catch blocks and are run right after them.

They are blocks that run no matter what happens.

Purpose is to ensure something is run right before the program would terminate on an error (but it still will terminate afterwards).

They are often used for ensuring a file is closed when working on a file.

 

Assertions

assert expression;

This statement requires that some expression evaluates to true, else the program creates an AssertionError that must be caught or the program terminates.

This AssertionError is only created if the assertion feature is enabled in the compiler that you are using.

Purpose is to help detect errors in your program.

Example:

 

int divide(int x, int y)
{
     assert y != 0;

     return x / y;
}

 

 

Creating your own Error type

Your can make your own error classes, which must subclass Throwable.

Two types of Throwable already exist:

  • Error, which represents errors so severe they are not often handled.
  • Exception, which is often handled and includes errors that do or do not need to be handled.

Example:

class NewError extends Throwable
{
}
class Tester
{
    public static void main(String[] args)
         {
              try
              {
                   if (true == true)
                        throw new NewError();
              }
              catch(NewError error)
              {
                                  System.out.println("got here");

              }
       }
}
Please like & share:

Javadoc

Capture

Example of a javadoc-generated document (for ArrayList).

Javadoc is a utility included by JDK for creating documentation for your classes, interfaces, instance and class variables, constructors, and methods.

Javadoc uses a commenting format to be able to parse your code automatically.

The comments do not affect the function of your code.

 

Format

/** [description]

    @author [author name]
    @version [version info]
    @param [parameter] description
    @return [return value] [description]
    #throws [error type] [description]
*/ 

This is placed right before the method, class, etc. that you want to document.

The things preceded by @ are called tags (like @param, @return). Tags are optional keywords used to describe something.

Multiple of the same tag can be written (like with multiple authors).

Example:

/** Toaster of Food objects.
    @author David Hsu 
    @version 1.1 11/1/11
*/
class Toaster
{
     /** temperature setting for toasting. */
     int temperature = 500;

     /** This method toasts something.
         
         @param food1 the first food fed to the oven. 
         @param food2 the second food fed to the oven. 
         @return array of toasted items.
     */
     Food[] toast(Food food1, Food food2)
     {
          food1.status = "toasted";
          food2.status = "toasted";

          Food[] foods = {food1, food2};
          return foods;
     }
}

 

Generating the Javadoc document

Some IDEs make this easy: with Eclipse (if you have it), you can generate documentation simply by going file->export in the menu bar.

To do it in the computer terminal (command prompt), type the following while being in the directory of files that you want to document:

javadoc [files]

This will generate HTML pages (if it does not, check if you have installed JDK).

Example:

c:\animals> javadoc Cat.java Dog.java

Options can be included in the above command, which include:

  • -author : include author in generated pages.
  • -classpath [path] : give path of imported classes (if you need any).
  • -classpathlist [path];[path];…;[path] : same as above, but multiple paths.
  • -d [path] : Say what path to save generated pages.
  • -private : include private fields and methods (only public and protected ones are included by default).
  • -sourcepath [path] : say what path that the file you want to generate pages from is in.
  • -sourcepathlist [path];[path];…;[path] : same as above, but multiple paths.
  • -version : include version in generated pages.

 

(Optional) Preconditions and Postconditions

These things aren’t recognized in javadoc, but can be mentioned in your comments to more formalize your code (often used for design by customer contract).

Preconditions are required states of variables when a method is starting to run.

Example

/** Divide two integers.
    Precondition: divisor must not be 0.
    @param dividend left argument to the / operator
    @param divisor right argument to the / operator
*/
int divide(int dividend, int divisor)
{
     return dividend / divisor;
}

The assert statement in Java emulates preconditional checks. It requires that a condition is true, or an AssertionError is thrown (which must either be handled or the program terminates). Example:

assert divisor != 0;

Postconditions are required states of variables when a method finishes execution. Example:

/** add minutes to time.
     postconditions: 0 < hour < 24, 0 < minute < 60
*/
void addMinutes(int minutes)
{
     ...
}

 

Please like & share:

Abstraction & Interfaces

Abstraction is making something undefined (methods) or unable to be instantiated (classes).

Concretion, in contrast, is defining something and allowing it to be instantiated.

 

Abstract methods

abstract method();

These are methods that can be declared a name, type, and parameters, but have no body (no statements).

Abstract methods must be overridden.

They can only belong in abstract classes.

Purpose is for when you cannot agree on the implementation of a method, but you know it will be called, so you keep its name.

 

Abstract Classes

abstract Class
{
     ...
}

Abstract classes are classes that can have abstract and concrete methods.

Abstract classes cannot be instantiated.

Purpose is for grouping other classes together.

Example:

abstract Account //cannot be instantiated
{
}
class BankAccount extends Account
{
}

 

Interfaces

interface Interface
{
     abstract-methods
}

Interfaces are simply fully abstract classes (all methods are abstract) without variables.

Its methods are automatically declared abstract, so writing abstract is not needed.

Classes inheriting interfaces must use the reserved word implements instead of extends.

Example:

interface Menu
 {
     String button();
     String button2();
 }
 
class SimpleMenu
{
     String button()
     {
          return “yes”;
     }
     String button2()
     {
          return “no”;
     }
}
Please like & share:

Inheritance

inheritance

Inheritance means making a subclass of a class, or making a child of a parent (superclass) in other words.

Purpose is for reusing variables or methods of existing classes when creating new ones.

Extend is another word for inherit.

 

Syntax

class Class extends AnotherClass
{
     ...
}

This makes Class inherit AnotherClass.

Inheritors receive all their parent class fields and methods, but also can redefine them.

All classes automatically subclass the class Object, even without declaring so.

Example:

class Animal
{
}
class Horse extends Animal
{
}
class Donkey extends Horse
{
} 

We may refer to a subclass by its superclass name: “Horses and Donkeys are Animals.”

 

Common error: confusing super/sub classes
Super sounds like “greater”, so people mistake superclasses for an “extending” class. Super comes from the word “over” in fact, so superclasses can be thought of as being “over”, as parents are over and prior to, another.

 

Liskov Substitution Principle

substitution

This means that though a variable has a type, it can be assigned a subtype value.

Example:

Computer computer = new Iphone();

The value is used as the variable’s type, however. This means properties had by the value’s type but not the variable’s type cannot be accessed through the variable.

Like English: If an iphone is a computer, and we use the iphone as a computer, but only iphones can call someone, we cannot use it to call someone. But the iphone can be used as a computer, because it is a computer, so we can use it to compute things for example.

If you need to use the value as its own type, you must convert the variable to the subtype, shown in the Type Conversions section.

 

Overridding methods

Child classes can redefine their inherited methods or variables (not changing original).

Do this by declaring a method with the same name, in the inheriting class.

Example:

class Animal
{
     void cry()
     {
     }
}
class Horse extends Animal
{
     void cry() //overrides above cry()
     {
           System.out.println("neigh!");
     }
}
class Donkey extends Horse
{
     void cry() //overrides above cry()
     {
           System.out.println("bray!");
     }
}
Common error: overriding method declaration mismatchThis often occurs in such methods as equals(). It must be exactly:

public boolean equals(Object object)
{
	...
}

But people often put their own class in place of Object. This not only will not override the inherited equals, but will make the compiler think you are trying to add a new, overloaded method. So now you have two of the same method name, making this error hard to detect. Beware.

 

Polymorphism

This simply means calling the overridden method over the original.

(Polymorphism literally means “changing into many.”)

Example (try it):

//continuing above example.
animal.cry(); //will print neigh!
anotheranimal.cry(); //will print bray!

Since all classes inherit Object methods, overriding them is a common use for polymorphism:

  • toString() – gives a customized String representation of the object
  • equals() – customizes how to compare if something is “equal” to another object

The method System.out.println() uses toString() to print a String representation of its argument, so you can override toString() to make it print objects your way. Example:

class Animal
{
     String name;
     public String toString()
     {
           return name;
      }
}

Overriding equals() creates a customized way to compare between objects to see if they are equal. Example (try it):

class Animal
{
     String name;
     public boolean equals(Object object)
     {
           Animal other = (Animal) object;
           return this.name == other.name; //equal if same name
     }
}

 

 

Calling Parent Class Methods

Though methods can be overridden, the originals can still be accessed by the inheritors, as if they hold them. Do this by calling super.method(arguments), which denote calling their parent’s version.

Example:

class Donkey
{
     void cry()
     {
          super.cry(); //executes Horse's cry()
     }
}

 

Using Parent Class Constructor

The parent class constructor can be used for construction of its child, by using super(arguments).

super(); must only ever be the first statement in the constructor.

Example:

class Donkey
{
     Donkey()
     {
          super(); //executes the constructor Horse()
     }
}

 

Please like & share: