public class QuestionFileOutputStream implements AmigoOutputStream {
private AmigoOutputStream amigoOutputStream;
public QuestionFileOutputStream (AmigoOutputStream amigoOutputStream) {
this.amigoOutputStream = amigoOutputStream;
}
@Override
public void flush() throws IOException {
amigoOutputStream.flush();
}
@Override
public void write(int b) throws IOException {
amigoOutputStream.write(b);
}
@Override
public void write(byte[] b) throws IOException {
amigoOutputStream.write(b);
}
@Override
public void write(byte[] b, int off, int len) throws IOException {
amigoOutputStream.write(b, off, len);
}
@Override
public void close() throws IOException {
System.out.println("Do you really want to close the stream? Y/N");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String lineRead = br.readLine();
if (lineRead.equals("Y")) amigoOutputStream.close();
}
}
Andrei
Level 41
Why do I need to close the AmigoOutputStream and not the BufferedReader stream ? I have never seen this before? What happens to BufferedReader stream?
Under discussion
Comments (9)
- Popular
- New
- Old
You must be signed in to leave a comment
Guadalupe Gagnon
14 January 2021, 19:50useful
This task asks that you 'pretend' a little bit. There are many classes in Java that do a lot, but the longer your program the more you will find the provided base classes can't be used to solve an infinite amount of problems. This is why OOP languages allow you to create custom classes where you inherit a base class, which would give you the functionality of that class but allow you to make changes necessary to solve the problem you are given.
In this task you are given an interface, AmigoOutpuStream, which is similar to OutputStream. The task wants you to pretend that the interface's implementation inside the QuestionFileOutputStream is one of these classes that has the functionality that you mostly want, but you are using your own custom class to create additional functionality, such as asking if they are sure they want to close it. The task is a simple example, but you could add any functionality to a class that you want. I do this all the time with by creating a class that extends ArrayList and then over riding the toString() method to output the data formatted the way that I want it formatted instead of the standard formatting.
+1
Guadalupe Gagnon
14 January 2021, 20:02useful
Here I just extended Solution class so that it is an ArrayList and created an overridden toString() method. In the main method I created a standard ArrayList and filled it with some values. Next I created a Solution object (which is now an ArrayList with all the same exact functionality other than the modified toString()) and filled it with the same values. Then I output both of the objects to show the difference. Its simple to do and you can extend nearly all the classes in Java to add functionality as you need or desire.
+1
Andrei
15 January 2021, 08:21
OK, so let me see if I understood this: the AmigoOutputStream interface basically replaces the original OutputStream abstract class(I also saw, write, flush methods).
But then we have to close the InputStreamReader which is a different class.
However, I suppose it doesn't matter the type of Stream open because close() applies to all subclasses of Reader class?
0
Guadalupe Gagnon
15 January 2021, 14:44useful
It doesn't replace, per say, it is more like a copy of it. Interfaces, though, don't actually do anything by themselves. If you look at the code in the AmOutStr interface you are going to see a few methods, but no actual code. Interfaces are sort of like contracts that state that whatever class implements the interface MUST implement the methods that the interface declares, and must also make them as public (you'll get a red squiggly if you remove 'public' from any of those methods in the class). It is important to understand, however, that there is no guarantee that the implemented methods MUST do anything, least of all what you expect. Example:
There is nothing stopping you from writing whatever you want in those methods, or any other programmer from doing so. Following standard and good coding practices, however, means you should be naming and using things meaningfully, and if you create a class that implements an interface with "OutputStream" in its name with those methods, it better work as an OutputStream.
+1
Guadalupe Gagnon
15 January 2021, 14:59useful
You could actually take that code I shared, paste it below line 35 of your code in the QuestionFileOutputStream file (outside the class). Then inside the QuestionFileOutputStream class add a main method:
Line 2 declares a variable of the interface, which is perfectly acceptable, then creates an object of QuestionFileOutputStream. Interfaces cannot be made into objects themselves, so you would need to make a valid object from a class that implements the interface, with that class does. Now the constructor takes an AmigoOutputStream object, which myClass (which has some actual functionality) is also. Then you run the code. The QuestionFileOutputStream delegates all the actual work to the object passed into the constructore, which is the useless myClass. This is just an example.
In real life if you were using a class, such as some random OutputStream, that did what you basically wanted it to do, but you wished it could do just a little bit more to be perfect. You could follow the steps in this task:
- Create a class that implements the same interface of that object
- Make a constructor that takes that object to use in your class
- Copy all the methods but pass the actual work off to the original object
- Add the functionality that you desire +1
Andrei
15 January 2021, 15:31
Thanks, it is a bit clear now and the example your provided was really cool , I copy-pasted it into my IDE and it worked ! đ
One thing is still unclear to me:
How is line 1 closed by line 3 when amigoOutputStream is a standalone interface, with it's own close method? This bit is a bit fuzzy.
I apologize if you have already explained this, I probably haven't understood, and if you have, I will look at your answers tomorrow again because today, after 4 hours of studying I am 'a bit' fuzzy. đ 0
Guadalupe Gagnon
15 January 2021, 15:37
Line 1, the BufferedReader, is not being closed. The AmigoOutputStream object is being closed.
The BufferedReader would still be open in memory until the program ended or Java's garbage collection disposed of it. You can add a line to close it, which would probably be for the best:
+1
Nouser
15 January 2021, 16:10
the task won't validate when closing the reader (afair). I have commented that out in my solution, too.
+1
Andrei
18 January 2021, 08:29
OK, now I understand completely, thank you!
0