As
SeekableByteChannel is an interface,how are we invoking its methods from Files class's newByteChannel method.
I Know how to invoke it .But i cant understand the concept because an interface doesn't implements the behavior
1 more Question.I have seen many times in java example code that interface methods are invoked or called.But as far as i know interface doesn't initialize or implements the methods.
SeekableByteChannel idd = Files.newByteChannel(file);
idd.size();
How does the above code works because SeekableByteChannel is an interface and Files class doesn't implement the methods of SeekableByteChannel .So where SeekableByteChannels methods are initialized.
Please Help
An interface in Java is nothing more but a contract; at the compiler level, the only contract is that if you implements an interface, you must have an implementation of all methods (for classes which are not abstract):
public interface Foo
{
/*
* Any invocation of this method sends the instance to the moon
*/
void foo();
}
If you have a concrete class which you can instantiate and which implements Foo, such as:
public class MyClass
implements Foo
{
// must implement foo()
#Override
public void foo() { stayOnEarth(); }
}
then you can do:
final Foo foo = new MyClass();
As you have a reference to an instance of type Foo, it means you can invoke foo() on it:
foo.foo();
The JVM will look up method foo() and find it.
Now: the fact that you have implemented foo() is one thing; the fact that you obey the contract of this interface is another. The compiler does not give a <beep> if you stay on Earth or go right to Antares: it cannot enforce that.
This is a question of trust first and foremost: if you implement an interface, you are expected to understand what this interface means; which is why there is documentation. The compiler cannot help any further but to enforce that you at least implement the needed methods.
It seems your underlying question is how do interfaces work. The common buzzword that goes with interfaces is "contract". If your class implements an interface, it implements this contract. The contract means that the class MUST define the functions declared in the interface. Thus if we have -
Interface InterfaceTest{
void foo();
}
Class Implementer implements InterfaceTest{
the class Implementer MUST implement the function foo() or there will be a compiler error -
void foo(){
//Do stuff.
}
Note that Files does not implement SeekableByteChannel. So Files does not have any relation to it. Thus Files can have any functions it wants, including ones in SeekableByteChannel without issue.
Related
Why the superclass run method is called without error in the following code?
public interface ISchedulingTask {
public void run();
}
public class SerialTask {
public void run(){
System.out.println("SerialTask");
}
}
public class SchedulingTask extends SerialTask implements ISchedulingTask {}
public class SchedulingTaskPane {
public SchedulingTaskPane(ISchedulingTask task){
task.run();
}
}
#Test
public void test(){
SchedulingTask task = new SchedulingTask();
SchedulingTaskPane paneProduction = new SchedulingTaskPane(task);
}
The code outputs SerialTask without any problems, but I don't understand this behavior. Why is a super class method called, even though the constructor specifies ISchedulingTask?
SchedulingTask is the child of SerialTask, and both the class now inherits from the interface, makes them type of ISchedulingTask. The only implementation of run() method is in the SerialTask. Now you are passing instance of SchedulingTask while creating instance of in the SchedulingTaskPane, on which you are invoking run method. Now SchedulingTask does not override the implementation of its parent class, so it would have to rely on super class. I hope this explains.
This works as expected. Take a look at the Java Tutorial for Interfaces
Interfaces in Java only describe a certain "contract", i.e., every class implementing an interface has to offer all the methods in the interface.
SchedulingTask extends SerialTask, so the method SerialTask.run is now part of SchedulingTask. SchedulingTask implements the interface ISchedulingTask - this means "I sign a contract that I have all the methods in ISchedulingTask". This "contract" is fulfilled, because SchedulingTask inherits the method from SerialTask.
Remember, inheritance ("extends") represents a "is a"-relationship, i.e., a SchedulingTask is a SerialTask.
Looking at SchedulingTask it is a class that extends the SerialTask parent class, and it also declares that it implements the ISchedulingTask interface. By implementing an interface all that it means is that SchedulingTask promises to implement the interface so anyone using that class can know there is a run() method in it. Note that the interface does not actually implement the run function, it simply declares that it exists in that specific signature (takes no parameters and returns nothing).
Since SerialTask implements the run public function then anything that extends it will also have that implementation. In fact in the code you gave that is the only place that the run function is actually implemented.
Note that SchedulingTask does not implement the run function though it says it implements the interface. Normally this would be a compile-time error since the class doesn't implement the required interface functions, but since its parent does have it, all is good and that's the function that gets used at rutime.
A better way to arrange things would be to make the SerialTask class implement the ISchedulingTask interface since that's where it really is implemented. Since SchedulingTask is extending it, it automatically implements the interface also, so nothing really changes in terms of how users of SchedulingTask see its functionality but it's more clear about where the run function is from.
Note that any subclass that extends the parent or implements the interface is free to implement their own version of the run function and that the runtime will use the first one that it comes across.
The run function is searched for in this order:
SchedulingTask.run -> doesn't explicitly exist in the class
parent: SerialTask.run -> does exist so is used
Because of the SchedulingTask inherited SerialTask class, SchedulingTask considers have an implementation to the run method. So it's run successfully.
But if you removed the run method from SerialTask class will cause a compile-time error, you have to implement run from ISchedulingTask.
I'm confused why the following is not allowed:
public interface MyInterface {
MyInterface getInstance(String name);
}
public class MyImplementation implements MyInterface {
public MyImplementation(String name) {
}
#Override
public static MyInterface getInstance(String name) { // static is not allowed here
return new MyImplementation(name)
}
}
I understand why a method in the interface cannot be static, but why can't the overriding method be?
I want all classes to implement the getInstance(String name) method, but I'm currently limited to only being able to call the method if the object has already been instantiated which kind of defeats the purpose...
*update:* Thanks for the answers, I understand it better now. Basically I shouldn't be trying to make a utility class (or a factory class for that matter) implement an interface (or at least, not in this way)...
Invoking static methods in Java requires you to specify the exact type. It is not possible to invoke static methods polymorphically, eliminating the need for #Override.
Please note that this approach is not universal across all languages: for example, you can override class methods in Objective-C, and Apple's cocoa frameworks make good use of this mechanism to customize their "factory" classes. However, in Java, C++, and C# class methods do not support polymorphic behavior.
Theoretically, Java designers could have let you provide interface method implementations through static methods in case an implementation does not need to access the state from the instance. But the same behavior is simple to achieve with a trivial wrapper:
public class MyImplementation implements MyInterface {
public MyImplementation(String name) {
}
#Override
public MyInterface getInstance() { // static is not allowed here
return getInstanceImpl();
}
public static getInstanceImpl() {
return new MyImplementation(name)
}
}
Java compiler could have done the same thing on your behalf, but seeing a static method implement an instance method is both unusual and confusing, so my guess is that Java designers decided against providing this "piece of magic".
Static methods cannot be subject to polymorphic behavior. That would not make much sense. Image this use case, assuming what you want would be possible:
public void foo(MyInterface i) {
i.getInstance("abc");
}
now I want to call this method with an implementation of MyInterface (class A), but since I cannot pass the class itself, I need to pass an object:
A a = new A();
foo(a);
now inside foo the static override of getInstance is called on the instance of class A. So now I am stuck with creating an object just to call a static method.
My point is that you would still be constrained to create an object in most use cases of polymorphism since in your original interface the method was an instance method.
because implementing an interface makes the implementor the type of the interface. That means instances need to have the methods defined by the type, not the class of the instances.
To put it another way,
public void mymethod
and
public static void mymethod
are NOT the same method declaration. They are completely distinct. If mymethod is defined on an interface, having the second definition simply does not satisfy implementing the interface.
The answer comes down to what it means to implement an interface. When a class implements an interface, that is a promise that every instance of the class will respond to every method in the interface. When you implement the method as static, you make it possible to call the method without an instance of the class - but that doesn't fulfill the inheritance implementation's promise that the method will be callable on every instance of the class.
A Concrete class typecasted to interface, does JVM still consider it a instance of concrete class ?
When you create an assignment, the type of the assignment is inferred based on the type given. E.g. MyInterface mi = new MyImplementation(); mi in this case is typed as the interface, but refers to the implementation. The JVM will know that the instance points to an implementation if you do instance of.
Before I answer the specific question, note that implementations of interfaces are can be passed anywhere the interface type is accepted. i.e. if Impl implements Interface, Impl isA interface, so why would you cast to the interface type? It would be completely unnecessary. I have seen situations where you would cast to a specific implementation, but not from implementation to interface, and even those situations are dicey.
I had to verify this with the following code, but no, if you have an interface implementation, and you cast it to the interface, anything that requires the implementation will get a compile time error if you try to pass as the interface. Here is the code
public class Runner {
public static void main(String[] args) {
ExampleImpl impl = new ExampleImpl(); // never do this in real life
// Example impl = new ExampleImpl() <-- do this instead "code to the interface"
Example casted = (Example) impl;
takesExampleImpl(casted); // compile error because takesImpl expects the implementation
takesExampleImpl(impl); // works because impl is an implementation
takesExampleImpl((ExampleImpl)casted); // works because I cast it back to imple
}
public static void takesExampleImpl(ExampleImpl instance){
}
static class ExampleImpl implements Example {
public void testMethod() {
System.out.println("impl");
}
}
}
Example is just a simple interface with one method, code not shown.
Also, note that my code answers the question, it does a lot of things wrong--you wouldn't see code like that in a professional setting (or you shouldn't at least). The point of interfaces is so that you can define the behavior, and just pass in an object that conforms to that behavior. So you would not write a method that accepted an implementation, you would write a method that accepted the interface, to which you could pass anything that provided the implementation. That way you can pass different implementations to the same method as the need might arise.
What is the fragile base class problem in java?
A fragile base class is a common problem with inheritance, which applies to Java and any other language which supports inheritance.
In a nutshell, the base class is the class you are inheriting from, and it is often called fragile because changes to this class can have unexpected results in the classes that inherit from it.
There are few methods of mitigating this; but no straightforward method to entirely avoid it while still using inheritance. You can prevent other classes inheriting from a class by labelling the class declaration as final in Java.
A best practice to avoid the worst of these problems is to label all classes as final unless you are specifically intending to inherit from them. For those to intend to inherit from, design them as if you were designing an API: hide all the implementation details; be strict about what you emit and careful about what you accept, and document the expected behaviour of the class in detail.
A base class is called fragile when changes made to it break a derived class.
class Base{
protected int x;
protected void m(){
x++;
}
protected void n(){
x++; // <- defect
m();
}
}
class Sub extends Base{
protected void m(){
n();
}
}
It is widely described in below article By Allen Holub on JavaWorld
Why extends is evil.
Improve your code by replacing concrete base classes with interfaces
All of what Colin Pickard said is true, but here I want to add some of the best practices when you are writing code that may cause this kind of issue, and especially if you are creating a framework or a library.
Make all your concrete classes final by default, because you probably don't want them to be inherited. You can find this behavior as a feature of many languages, such as Kotlin. Besides, if you need to extend it, you can always remove the final keyword. In this way the absence of final on a class can be interpreted as a warning to not rely on specific functionality for other methods on this that are not private and/or final.
For classes that cannot be marked as final, make as many methods as possible final to ensure they're not modified by subclasses. Additionally, do not expose methods that are not meant to be overridden—prefer private over protected. Assume that any method not private and/or final will be overridden and ensure that your superclass code will still work.
Try to not use an inheritance ("Bar is a Foo") relationship. Instead use a helper ("Bar uses a Foo") relationship between your classes. Use interfaces rather than abstract classes to ensure that classes using this helper have a uniform interface.
Remember that almost* every extends can be replaced by implements. This is true event when you want to have a default implementation; an example of such a conversion is shown below:
Old Code:
class Superclass {
void foo() {
// implementation
}
void bar() {
// implementation
}
}
class Subclass extends Superclass {
// don't override `foo`
// override `bar`
#Override
void bar() {
// new implementation
}
}
New Code:
// Replace the superclass with an interface.
public interface IClass {
void foo();
void bar();
}
// Put any implementation in another, final class.
final class Superclass implements IClass {
public void foo() {
// implementation for superclass
}
public void bar() {
// implementation for superclass
}
}
// Instead of `extend`ing the superclass and overriding methods,
// use an instance of the implementation class as a helper.
// Naturally, the subclass can also forgo the helper and
// implement all the methods for itself.
class Subclass implements IClass {
private Superclass helper = new Superclass();
// Don't override `foo`.
public void foo() {
this.helper.foo();
}
// Override `bar`.
public void bar() {
// Don't call helper; equivalent of an override.
// Or, do call helper, but the helper's methods are
// guaranteed to be its own rather than possibly
// being overridden by yours.
}
}
The advantage of this is that the methods of the superclass are able to be sure they are working with one another, but at the same time you can override methods in your subclass.
*If you actually wanted the superclass to use your overridden method you are out of luck using this approach unless you also want to reimplement all of those methods on the "subclass". That said, the superclass calling the subclass can be confusing so it may be good to reevaluate that type of usage, its incompatibility with this approach notwithstanding.
Are there some practical programming situations for someone to declare a class abstract when all the methods in it are concrete?
Well you could be using a template method pattern where there are multiple override points that all have default implementations but where the combined default implementations by themselves are not legal - any functional implementation must subclass.
(And yes, I dislike the template method pattern ;))
An abstract class is a class that is declared abstract - it may or may not include abstract methods. They cannot be instantiated so if you have an abstract class with concrete methods then it can be subclassed and the subclass can then be instantiated.
Immagine an interface whose declared methods usually show the same default behavior when implemented. When writing a class that needs to support the interface you have to define said default behavior over and over.
To facilitate implementation of your concrete classes you might want to provide an abstract class providing default behavior for each method. To support the interface in a concrete class you can derive from the abstract class and override methods if they deviate from the standard behavior. That way you'll avoid the repeated implementation of the same (redundant) default behavior.
Another possible use case is a decorator which delegates all calls to the wrapped instance. A concrete decorator implementation can override only those methods where functionality is added:
public interface Foo {
public void bar();
}
public abstract class FooDecorator implements Foo {
private final Foo wrapped;
public FooDecorator(Foo wrapped) { this.wrapped = wrapped; }
public void bar() { wrapped.bar(); }
}
public class TracingFoo extends FooDecorator {
//Omitting constructor code...
public void bar() {
log("Entering bar()");
super.bar();
log("Exiting bar()");
}
}
Although I don't really see the necessarity to declare FooDecorator as abstract (non-abstract example: HttpServletRequestWrapper).
Previous answers already hit the main issues, but there's a minor detail that might be worth mentioning.
You could have a factory that returns instances of (hidden) subclasses of the abstract class. The abstract class defines the contract on the resulting object, as well as providing default implementations, but the fact that the class is abstract both keeps it from being instantiated directly and also signals the fact that the identity of the "real" implementation class is not published.
Wondering why no one has pointed to the Practical Example of MouseAdapter:
http://docs.oracle.com/javase/6/docs/api/java/awt/event/MouseAdapter.html
An abstract adapter class for receiving mouse events. The methods in
this class are empty. This class exists as convenience for creating
listener objects.
Nice question :)
One thing is for sure ... this is certainly possible. The template suggestion by krosenvold is one good reason for doing this.
I just want to say that a class must not be declared abstract just for preventing it's instantiation.
This is referred in the Java Language Specification Section 8.1.1.1
When you have an important class but the system cannot create an instance fo this class, because
this class is parent of a lot of classes of the system;
this has a lot of responsability (methods used by a lot of class) for domain's requires;
this class not represents a concrete object;
Servlet Example:
All methods are concrete,
but the base class is useless by itself:
DeleteAuthor.java
Abstract class with concrete doGet method.
doGet calls file pointed to in protected string sql_path.
sql_path is null.
DeleteAuthorKeepBook.java
extends abstract class DeleteAuthor
sets sql_path to delete_author_KEEP_BOOK.sql
DeleteAuthorBurnBook.java
extends abstract class DeleteAuthor
sets sql_path to delete_author_BURN_BOOK.sql