Chapter:Interfaces - Writing an interface - Exercises

From Juneday education
Jump to: navigation, search

Exercises on writing your own interface

Exercises on writing a small interface and some classes which implements that interface.

We should now write a MediaPlayer - not a very fancy one. To do this we start by writing a new interface for files that are, in some way, Playable. Since we started, in the previous chapter on inheritance, to use FBFile etc we will stick to using that so let's call our interface FBPlayable.

What do we expect from a playable file? Well, since we call the interface FBPlayable we can expect it to be able to play itself ... so a method called play() sounds reasonable.

Before we start we want you to do any of the following:

  • copy the files from the previous chapter exercises where you were using FBFile etc, to a new directory
    • If you don't have the files, you can download them from here.
  • continue editing the files in the same directory as you used in the previous section

Ok, we're ready to start. Let's do some basics first - the interface and some classes.

Q1

Create an interface FBPlayable. It can use the same package as FBFile. The interface should specify the method play() as:

  • public
  • return type shall be void
  • have no parameters

Expand using link to the right to see the full content.

Suggested solution:

package com.superpower.filebrowser;

public interface FBPlayable  {

    public void play();

}

Q2

FBOgg and FBMp3 implementing FBPlayable
Dotted arrows mean "implements"

Add a class FBMp3. This class should:

  • extend FBFile, since we want it to be a file
  • implement FBPlayable, since we want it to be able to "behave" as a Playable. The implementation of the play method can be done by simply outputting some words about the file being played.... it would be better to actually play the file but for now we're happy with this solution.
  • have a constructor with one parameter (of type String)

Expand using link to the right to see the full content.

Suggested solution:

package com.superpower.filebrowser;

public class FBMp3 extends FBFile implements FBPlayable {

    public FBMp3(String name) {
        super(name);
    }

    public String thumbnail() {
        return "[mp3 ]";
    }

    @Override // It is called overriding, also when you implement an interface!
    public void play() {
        System.out.println("faked playing of file: " + this);
    }
    
}

Q3

Add a class FBOgg in a similar way you did with the FBMp3 class.

Expand using link to the right to see the full content.

Suggested solution:

package com.superpower.filebrowser;

public class FBOgg extends FBFile implements FBPlayable {

    public FBOgg(String name) {
        super(name);
    }

    public String thumbnail() {
        return "[ogg ]";
    }

    public void play() {
        System.out.println("faked playing of file: " + this);
    }
    
}

Q4

In the class FileList you need to add code to handle FBPlayable. So, add the following methods to the class FileList:

    public static List<FBPlayable> listPlayable() {
        return listPlayable(".");
    }
    
    public static List<FBPlayable> listPlayable(String dir) {
        return listPlayable(new File(dir));
    }
    
    public static List<FBPlayable> listPlayable(File dir) {
        List<FBFile>     files = list(dir);
        List<FBPlayable> list  = new ArrayList<FBPlayable>();

        for (FBFile f : files) {
            if (f instanceof FBPlayable ) {
                list.add((FBPlayable)f);
            }
        }
        
        return list;
    }

Change the following method in the class FileList to look like this.

    public static List<FBFile> list(File dir) {

        if ( (dir==null) || dir.isFile() ) {
            return null;
        }
        
        // By returning a List we can chose any the subclasses (in
        // this case actually sub interfaces - more on that in the
        // coming chapter) and change it afterwards, since the users
        // of this method only uses the methods as "provided" by List
        List<FBFile> list = new ArrayList<FBFile>();
        
        // Note that we use File below. File is a class in Java.
        File[] files = dir.listFiles();
        if (files==null) {
            System.err.println("Woooops, list files returned null");
            System.err.println(" * dir: " + dir);
        }
        for (File file : files) {
            if (file.isFile()) {
                if (file.getPath().endsWith(".java")) {
                    list.add(new FBJavaFile(file.getPath()));
                } else if (file.getPath().endsWith(".mp3")) {
                    list.add(new FBMp3(file.getPath()));
                } else if (file.getPath().endsWith(".ogg")) {
                    list.add(new FBOgg(file.getPath()));
                } else {
                    list.add(new FBFile(file.getPath()));
                }
            } else if (file.isDirectory()) {
                list.add(new FBDir(file.getPath()));
            }
        }
        return list;
    }

