Never confuse education with intelligence, you can have a PhD and still be an idiot.
- Richard Feynman -



Difference between revisions of "Chapter:Interfaces - Writing an interface - Exercises"

From Juneday education
Jump to: navigation, search
(Exercises on writing your own interface: Added a UML class diagram)
(Preparing for split of solutions into each exercise section)
Line 13: Line 13:
 
Ok, we're ready to start. Let's do some basics first - the interface and some classes.
 
Ok, we're ready to start. Let's do some basics first - the interface and some classes.
  
'''1.''' Create an interface <code>FBPlayable</code>. It can use the same package as FBFile. The interface should specify the method <code>play()</code> as:
+
==Q1==
 +
Create an interface <code>FBPlayable</code>. It can use the same package as FBFile. The interface should specify the method <code>play()</code> as:
 
* public
 
* public
 
* return type shall be void
 
* return type shall be void
 
* have no parameters
 
* have no parameters
  
'''2.'''
+
<div class="mw-collapsible mw-collapsed">
 +
Expand using link to the right to see the full content.
 +
<div class="mw-collapsible-content">
 +
</div></div>
 +
 
 +
==Q2==
 
[[File:FBPlayable FBMp3 FBOgg.png|thumb|400px|right|FBOgg and FBMp3 implementing FBPlayable<br>Dotted arrows mean "implements"]]
 
[[File:FBPlayable FBMp3 FBOgg.png|thumb|400px|right|FBOgg and FBMp3 implementing FBPlayable<br>Dotted arrows mean "implements"]]
 
Add a class <code>FBMp3</code>. This class should:
 
Add a class <code>FBMp3</code>. This class should:
Line 26: Line 32:
 
* have a constructor with one parameter (of type String)
 
* have a constructor with one parameter (of type String)
  
'''3.''' Add a class <code>FBOgg</code> in a similar way you did with the <code>FBMp3</code> class.
+
<div class="mw-collapsible mw-collapsed">
 +
Expand using link to the right to see the full content.
 +
<div class="mw-collapsible-content">
 +
</div></div>
 +
 
 +
==Q3==
 +
Add a class <code>FBOgg</code> in a similar way you did with the <code>FBMp3</code> class.
 +
 
 +
<div class="mw-collapsible mw-collapsed">
 +
Expand using link to the right to see the full content.
 +
<div class="mw-collapsible-content">
 +
</div></div>
  
'''4.''' In the class <code>FileList</code> you need to add code to handle <code>FBPlayable</code>. So, add the following methods to the class <code>FileList</code>:
+
==Q4==
 +
In the class <code>FileList</code> you need to add code to handle <code>FBPlayable</code>. So, add the following methods to the class <code>FileList</code>:
  
 
<source lang="Java">
 
<source lang="Java">
Line 94: Line 112:
 
''Note: we check the suffix of the files and create objects using that information.''
 
''Note: we check the suffix of the files and create objects using that information.''
  
'''5.''' 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 <code>TextMain</code> class. Pass this directory to the <code>FileList</code>'s <code>list</code> method.
+
<div class="mw-collapsible mw-collapsed">
 +
Expand using link to the right to see the full content.
 +
<div class="mw-collapsible-content">
 +
</div></div>
 +
 
 +
==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 <code>TextMain</code> class. Pass this directory to the <code>FileList</code>'s <code>list</code> method.
 +
 
 +
<div class="mw-collapsible mw-collapsed">
 +
Expand using link to the right to see the full content.
 +
<div class="mw-collapsible-content">
 +
</div></div>
  
'''6.''' let's write a new class, <code>MediaPlayer</code> in the same package as <code>TextMain</code>. This class should have a main method that:
+
==Q6==
 +
Let's write a new class, <code>MediaPlayer</code> in the same package as <code>TextMain</code>. This class should have a main method that:
 
* checks if the users supplied a directory (see previous exercise) and uses that when listing files
 
* checks if the users supplied a directory (see previous exercise) and uses that when listing files
 
* asks <code>FileList</code> for a list of <code>FBPlayable</code> objects.
 
* asks <code>FileList</code> for a list of <code>FBPlayable</code> objects.
 
* loops through the objects and plays them one by one (using the <code>play</code> method).
 
* loops through the objects and plays them one by one (using the <code>play</code> method).
 
 
  
 
<div class="mw-collapsible mw-collapsed">
 
<div class="mw-collapsible mw-collapsed">
 
=Solutions=
 
 
Expand using link to the right to see the full content.
 
Expand using link to the right to see the full content.
 
<div class="mw-collapsible-content">
 
<div class="mw-collapsible-content">
 +
</div></div>
  
{{SolutionSource|dir=writing-your-own-interfaces|zip=https://github.com/progund/interfaces/archive/master.zip|vcs=git|vcs-link=https://github.com/progund/interfaces.git}}
 
  
 +
 +
 +
=Solutions=
  
 
'''1.''' Suggested solution:
 
'''1.''' Suggested solution:
Line 308: Line 337:
 
</div>
 
</div>
 
=Links=
 
=Links=
 +
==Source code (exercises/solutions)==
 +
{{SolutionSource|dir=writing-your-own-interfaces|zip=https://github.com/progund/interfaces/archive/master.zip|vcs=git|vcs-link=https://github.com/progund/interfaces.git}}
 +
 
==Further reading==
 
==Further reading==
 
* [https://docs.oracle.com/javase/tutorial/java/concepts/interface.html Oracle tutorial - What is an interface?]
 
* [https://docs.oracle.com/javase/tutorial/java/concepts/interface.html Oracle tutorial - What is an interface?]

Revision as of 15:39, 28 June 2017

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 section to a new directory
  • 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.

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.

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.

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.

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.

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.



Solutions

1. Suggested solution:

package com.superpower.filebrowser;

public interface FBPlayable  {

    public void play();

}

2. Suggested solution:

package com.superpower.filebrowser;

public class FBMp3 extends FBFile implements FBPlayable {

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

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

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


3. 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);
    }
    
}

4. 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;
    }

}


5. 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());
        }
        
    }


6. Suggested solution:

package com.superpower.filebrowser.main;

import java.util.List;

import com.superpower.filebrowser.FBPlayable;

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();
        }
        
    }

}


</div> </div>

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

« PreviousBook TOCNext »