I haven't been hungry about Java interfaces for a long time. There are several reasons for this, but one is that it is difficult to grasp where the method described in the implementation class of the interface is executed. So, let's try to find out where to execute with a simple program. The first program I wrote was Java animation, and I was struck by the fact that I used threads at that time. Let's start over from there (it may not be very Java-like, as many sites where Java is used don't seem to be pick-ups like animation). I don't really touch on the thread itself. I thought the explanation on the following pages, which I referred to in this article, is easy to understand. → Use of threads Nor does it mention the benefits of using the ** interface **.
An insubstantial abstract method (interface) -[Where is implemented](# Where is it implemented), ・ [What kind of setup](#What kind of setup is it), ・ Who (which object) ・ At what timing ·Execute Check if.
keyword: Abstract methods, Strategy patterns (Strategy, ConcreteStrategy, Context, Client), Delegate, upcast, execution objects
When it comes to decent animation, the focus cannot be focused on the interface, so a program that simply moves the "○" on the console and outputs it. A space is repeatedly added before the "○" in the infinite loop in the thread, and it is output.
Class, interface | Contents |
---|---|
Runnable interface | Since it is a Java standard interface, no source code is described. |
VerySimpleTextAnimation class | Runnable interface implementation class |
VerySimpleTextAnimationApp class | Execute the Main method |
Thread class | Since it is a Java standard interface, no source code is described. |
VerySimpleTextAnimationApp.java
/*
*Main method only
*Create an instance of a class that implements the Runnable interface
*Specify that instance in the constructor of the Thread class
*Create an instance (thread) of Thread.
*thread instance method start()Execute.
*/
public class VerySimpleTextAnimationApp {
public static void main(String args[]){
/*Create an object that runs as a separate thread*/
VerySimpleTextAnimation verySimpleTextAnimation = new VerySimpleTextAnimation();
/*Create another thread and start the thread*/
Thread thread = new Thread(verySimpleTextAnimation);
thread.start();
}
}
VerySimpleTextAnimation.java
/*
*Implementation class of the Runnable interface.
* Run()Implement the method.
*Animation that ○ gradually moves to the right (intention)
*/
public class VerySimpleTextAnimation implements Runnable {
String x = "○";
public void run() {
while(true) {
x = " " + x;
System.out.println(x);
try {
/*Wait a little*/
Thread.sleep(500);
} catch(InterruptedException e) {}
}
}
}
public void run() {
while(true) {
x = " " + x;
System.out.println(x);
try {
/*Wait a little*/
Thread.sleep(500);
} catch(InterruptedException e) {}
}
}
Inside the VerySimpleTextAnimation class. It implements the run method () that is only defined in the Runnable interface. I don't think this is so difficult. However, I feel uncomfortable with the following points in the implementation contents.
Thread.sleep(500);
Why is it a static method? I will think about this in my own way later. [About # Thread.sleep ()](About # Thread.sleep ())
Next, let's take a look at the VerySimpleTextAnimationApp. First, an instance of VerySimpleTextAnimation class (Runnable interface implementation class) is created. A class that implements the run method we saw earlier.
VerySimpleTextAnimation verySimpleTextAnimation = new VerySimpleTextAnimation();
By the way, it works even if you write as follows.
Runnable verySimpleTextAnimation = new VerySimpleTextAnimation();
This way of writing is called upcast. As I often see, this was also a stumbling block for me, so I wrote it in an article earlier. Upcast and supertype / subtype
I think that the difficulty of attaching an interface is because some elements are often combined in a complex manner in the usage situation.
Thread thread = new Thread(verySimpleTextAnimation);
It is also possible to write ** new class name ** directly in the argument without declaring an instance of the interface implementation class as a variable.
Thread thread = new Thread(new VerySimpleTextAnimation());
Here, create an instance of Thread class. At that time, the verySimpleTextAnimation created earlier is included in the argument of the constructor, but what is the type of this argument in the first place?
So, let's take a look at the Thread class constructor in the Java documentation.
public Thread(Runnable target) Parameters: target --An object that contains the run method that will be called when this thread starts.
** Defined to take an instance (target) of type Runnable as an argument **. Also, the parameter description says ** an object containing the run method **. This time, verySimpleTextAnimation is included in the argument of Thread's constructor. The run method ** that this instance contains ** is a fake animation implemented here. I felt quite uncomfortable with the ** method that defines the interface type in the argument like this constructor. I didn't understand the meaning of using an abstract method as an argument, and the interface itself should not have been instantiated in the first place. This involves the upcast mentioned earlier. If a method's arguments are of type interface, it is intended to be an implementation class instance of that interface. It took me some time to notice this.
thread.start();
Take a look at the start () method in the documentation
public void start() Starts running this thread. The Java virtual machine calls the run method of this thread.
It says ** call the run method of this thread **. It's called ** Delegate ** that entrusts the specific processing content to the run method.
So, let's see the explanation of the run () method.
public void run() If this thread was created using a separate Runnable run object, the run method of that Runnable object is called.
** When created using a separate Runnable run object ** should be when the instance was created by specifying the Runnable type target in the constructor. run () is executed by the start () method. The content of the run () method is the content implemented in the instance entered in the constructor. By the way, the name ** Runnable execution object ** is interesting. Do you call an instance of the interface implementation class that way?
VerySimpleTextAnimationApp class
When thread.start () is called in the Main method. In this example, it is easy to follow the execution timing, but it is better to leave the good timing to the Client (see [Strategy pattern table](#Strategy pattern)) that entrusted the execution object such as event processing and asynchronous processing.
The structure of the class is as follows in terms of Strategy pattern.
role | Class, interface | Contents |
---|---|---|
Strategy(strategy) | Runnable interface | Since it is a Java standard interface, no source code is described. |
ConcreteStrategy(Specific strategy) | VerySimpleTextAnimation class | Runnable interface implementation class |
Context(Situation judgment) | VerySimpleTextAnimationApp class | Execute the Main method |
Client(user) | Thread class | Since it is a Java standard interface, no source code is described. |
Reference: Strategy pattern Since the content of this article does not consider Strategy-like things, it is very doubtful whether it can be called a Strategy pattern, but since it has the same shape, it is easy to apply if there is such a pattern in the corner of the head. May become. You will have to follow the code to understand the contents of the program. It's easy to follow if you follow the chords linearly, deeply and deeply, but until you get used to it, you'll be forced to go back and forth and pull back, and your concentration will be reduced. I feel that the only way to overcome this is to get used to it, but I think that understanding the design pattern will improve the outlook (although it is difficult to grasp).
About Sleep processing of Java Thread class I understand the discomfort of this questioner, and for me, the answer here does not solve it. It seems strange that the execution instruction of the static method controls the operation of each instance. After all, I don't know the exact reason, but probably because this static method is called on an individual instance (here an instance of VerySimpleTextAnimation), you can determine which Thread instance the sleep instruction is for. I think it will be. Please let me know if anyone knows.
In the past, I had the image that Thread was animating, but if you follow the process flow again, it is the while loop of the run method that realizes the animation. I'm adjusting the frame rate with Thread.sleep ().
To implement an interface, just write implements between the class name and the interface name, and the implementation content is the same as writing other methods. In this article, I used the existing interface (Runnable), but if you can write a class even if you make it yourself, it is not particularly difficult. In other words, it's not difficult to write, but rather easy. As the name "interface" implies, the role is ** to connect the objects **, and to be like a non-existent ** protocol ** (in Swift, it plays a similar role). There is an object called ** Protocol **). Since there is no substance, nothing can be understood by looking at the interface alone. In order to understand the interface, it is necessary to be able to image ** between ** objects, which requires imagining a combination of multiple objects. It's difficult to think of complicated combinations without getting used to it, so if you think about it in a simple way, the composition is simple, but I don't understand how grateful it is (as can be said in this article), and it just looks like a messy way of writing. In the actual usage situation, the combination becomes complicated and other factors (generics, etc.) are involved, which makes it difficult to focus. Also, I think this is due to the position of the language Java rather than the interface, but it is not very attractive to beginners (maybe it makes me angry), and there are many explanations from an SIer perspective. Java has a descendant called Processing, so after a paragraph, I would like to write an article about the interface from that perspective.
Recommended Posts