Try โ€‚โ€‰HackMD

Programming II Lab 7

Abstract Classes & Interfaces

The Islamic University of Gaza
Engineering Faculty
Department of Computer Engineering
Author: Mohammed Nafiz ALMadhoun2021/03/27

In this lab, we are going to talk about abstract classes, then we will talk about interfaces, and how we could implement event listeners in JavaFX.

Abstract Classes

A lot of times when we are defining our classes, we noticed that a superclass is not created so we could create an object of it, we created that class so we can have a common type between other subclasses.

As you might notice in our previous example, we've created Shape class, which is the superclass for Circle, Rectangle classes, and we've created the method getArea in the superclass Shape, but the information in Shape is not enough to calculate the area, so we defined it and let it return zero, this solution is not correct.

The Shape class is created only to create a superclass, but we won't have an object of shape, because it doesn't even make sense in the real world.

So this is the concept of Abstract class, it's a class that you couldn't create objects from it, but you can use it to be supertype for other classes.

public abstract class Shape { int x; int y; ... public abstract int getArea(); }

Notice that getArea method doesn't have a body, so each concrete subclass should implement its body.

Shape type has the method getArea but it doesn't have its body.

Interfaces

An interface describes what a class can do, the class itself should implement certain methods defined in the interface.

As you know, a class can only extend one class, this restriction will save us from a lot of mistakes and errors, but we need something that tells the others that the class can do certain jobs (or methods), this is what an interface if for.

You could define an interface like this:

public interface Interactable { public abstract void interact(Event event); }

Notice that the name of an interface is an adjective, if a class implements this interface, it should implement its method interact, so we could use polymorphism to store an object type that implements this interface in a variable type of the interface.

class Test implements Interactable { public void interact (Event event) { System.out.println("Test Test"); } } ... Interactable t = new Test(); t.interact(null); ...

You could also implement as many interfaces as you like.

Comparable Interace

This interface defines compareTo method, which will make your life easier if you want to use the built-in array sorting methods.

public Shape implements Comparable<Shape> { ... @Override public int compareTo(Shape o) { return getArea() - o.getArea(); } ... }

Now you can sort an array of Shapes using java.util.Arrays.sort.

Events in JavaFX

To handle an event in JavaFX, you should handler object should implement the EventHandler interface, please take a look here.

This interface contains a method handle that should be impelemented.

public class Test extends Application { @Override public void start(Stage stage) throws Exception{ VBox vbox = new VBox(10); for (int i=0;i<3;i++){ Button btn = new Button("Button "+i); btn.setOnAction (new PrintlnHandler(i)); vbox.getChildren().add(btn); } vbox.setPadding(new Insets(10)); Scene scene = new Scene(vbox); stage.setScene(scene); stage.setTitle("Test"); stage.show(); } } class PrintlnHandler implements EventHandler<ActionEvent> { private int num; public PrintlnHandler(int num){ this.num = num; } public void handle(ActionEvent event) { System.out.println(num); } }

Notice that we've created an object for each button, this object contains some information (the number of the button) and implements the handle method.

Creating a class that implements the method, then creating an object for each button is a time-consuming job, so luckily Java let us create a class and an object from it in one line.

public class Test extends Application { @Override public void start(Stage stage) throws Exception{ VBox vbox = new VBox(10); for (int i=0;i<3;i++){ Button btn = new Button("Button "+i); int temp = i; btn.setOnAction (new EventHandler<ActionEvent>(){ public void handle(ActionEvent event) { System.out.println(temp); } }); vbox.getChildren().add(btn); } vbox.setPadding(new Insets(10)); Scene scene = new Scene(vbox); stage.setScene(scene); stage.setTitle("Test"); stage.show(); } }

And we've another shortcut we can use for interfaces with only one abstract method, we could write lambda expressions:

public class Test extends Application { @Override public void start(Stage stage) throws Exception { VBox vbox = new VBox(10); for (int i=0;i<3;i++){ Button btn = new Button("Button "+i); int temp = i; btn.setOnAction ((e) -> { System.out.println(temp); }); vbox.getChildren().add(btn); } vbox.setPadding(new Insets(10)); Scene scene = new Scene(vbox); stage.setScene(scene); stage.setTitle("Test"); stage.show(); } }

You should choose which one you will use, but notice that there is a difference between each form, sometimes it's much easier to create a class that implements EventHandler, but most of the times lambda expression will be enough.

Good luck with your mid-term exams <3
tags: Programming Java IUG
End Of Lab 7