I always wonder how just by implementing an interface , sub class acquires the behavior. For example if I implement Runnable interface my subclass start behaving as thread, but what if I implement all the methods defined in interface Runnable but not write "implementing Runnable", subclass doesn't behave as Thread. Same with EventListeners . Please help me understanding this behavior.
By implementing an interface I, you're declaring that the Object "is a" I and that it'll contain all the methods defined by this interface. If you just implement the methods of the interface I, but don't declare it by an implement statement, compiler won't be able to determine that your class "is a" I and you won't be able to use it as a I-type.
No, Runnable has nothing to do with behaving like a thread. It just contains a plain, simple, void nullary method called "run".
Not specifying implements Runnable will just make your object not an instance of the Runnable type, which means you won't be able to pass it to a method requiring a Runnable. This is just an issue of type safety. The method you call could also accept an Object and invoke run using reflection, with the exact same behavior.
When you are implementing Runnable your class does not become thread and does not start behavior as thread. However if your class implements Runnable you can run it in context of thread:
class MyClass1 implements Runnable {
public void run() {
// this stuff will run in thread when thread's start() method is called
}
}
new Thread(new MyClass1()).start();
But java is strongly typed language. You can just create class like this:
class MyClass2 {
public void run() {
// this stuff will run in thread when thread's start() method is called
}
}
But it will not be Runnable. Therefore you cannot just send it to thread:
new Thread(new MyClass2()).start();
In this case you will get compilation error. Compiler cannot know that your class indeed implements method that looks like one that is declared in Runnable. You must declare this (as in first case).
A Runnable only allows your class to be run in a Thread. You still need e.g. a java.util.concurrent.Executor to actually run it in an actual Thread.
However, you can extend Thread which would allow you to call Thread.start().
To actually get out behavior from just implementing an interface, you would need a second object inspecting the classpath for classes implementing your interface using reflection, and then do something with that class.
Your question has two aspect:
Interface as a contract: Interfaces imposes a behavioral contract on a class implementing it. For example, If Car is an interface with some methods abstractly defining a car, any class implementing Car interface will have to define the methods of the car. You are free to actually implement the behavior.
Analogy of Runnable acting as thread is incorrect. What makes Runnable class act as thread is the the Thread class. Runnable just specifies the contract for a class to act as thread. Check this post.
This is not a subclassing behavior. In order to use subclass behavior you need to extend the class.
W.r.t interfaces these are just templates/contracts that are implemented by class. In order for runnable to work calling program need to instantiate a thread and when thread will start it will call run method implemented by your class.
I always wonder how just by implementing an interface , sub class acquires the behavior.
It doesn't 'acquire' any 'behaviour'. The subclass provides the behaviour. What implementing the interface does is provide the compile-time type signatures such that you can use the subclass where the interface is specified.
Related
I know how anonymous functions work in JS and all but a bit confused on parts of it in Java.
So below I have an anonymous class (I'm just using the Thread class as an example to what I've seen), where I override the run() function and then call .start() on that class.
new Thread() {
#Override
public void run() {
System.out.println("Hello from the anonymous class thread");
}
}.start();
So this works, but IntelliJ wants to me re-write it as this:
new Thread(() -> System.out.println("Hello from the anonymous class thread")).start();
I get most of this syntax, but just a bit confused as to how the run() function is being overridden. From my understanding, there is no parameter being passed into the Thread class (so nothing being passed into the constructor I'm assuming). Now where I'm confused is here. It doesn't state anywhere that it is overriding the run() function. Is this a special case for the Thread class or is there something I am missing?
Hope that I explained this clearly and thanks in advance!
The syntax that IntelliJ proposes to you is not more of an "oblique" translation of your original code, and does not actually override Thread.run like your original code does.
Your original code creates an anonymous subclass of Thread with run overridden, whereas the proposed syntax by IntelliJ calls this constructor of Thread that accepts a Runnable. The lambda expression represents the Runnable. If we "expand" the lambda expression into an anonymous class, we will be actually doing this:
new Thread(new Runnable() {
#Override
public void run() {
System.out.println("Hello from the anonymous class thread");
}
}).start();
So we are creating an anonymous implementation of Runnable, and implementing Runnable.run instead.
It doesn't state anywhere that it is overriding the run() function.
True, but run is the only abstract method in the Runnable interface, so Java is able to figure out that you are overriding that method.
The run() function is being overridden implicitly because it's the only method of the Runnable interface, which makes it a functional interface. A functional interface has exactly one abstract method. This special property of an interface allows you to implement it implicitly using a lambda expression. The compiler knows you're providing an implementation of the Runnable.run() method, because it's the only method inside the interface.
If you take a look at the Runnable interface, you'll see that it is decorated with the #FunctionalInterface annotation. This annotation ensures that the decorated interface can never have more than one abstract method (or else the compiler will fail). Note that this annotation is not required in order for the implicit lambda feature to work.
When I searched on the internet about extending the Thread class, all the examples I came across had overridden the run() method. I have also extended the Thread class in my program but I haven't defined the run() method. It's just another class (I'll refer to it as MyClass), which extends Thread class, with a constructor and a few methods defined by me. However, I'm puzzled because I have created an object of MyClass in the Main class and have called the start() method using that object in main() method. And it still works.
My question is whether the run() method is implicitly defined by the Java compiler, like the default constructor, or is it simply not required to be overridden when extending the Thread class?
No, the run() method is not implicitly defined by the Java compiler. It is explicitly defined by the Thread class.
If this thread was constructed using a separate Runnable run object, then that Runnable object's run method is called; otherwise, this method does nothing and returns.
It is not abstract, so it does not need to be overridden. There is nothing special about the run method here.
Because you're extending Thread and not supplying a separate Runnable, your class inherits the run method; run runs and does nothing.
Because it does nothing, it's not very useful. Usually you want to do something in your Thread, so normally when creating a Thread this way, run is overridden to do something useful.
It confuses me why a subclass of thread that implements a runnable interface doesn't force me to override the run method. Basically, when i create simple class that implements Runnable it forces me to override the run method. But when i made the ordinary class a subclass of thread, it didn't force me to override the class anymore. What's the logic behind this?
When a non-abstract class declares that it implements an interface, what that means is that the class must have a concrete implementation of every method that the interface defines, but those implementation methods don't have to be explicit in the class, they could be inherited from a superclass. In this specific example java.lang.Thread has its own public void run(), which subclasses inherit, so a subclass of Thread that implements Runnable doesn't need to add its own override to satisfy the compiler (though it probably does to actually be useful).
This is because Thread itself implements run().
#Override
public void run() {
if (target != null) {
target.run();
}
}
By default it does nothing. If we extend a Thread we implement this method so that it does something useful
When a class implements an interface, does that make objects instantiated from the class be perceived as an object of that Interface?
i.e. Upon a class implementing the Runnable interface, does that make instances created from that class to be called a Runnable object?
So, where a Runnable object reference variable is expected (say, in the parameter of a method or a constructor), why is it legal that we can provide an instance of the class as an argument to that method or constructor? Is it because by implementing the interface, the class, is in essence, an object of the Interface?
An object of a class C that implements an interface I can be called an object of that interface, although a single object can be of many interfaces. Liskov substitution principle requires C to be usable anywhere where I is required, so in essence I becomes a contract of C, representing a subset of Cs abilities, as applicable to a certain situation.
For example, when an object implements Runnable, the run() method in the interface presents a particular aspect of the class to Java class library - namely, that objects of the class can be "ran" (by calling run() on them). The presence of Runnable lets you code the logic of your thread independently of Java designers, who write their thread-execution code independently of your implementation's logic.
The reference to a Runnable is possible since the Runnable object must have all methods in the Runnable interface implemented.
This way you can access all those methods at run time.
If the class that is said to implement Runnable would somehow not implement Runnable - there would be a compilation error, as Java Language Specification 7 chapter 8 (classes) - 8.1.5 (superinterfaces) specifies:
A class is said to implement all its superinterfaces.
The example given is the following:
Example 8.1.5-3. Implementing Methods of a Superinterface
interface Colorable {
void setColor(int color);
int getColor();
}
class Point { int x, y; };
class ColoredPoint extends Point implements Colorable {
int color;
}
This program causes a compile-time error, because ColoredPoint is not an abstract class but fails to provide an implementation of methods setColor and getColor of the interface Colorable.
If a class implements an interface, it can be used in any place where the interface type can be used. For example, if an class implements Runnable, then an instance of that class can be used anywhere where a Runnable can be used. This is an example of polymorphism.
For example, here is a class that implements Runnable:
public class MyRunner implements Runnable {
public void run() {}
}
You can use MyRunner like follows:
MyRunner runner = new MyRunner();
// can assign to a field of type "Runnable" without a cast
Runnable runnable = runner;
// can pass to methods that take a Runnable
Executors.newFixedThreadPool(3).execute(runner);
The MyRunner class is said to be an instance of Runnable. You even can check this via reflection;
public void runIfIsRunnable(Object object) {
if (object instanceof Runnable) {
Runnable r = (Runnable) object;
r.run();
}
}
Using instanceof is often considered a code smell, but there are situations where it is useful, like when you create instances of a class via reflection.
Objects inherit their parent classes interfaces, and methods from those interfaces can be overridden in sub classes.
The Value of interfaces is that they allow for methods to be created that accommodate a variety of object classes as input, by accepting the interface type as input.
Any object that implements an interface is in fact "interface"able for the given interfaces it implements.
The implementation of an interface by a class implies the ability of that class to perform any methods specified within the interface. As such any method that runs on the interface can run on something implementing the interface.
An interface establishes a contract that the object will contain the methods defined in the interface and this contract is enforced by the compiler. So the compiler will check for this.
By convention, interfaces end in "-ible" are "-able" to show this behavior (though this by no means is a hard rule). But in the end, the type of the object is either java.lang.Object or a direct/indirect extension of it. If you look at the inheritance tree on any Javadoc, you'll see the hierarchy of classes extending one another and known implementing classes of interfaces.
So one doesn't normally speak of objects created by the class as objects of an interface, but rather that the class implements one.
Look at the following code from the ThreadFactory interface
public Thread<T> newThread(Runnable<T> runnable);
What does s the type parameter convey here ? I mean Collection makes sense since T is specifying the type of objects that can go into the Collection but what does Runnable or Thread mean ?
In ThreadFactory.newThread(Runnable) there is no generic type, nor is Runnable or Thread a generic interface/class. The original must have been in error.
Thread class you are creating,it has to be the subclass of some other class, it can’t extend from the Thread class. This is because Java does not allow a class to inherit from more than one class. That's why Runnable interface to implement threads.
For better understanding,just take a look of these two links this1 and this2
It does not look like Runnable this was intended with the Runnable interface. Maybe you are getting confused with Callable. Here the generic type will be the type returned.