Note: we check the suffix of the files and create objects using that information.

Expand using link to the right to see the full content.

Suggested solution:

We're listing the entire FileList class here to make it a bit easier if you want to copy/paste.

package com.superpower.filebrowser.utils;

import java.util.List;
import java.util.ArrayList;
import java.io.File;

import com.superpower.filebrowser.*;


public class FileList {

    public static List<FBFile> list() {
        return list(".");
    }

    public static List<FBFile> list(String dir) {
        return list(new File(dir));
    }

    public static List<FBPlayable> listPlayable() {
        return listPlayable(".");
    }
    
    public static List<FBPlayable> listPlayable(String dir) {
        return listPlayable(new File(dir));
    }
    
    public static List<FBPlayable> listPlayable(File dir) {
        List<FBFile>     files = list(dir);
        List<FBPlayable> list  = new ArrayList<FBPlayable>();

        for (FBFile f : files) {
            if (f instanceof FBPlayable ) {
                list.add((FBPlayable)f);
            }
        }
        
        return list;
    }
    
    public static List<FBFile> list(File dir) {

        if ( (dir==null) || dir.isFile() ) {
            return null;
        }
        
        // By returning a List we can chose any the subclasses (in
        // this case actually sub interfaces - more on that in the
        // coming chapter) and change it afterwards, since the users
        // of this method only uses the methods as "provided" by List
        List<FBFile> list = new ArrayList<FBFile>();
        
        // Note that we use File below. File is a class in Java.
        File[] files = dir.listFiles();
        if (files==null) {
            System.err.println("Woooops, list files returned null");
            System.err.println(" * dir: " + dir);
        }
        for (File file : files) {
            if (file.isFile()) {
                if (file.getPath().endsWith(".java")) {
                    list.add(new FBJavaFile(file.getPath()));
                } else if (file.getPath().endsWith(".mp3")) {
                    list.add(new FBMp3(file.getPath()));
                } else if (file.getPath().endsWith(".ogg")) {
                list.add(new FBOgg(file.getPath())); 
                } else {
                    list.add(new FBFile(file.getPath()));
                }
            } else if (file.isDirectory()) {
                list.add(new FBDir(file.getPath()));
            }
        }
        return list;
    }

}

Q5

Ok, let's make sure we can list files as in the previous section. But first let's make it possible to pass a directory to the TextMain class. Pass this directory to the FileList's list method.

Expand using link to the right to see the full content.

Suggested solution:

    public static void main(String[] args) {

        String dir = ".";
        if ( args.length!=0) {
            dir = args[0];
        }
        
        List<FBFile> files = FileList.list(dir);

        for (FBFile f : files) {
            System.out.println(f.thumbnail() + " " + f.name());
        }
        
    }

Q6

Let's write a new class, MediaPlayer in the same package as TextMain. This class should have a main method that:

  • checks if the users supplied a directory (see previous exercise) and uses that when listing files
  • asks FileList for a list of FBPlayable objects.
  • loops through the objects and plays them one by one (using the play method).

Expand using link to the right to see the full content.

Suggested solution:

package com.superpower.filebrowser.main;

import java.util.List;

import com.superpower.filebrowser.FBPlayable;
import com.superpower.filebrowser.utils.FileList;


public class MediaPlayer {

    public static void main(String[] args) {

        String dir = ".";
        if ( args.length!=0) {
            dir = args[0];
        }
        
        System.out.println("Playing in " + dir + ":");
        for (FBPlayable p : FileList.listPlayable(dir)) {
            p.play();
        }
        
    }

}

Q7 - bonus

Read this, if you want to learn more about uses of interfaces.

For a solution which doesn't create a new class for each kind of file type, please see the following PDF presentation:

No exercise, but rather voluntary reading.

Links

Source code (exercises/solutions)

You can find complete source code to the suggested solutions below in the writing-your-own-interfaces directory in this zip file or in the git repository.

Further reading

Where to go next

Next page is: Interfaces_-_Program_against_an_interface

« PreviousBook TOCNext »