Introduction To Interfaces
I recommend that you complete the Introduction to Classes before doing this as I will be continuing with the code from it.
If you would like to keep the previous code for reference then I would suggest you copy the entire folder and use that. If not then files you were using for the Introduction to Classes.
Interfaces are fairly simple and this tutorial will be much shorter than the class one. First off what is an interface? Well I mentioned that a Class is like the blueprint of an Object so an Interface is like the blueprint of a Class. Although not necessary, an interface can be used to define the methods and properties a class has. The class is not limited to just those methods and properties set by the interface and a class can have many interfaces as well as other methods and properties of its own. Best of all interfaces have no code! That's right there is no code in an interface. Just declarations of the necessary properties and methods.
Since an interface is just to define the properties and methods they are all public and don't have to be declared as public. I will continue from the Introduction to Classes and start by creating a new .java file interface called IFourSidedShape.
public interface IFourSidedShape
{
}
Now lets think of characteristics of a four sided shape. What comes to mind? Square, Rectangle, Parallelogram, Rhombus, Trapezoid. OK not all those would normally come to mind and you may not even know what some of those are. That doesn't matter the only thing that matters is they all have four sides but do we need to keep track of all four sides? No. A square and rhombus have four sides but they are all the same length and a rectangle and parallelogram have two pairs of sides. So they all have sides but the number of sides you need to keep track of differ. This sounds like a parameter list to me even if some will only have one value. Since the number of different sides is well, different, there should be a property to tell how many different sides there are. This should be a read only property because the Shape determines the number of different sides not the user so they have no need to change it. Along with the Area we have a simple Interface.
public interface IFourSidedShape
{
double getSide(int index);
void setSide(int index, double sideLength);
int getNumberOfSides();
double area();
}
That's all there is to Interfaces. Well not exactly, you probably want to know how to use them. So lets start by adding a new Class and calling it Rectangle. To use an interface you "Implement" it with the keyword implements after you declare the class.
public class Rectangle implements IFourSidedShape
{
}
If you try to compile the class now you will get an error stating that it should be declared abstract since it does not implement getSides from IFourSidedShape. Abstract is explained later in the Abstract Class lesson. We do not want an Abstract Class since we plan to implement all of the Interface within Rectangle. So lets do that by declaring them:
public double getSide(int index)
{
}
public void setSide(int index, double sideLength)
{
}
public int getNumberOfSides()
{
}
public double area()
{
}
All you have to do to properly implement the interface is declare all the necessary methods with the same name and parameter list. Note that all the methods in the interface are public and we cannot go lower in scope so all the implemented methods in Rectangle must be public.
As I mentioned the Interface is the blueprint of a class and it has no code. That means the Class has all the code. A rectangle has two different sides (length and width) so we will need a two element array and getNumberOfSides will return 2. The Area is length * width. Also to show that you are not limited to just those set by the interface there will also be the isSquare function which will compare the two sides and if they are equal will return True. If not return False.
Your code should end up something like this:
public class Rectangle implements IFourSidedShape
{
private double[] sides = new double[2];
public double getSide(int index)
{
if (index < 0 || index > 1)
throw new IndexOutOfBoundsException("Index must be 0 or 1");
else
return sides[index];
}
public void setSide(int index, double sideLength)
{
if (index < 0 || index > 1)
throw new IndexOutOfBoundsException("Index must be 0 or 1");
else
if (sideLength > 0)
sides[index] = sideLength;
}
public int getNumberOfSides()
{
return 2;
}
public double area()
{
return sides[0] * sides[1];
}
public boolean isSquare()
{
return sides[0] == sides[1];
}
}
Now do the same for the Square. Create a new class called Square2. There aren't many differences between the Square class and Rectangle class. The Square class only has one different side so it will have an array of one and getNumberOfSides will return 1. Also there is no need for the isSquare method and the Area has a slight change in math.
public class Square2 implements IFourSidedShape
{
private double[] sides = new double[1];
public double getSide(int index)
{
if (index != 0)
throw new IndexOutOfBoundsException("Index must be 0");
else
return sides[index];
}
public void setSide(int index, double sideLength)
{
if (index != 0)
throw new IndexOutOfBoundsException("Index must be 0");
else
if (sideLength > 0)
sides[index] = sideLength;
}
public int getNumberOfSides()
{
return 1;
}
public double area()
{
return sides[0] * sides[0];
}
}
Now you have two classes that implement the IFourSidedShape
interface. You may be wondering what the point of this is. It seams like a lot
of work for nothing. Well now comes the pay off. An interface is a data type.
It cannot be directly created (IFourSidedShape r = new
IFourSidedShape())
but classes that implement it are also consider that type. Return to the
Tester class for a demonstration.
public static void main(String[] args)
{
Rectangle r = new Rectangle();
if (r instanceof Rectangle)
System.out.println("r is a Rectangle");
if (r instanceof IFourSidedShape)
System.out.println("r is an IFourSidedShape");
}
As the output to the Console will show "r" is a Rectangle and it is also an IFourSidedShape.
Then set both different sides of "r" to the same value and try the IsSquare function.
r.setSide(0, 10);
r.setSide(1, 10);
System.out.println("r is a Square: " + r.isSquare());
Also a variable of the Interface type can hold objects of other classes that implement it. Declare two variables of type IFourSidedShape and set one to a new Rectangle and the other to a new Square2. Notice that it works the same way but also notice that the Rectangle one doesn't have the isSquare function. This is because the data type is IFourSidedShape so it has the methods and properties of that and doesn't know what the actual object it holds is. If you are sure the variable is a certain type then you can cast it to get to that Type's methods and properties.
IFourSidedShape f1 = new Rectangle();
IFourSidedShape f2 = new Square2();
f1.setSide(0, 10);
f1.setSide(1, 10);
f2.setSide(0, 3);
System.out.println("Rectangle Area = " + f1.area() +
" Square Area = " + f2.area());
// doing f1.isSquare() is invalid since it is not a method
// of IFourSidedShape which is the data type of f1
// therefore we must cast it to a Rectangle to use isSquare
Rectangle rect = (Rectangle)f1;
System.out.println("f1 is a square: " + rect.isSquare());
If f1 was not a Rectangle then trying to cast it would throw an Exception. You should normally check to see if it is that type using instanceof first.
Some final notes are you can't declare the constructors inside an interface. The class can still have multiple constructors (i.e. like we did with Square and Triangle) but those can't be defined within the interface. If you want to implement multiple interfaces then separate them with commas.
public class Rectangle implements IFourSidedShape, AnotherInterface, YetAnotherInterface
Congratulations you have completed the Introduction to Interfaces. You can now continue on with the Introduction to Inheritance lesson.
Author Information:
http://www.programmers-corner.com
