Interfaces

An interface in the Java programming language is an abstract type that is used to specify an interface (in the generic sense of the term) that classes must implement. Interfaces are declared using the interface keyword, and may only contain method signature and constant declarations (variable declarations that are declared to be both static and final). An interface may never contain method definitions.

Interfaces cannot be instantiated, but rather are implemented. A class that implements an interface must implement all of the methods described in the interface, or be an abstract class. Object references in Java may be specified to be of an interface type; in which case, they must either be null, or be bound to an object that implements the interface.

One benefit of using interfaces is that they simulate multiple inheritance. All classes in Java must have exactly one base class, the only exception being java.lang.Object (the root class of the Java type system); multiple inheritance of classes is not allowed.

In order to explain interfaces, we are going to play bingo and for this we are going to create 20 bingo cards with 15 numbers in each one of them.

First, we create a class Main with a new ArrayList of Bingo Cards. After adding each of the cards to the list, we print them to console.

package com.edu4java.tutorial16;

import java.util.ArrayList;

public class Main {
public static void main(String[] args) {
	ArrayList<BingoCard> bingoList = new ArrayList<BingoCard>();
	
	for (int i = 0; i < 20; i++) {
		BingoCard bingo=new BingoCard();
		bingoList.add(bingo);
		bingo.syso();
	}
}
}

In the class "BingoCard", we create a new array of ints with 15 positions. After creating it, the constructor is called and we use an object Random to raffle numbers.

I then use a for to iterate over the 15 positions of the array and in each loop I add a number, raffled between the numbers 0 to 99.

So we raffle numbers, we insert them in the array of ints "bingo", so they are kept in an instance variable of "BingoCard" and each time the method "syso" is called, we call the method "toString()".

The method "toString", iterates over all the array of ints "bingo", concatenating each one of them with the other and printing them to console.

package com.edu4java.tutorial16;

import java.util.Random;

public class BingoCard {
	int[] bingo = new int[15];

	public BingoCard() {
		Random random = new Random();
		for (int i = 0; i < bingo.length; i++) {
			bingo[i] = random.nextInt(100);
		}
	}

	public int[] getBingo() {
		return bingo;
	}

	public void setBingo(int[] bingo) {
		this.bingo = bingo;
	}

	@Override
	public String toString() {
		String s = "[";
		for (int i = 0; i < bingo.length; i++) {
			s = s + bingo[i] + ",";
		}
		return s + "]";

	}

	public void syso() {
		System.out.println(this.toString());
	}

}

The constructor of the class "BingoCard1" has a filter to avoid repeated numbers in our bingo cards. This is an improvement in relation to the class "BingoCard".

package com.edu4java.tutorial16;

import java.util.Random;

public class BingoCard1 {
	int[] bingo = new int[15];

	public BingoCard1() {
		Random random = new Random();
		for (int i = 0; i < bingo.length; i++) {
			bingo[i] = random.nextInt(100);
			if (isRepeated(i)) {
				i--;
			}
		}
	}

	private boolean isRepeated(int i) {
		for (int j = 0; j < i; j++) {
			if (bingo[i] == bingo[j]) {
				return true;
			}
		}
		return false;
	}

	public int[] getBingo() {
		return bingo;
	}

	public void setBingo(int[] bingo) {
		this.bingo = bingo;
	}

	@Override
	public String toString() {
		String s = "[";
		for (int i = 0; i < bingo.length; i++) {
			s = s + bingo[i] + ",";
		}
		return s + "]";

	}

	public void toConsole() {
		System.out.println(this.toString());
	}

}

BingoCard2 has another improvement; with the method printoToConsole(), it gets rid of the last coma.

package com.edu4java.tutorial16;

import java.util.Random;

public class BingoCard2 {
	int[] bingo = new int[15];

	public BingoCard2() {
		Random random = new Random();
		for (int i = 0; i < bingo.length; i++) {
			bingo[i] = random.nextInt(100);
		}
	}

	public int[] getBingo() {
		return bingo;
	}

	public void setBingo(int[] bingo) {
		this.bingo = bingo;
	}


	public void printoToConsole() {
		System.out.print("[");
		for (int i = 0; i < bingo.length; i++) {
			System.out.print(bingo[i]);
			if (i + 1 < bingo.length) {
				System.out.print(",");

			}
		}
		System.out.println("]");
	}

}

Every time we make an improvement we have to change a lot of code in the main class. This can be problematic in a program with thousands of classes. To avoid this we define an interface;

package com.edu4java.tutorial16;

public interface IBingoCard {

	void syso();

}

And we now make all the classes BingoCard implement the interface IBingoCard and its methods;

package com.edu4java.tutorial16;

import java.util.Random;

public class BingoCard implements IBingoCard {
	int[] bingo = new int[15];

	public BingoCard() {
		Random random = new Random();
		for (int i = 0; i < bingo.length; i++) {
			bingo[i] = random.nextInt(100);
		}
	}

	public int[] getBingo() {
		return bingo;
	}

	public void setBingo(int[] bingo) {
		this.bingo = bingo;
	}

	@Override
	public String toString() {
		String s = "[";
		for (int i = 0; i < bingo.length; i++) {
			s = s + bingo[i] + ",";
		}
		return s + "]";

	}

	/* (non-Javadoc)
	 * @see com.edu4java.tutorial16.IBingoCard#syso()
	 */
	@Override
	public void syso() {
		System.out.println(this.toString());
	}

}

package com.edu4java.tutorial16;

import java.util.Random;

public class BingoCard1 implements IBingoCard{
	int[] bingo = new int[15];

	public BingoCard1() {
		Random random = new Random();
		for (int i = 0; i < bingo.length; i++) {
			bingo[i] = random.nextInt(100);
			if (isRepeated(i)) {
				i--;
			}
		}
	}

	private boolean isRepeated(int i) {
		for (int j = 0; j < i; j++) {
			if (bingo[i] == bingo[j]) {
				return true;
			}
		}
		return false;
	}

	public int[] getBingo() {
		return bingo;
	}

	public void setBingo(int[] bingo) {
		this.bingo = bingo;
	}

	@Override
	public String toString() {
		String s = "[";
		for (int i = 0; i < bingo.length; i++) {
			s = s + bingo[i] + ",";
		}
		return s + "]";

	}


	@Override
	public void syso() {
		System.out.println(this.toString());
		
	}

}

package com.edu4java.tutorial16;

import java.util.Random;

public class BingoCard2 implements IBingoCard {
	int[] bingo = new int[15];

	public BingoCard2() {
		Random random = new Random();
		for (int i = 0; i < bingo.length; i++) {
			bingo[i] = random.nextInt(100);
		}
	}

	public int[] getBingo() {
		return bingo;
	}

	public void setBingo(int[] bingo) {
		this.bingo = bingo;
	}

	@Override
	public void syso() {
		System.out.print("[");
		for (int i = 0; i < bingo.length; i++) {
			System.out.print(bingo[i]);
			if (i + 1 < bingo.length) {
				System.out.print(",");

			}
		}
		System.out.println("]");

	}

}

Finally, we use this interface in the Main class. We can use for example BingoCard2 and we only have to change it in just one place;

package com.edu4java.tutorial16;

import java.util.ArrayList;

public class Main {
public static void main(String[] args) {
	ArrayList<IBingoCard> bingoList = new ArrayList<IBingoCard>();
	
	for (int i = 0; i < 20; i++) {
		IBingoCard bingo=new BingoCard2();
		bingoList.add(bingo);
		bingo.syso();
	}
}
}
<< Previous Index >>