subclass of thread implementing Runnable interface - java

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

Related

Whose method gets overridden when a derived class extends a base class and at the same time implements an interface?

Case 1:
I have an Interface Inter.java:
interface Inter
{
void abcd();
}
A base class:
class Base
{
void abcd()
{
System.out.println("Base abcd");
}
}
A Derived class:
class Use extends Base implements Inter
{
void abcd() //intentionally not using public
{
System.out.println("Use abcd");
}
public static void main(String[] args)
{
Use u = new Use();
u.abcd();
}
}
Now I compile it:
gyan##ns:~/Desktop$ javac Inter.java Base.java Use.java
Use.java:3: error: abcd() in Use cannot implement abcd() in Inter
void abcd()
^
attempting to assign weaker access privileges; was public
1 error
gyan##ns:~/Desktop$
That means the overridden method abcd() in the class Use is from the implemented interface "Inter" and not from the base class "Base".
Case 2:
We have a file Test.java containing following codes:
interface Ab
{
void run();
}
class A extends Thread implements Ab
{
public void run()
{
System.out.println("class A");
}
public static void main(String[] args)
{
A a = new A();
Thread t = new Thread(a);
t.start();
System.out.println("main method");
}
}
When we execute it we got:
gyan##ns:~/Desktop$ java A
main method
class A
gyan##ns:~/Desktop$
Since t.start() executed the method run(), that means method run() of the class Thread got overridden. But in the case 1 method abcd() of the interface "Inter" got overridden.
In case 1: Whose method abcd() is overridden in class Use? Class Base or interface Inter? Error says we are overriding the abcd() of interface Inter. But in case 2: It seems that we are not overriding the method run of interface Ab. Because we can execute the run() method by calling t.start(). Which is only possible if we are overriding the run() of class Thread.
The method in your class overrides the base class method and implements the interface, at the same time.
Overriding a method is not exactly the same as implementing an interface :
Overriding a method from a superclass means you are replacing its implementation. If you are not providing an overriding method, the implementation from the superclass (which can be empty) will be used.
When implementing an interface method, you are providing code for a simple declaration (without any implementation). If you declare a not-abstract class as implementing an interface, but don't provide an implementation for every method of the interface, compilation fails. This is less true in Java 8, where you can optionnally provide a default implementation in interfaces, but in this case any implementation from a superclass would win.
Implementations and overrides of a method can always extend its visibility, but not decrease it. This means :
a package-private (default visibility), or protected method in a superclass can be made public in the subclass
but a public method in a superclass cannot be made package-private or protected in the subclass.
Methods in an interface are always public, even if the "public" modifier is not specified in the interface. Hence, their implementations must also be public => that's the error you get in your case 1
As a side note, in your case 2, you are using threads wrong. Do not subclass Thread. Instead, create a class implementing the Runnable or Callable interface, and submit it to a thread pool (see classes in java.util.concurrent, or for a quick test use java 8's ForkJoinPool.commonPool().submit(myTask).
Both. Method overriding depends on the name and signature of the method not where it is defined. If defined on more than one ancestor, it overrides both.
Note: If defined as public in one and protected in another, it'll become public.
In the Inter interface, void abcd(); is the definition of an abstract method. All abstract methods are inherently public.
From {Defining an Interface},
All abstract, default, and static methods in an interface are implicitly public, so you can omit the public modifier.
So, while Inter said that abcd() was public, the actual implementation in Use is saying that the implementation of abcd() is package-private, which is a weaker access privilege. This should address your comment "//intentionally not using public".
Traditionally, abcd() should also use the annotation #Override (although it is not a hard requirement).
In your second example, Thread class provides a concrete implementation of run(). Given that A#run() is public, you have satisfied the requirement imposed by interface Ab regarding access specifiers. Then, A#run() went on to override Thread#run() - which is exactly how we would expect inheritance to behave.
To summarize, we just saw the difference between extends (extending or overriding class methods) and implements (contract that the given class provides an implementation for all the methods states in the interface). {This answer} goes into more depth about this and is an excellent read.
Let me know if any part of this answer needs more clarity.

Implementing Interfaces and Objects

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.

how just by implementing an interface subclass acquires the behaviour

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.

Require override of specific methods of a non-abstract class

Is it possible to have a class defined like
public class MyClass
{
public void methodA(){} // Inherit
public void methodB(){} // Inherit
public void methodC(){} // Require override
}
and then have all classes which extend from MyClass to be required to override methodC() but just simply inherit methodA() and methodB()?
If it is possible, how does one do it? If it's not possible, can you propose an alternative solution to achieve a similar result?
EDIT:
I need a non-abstract class because I want to be able to instantiate this class too.
You would have to make your base class abstract.
public abstract class MyClass
{
public void methodA(){} // Inherit
public void methodB(){} // Inherit
public abstract void methodC(); // Require override
}
You cannot require an override of a non-abstract method.
Maybe you can do something similar to the template method pattern:
public final void methodC() { methodC1(); someMoreLogic(); methodC2();}
protected abstract void methodC1();
protected abstract void methodC2();
Here methodC encapsulates a fixed algorithm that calls into pieces that have to be supplied by the subclasses.
I don't think you do exactly what you want. Alternatively, create MyBaseClass as an abstract class with methodC() abstract implementations for methodA() and methodB(). Derive MyClass from it, adding an implementation for methodC(). Any classes that you do not want to have inherit that implementation should directly subclass MyBaseClass rather than MyClass.
If you want a method to be just inherited use final keyword. To force overriding make it abstract. However, only non-abstract child classes will have to override it.
AFAIK there is no way to force override a method in Java with out abstract.
You can achive with abstract class by making the method as abstract method.
one way to do it may be to use virtual keyword instead of abstract but it doesnt require to override, but you can do override. though so, you can instantiate.
another way and more recommended is to create an interface where you can indicate what the class requirements. it is something like abstract, you indicate what to require, but keep in mind interface is not a class. it's more like pointer. for more for interface click: https://docs.oracle.com/javase/tutorial/java/concepts/interface.html
So, java.lang.Thread is a concrete class that implements the Runnable interface. Therefore, it must be that Thread implements a public void run() method. Yet, when you extend Thread, like MyClass extends Thread { }, you are required to implement the run() method.
It stands to reason that there is a way to force overriding of a method without making the containing class abstract.

Forcing subclasses of my class to override only certain functions in Java

I have a class, let's say
public class GeneralClass<T> {
methodA() {...}
methodB() {...}
methodC() {...}
}
and I'm deriving from this class
public class MoreSpecificClassString extends GeneralClass<String> {
methodD() {...}
methodE() {...}
methodF() {...}
}
public class MoreSpecificClassInt extends GeneralClass<Integer> {
methodX() {...}
methodY() {...}
methodZ() {...}
}
Now, what I would like to know if it is possible to force the subclasses of GeneralClass to override only one method, such as methodA?
Thanks
Yes. Make methodA abstract and make GeneralClass an abstract class. If you want to prohibit overriding methodB and methodC, mark them as final.
Edit
If on the other hand you want to be able to provide a default implementation of methodA, and also require subclasses to override it, you are essentially violating the Liskov Substitution Principle. You need to reevaluate why you require this design, because it smells pretty bad. For example, there would be absolutely nothing preventing your subclass from just overriding your method like this:
#Override
public void methodA() {
super.methodA();
}
And if the re-implementation can just call the super class' default implementation, what was the point in forcing it to be overridden in the first place?
It's for this reason (among others) that it's not possible to provide a default implementation and require subclasses to override it. Rethink your design.
Yes, make GeneralClass an abstract class, with implementations for the other methods.
Example:
abstract class ABC {
abstract int methodA();
final int methodB() { ... implementation ...}
}
For forcing just a one - make this method abstract ?
You have several tools available:
You can declare a method (and the base class) abstract. Concrete classes will be forced to implement the method.
Declare non-overrideable methods final. Derived classes cannot override these methods.
Combine 1 & 2: declare a method final and have it delegate part of its work to an abstract method. (This pattern is often used with an empty method instead of an abstract method to implement so-called "hooks" into otherwise fixed logic.)

Categories