I am having some interesting problem with interfaces, please help me understand this concept.
I have three interfaces Itest, Itest3, Itest4. Interface Itest extends both Itest3 and Itest4 interfaces.
They both interfaces have common one method public void one(); Now a class Test implements Itest interface and overrides method one()
Now of which interface it inherits method of? What if I want to inherit common method of specific interface.
And
What effect it has on polymorphism ? what if another class only inherits Itest3 only. I think this will break at runtime.
Please help me understand what the advantage is of that?
Code is here...
public interface ITest extends Itest4,Itest3 {
public static interface ITest2{
}
}
public interface Itest3 {
public void one();
}
public interface Itest4 {
public void one();
}
public class Test implements ITest {
#Override
public void one() {
//Which interface method it overrides?
}
public static void main(String... arg) {
new Test();
}
}
The answer is: it doesn't matter.
An interface is just declarations, not code. Both interfaces declare a method public void one(). When you have an implementing class which implements this method, it implements it for both interfaces at the same time. This implementation in class Test doesn't override anything. It's the first implementation. There are no implementations in the interfaces it could override - just two identical declarations for it.
When another class implements ITest3, it will need its own implementation for public void one(). Just like any other class which implements ITest4, or ITest. The only case where you wouldn't need an own implementation, is when you would have a class which extends the class Test, because it could inherit the implementation from Test.
The declaration
public interface Itest3 {
public void one();
}
Simply states that any implementer of Itest3 will provide a method that is named one, takes no arguments, and returns void.
In exactly the same way
The declaration
public interface Itest4 {
public void one();
}
also states that any implementer of Itest4 will provide a method that is named one, takes no arguments, and returns void.
Interfaces simply exist to specify a behavioral contract, irrespective of the implementation of said behavior.
Thus,
public class Test implements ITest {
#Override
public void one() {
//Defines the behavior of both interfaces
}
}
Defines a class which implements both interfaces.
This is because the method implementation satisfies the requirements of both interfaces.
Related
I am trying to understand how default methods deal with diamond problem in various scenarios. And, this is one of the scenario which I'm not able to understand.
Following is the description,
1. Interface with a default method method()
2. Abstract Class with a method method()
3. Concrete Class implementing the above interface and extending the abstract class.
interface Interface {
default void method() {
System.out.println("Interface method");
}
}
abstract class AbstractClass {
void method() {
System.out.println("Abstract class method");
}
}
// Concrete class definition first starts
public class ConcreteClass extends AbstractClass implements Interface {
#Override
public void method() {
super.method();
}
public static void main(String[] args) {
Interface test = new ConcreteClass();
test.method();
}
}
// Concrete class definition first ends
// Concrete class definition Second starts
public class ConcreteClass extends AbstractClass implements Interface {
public static void main(String[] args) {
Interface test = new ConcreteClass();
test.method();
}
}
// Concrete class definition Second ends
My queries,
1. Why does definition first always gives output as "Abstract class method" even when I use the Interface type for concrete class object?
2. Why definition second doesn't compile?
If compiler is using abstract class implementation in definition first, then it should be able to identify that it will always use Abstract class implementation in definition second.
This behavior is very confusing to me and any help is greatly appreciated.
Otherwise, the more I delve deeper into this, the more confusing it gets.
Edit 1 :
Compilation error in second definition is "The inherited method AbstractClass.method() cannot hide the public abstract method in Interface"
Default methods are just that: defaults. If there is an implementation, it will be used. If there isn't, the default will be used. There is no diamond problem here (there can be with multiple defaults, however).
1) Dynamic dispatch
2) The abstract class gives the method named method package-private access; the interface demands it be public.
Suppose I have this two interfaces...
public interface ObjectInterface { /* empty interface */ }
public interface ObjectHandler
{
void handle(ObjectInterface object);
}
...and also a concrete class which implements the ObjectInterface:
public class ConcreteObject implements ObjectInterface { /* ... */ }
Why is this not allowed in Java?
public class ConcreteHandler implements ObjectHandler
{
#Override
public void handle(ConcreteObject object) // <-- ObjectInterface implementation
{
// ...
}
}
A ConcreteObject implements the ObjectInterface interface afterall.
However, is there a way to design my classes in Java keeping this pattern of abstraction?
You can parameterize ObjectHandler with the class of accepted ObjectInterfaces:
public interface ObjectHandler<T extends ObjectInterface>
{
void handle(T object);
}
and use it as follows:
public class ConcreteHandler implements ObjectHandler<ConcreteObject>
{
#Override
public void handle(ConcreteObject object) // <-- now this works
{
// ...
}
}
Interface method is the contract,
void handle(ObjectInterface object);
Therefore the implementation of the interface should adhere to the contract. So it won't let you limit the object type it accepts.
handle(ConcreteObject object){...}
Above limits the input to the method, as its just a one implementation of ObjectInterface. Think what happens if there's another implementation called, ConcreteObject2 which implements the ObjectInterface. According to your code handle method won't accepts the ConcreteObject2 type objects.
If you want to keep the pattern you can use java generics
Because you're breaking the contract of the interface, and thus breaking the Liskov substitutioon principle.
The interface says: handle() can take any instance of ObjectInterface as argument. That's the contract: any implementation of handle() must accept any instance of ObjectInterface.
But the class says: handle() only accepts instances of ConcreteHandler.
I came to situation :
public interface Intr {
public void m1();
}
public abstract class Abs {
public void m1() {
System.out.println("Abs.m1()");
}
// public abstract void m1();
}
public class A extends Abs implements Intr {
#Override
public void m1() {
// which method am I overriding, well it is Abs.m1() but why?
// if method implemented is Abs.m1(), then why I am not getting error for Intr.m1() not implemented.
}
}
You are satisfying both conditions at once; ie. the one implementation is at the same time fulfilling the abstract class requirements and the interface requirements.
As a note, unless you are using Intr in another inheritance chain, you don't need it. Also, it might make sense to move the implements Intr up to the abstract class definition.
You can only override methods defined in another class.
Methods declared in an interface are merely implemented. This distinction exists in Java to tackle the problem of multiple inheritance. A class can only extend one parent class, therefore any calls to super will be resolved without ambiguity. Classes however can implement several interfaces, which can all declare the same method. It's best to think of interfaces as a list of "must have"s: to qualify as a Comparable your cluss must have a compareTo() method but it doesn't matter where it came from or what other interfaces require that same method.
So technically you override Abs.m1() and implement Intr.m1() in one fell swoop.
Note that this would be fine too:
public class B extends Abs implements Intr {
//m1() is inherited from Abs, so there's no need to override it to satisfy the interface
}
Here, both the interface and abstract class have the same method.
You have one class with named Derived which extends an abstract class and implement an interface. It's true and you override print method on Derived class it's fine and it compiles correctly and does not give any error but here you can't identify which class method is overridden like abstract class or interface.
This is runtime polymorphism you can't create an instance of an abstract class or interface but you can create a reference variable of that type. Here the solution is you can't identify that on compile-time it's actually overridden at run time.
interface AnInterface
{
public void print();
}
abstract class Base
{
public abstract void print();
}
public class Derived extends Base implements AnInterface
{
public void print(){
System.out.println("hello");
}
AnInterface iRef = new Derived();
iRef.print(); // It means interface method is overridden and it's decided when we call the method.
Base base = new Derived();
base.print(); // It means abstract class method is overridden.
}
#Override ensures you override the method with no difference Interface or abstract superclass. So no error with override.
On the other hand Interface method is also implemented in the superclass which is enough for Interface contracts.
How do I create an object of an abstract class and interface? I know we can't instantiate an object of an abstract class directly.
You can not instantiate an abstract class or an interface - you can instantiate one of their subclasses/implementers.
Examples of such a thing are typical in the use of Java Collections.
List<String> stringList = new ArrayList<String>();
You are using the interface type List<T> as the type, but the instance itself is an ArrayList<T>.
To create object of an abstract class just use new just like creating objects of other non abstract classes with just one small difference, as follows:
package com.my.test;
public abstract class MyAbstractClass {
private String name;
public MyAbstractClass(String name)
{
this.name = name;
}
public String getName(){
return this.name;
}
}
package com.my.test;
public class MyTestClass {
public static void main(String [] args)
{
MyAbstractClass ABC = new MyAbstractClass("name") {
};
System.out.println(ABC.getName());
}
}
In the same way You can create an object of interface type, just as follows:
package com.my.test;
public interface MyInterface {
void doSome();
public abstract void go();
}
package com.my.test;
public class MyTestClass {
public static void main(String [] args)
{
MyInterface myInterface = new MyInterface() {
#Override
public void go() {
System.out.println("Go ...");
}
#Override
public void doSome() {
System.out.println("Do ...");
}
};
myInterface.doSome();
myInterface.go();
}
}
There are two ways you can achieve this.
1) Either you extend / implement the Abstract class / interface in a new class, create the object of this new class and then use this object as per your need.
2) The Compiler allows you to create anonymous objects of the interfaces in your code.
For eg. ( new Runnable() { ... } );
Hope this helps.
Regards,
Mahendra Liya.
You can provide an implementation as an anonymous class:
new SomeInterface() {
public void foo(){
// an implementation of an interface method
}
};
Likewise, an anonymous class can extend a parent class instead of implementing an interface (but it can't do both).
public abstract class Foo { public abstract void foo(); }
public interface Bar { public void bar(); }
public class Winner extends Foo implements Bar {
#Override public void foo() { }
#Override public void bar() { }
}
new Winner(); // OK
"instantiate" means "create an object of".
So you can't create one directly.
The purpose of interfaces and abstract classes is to describe the behaviour of some concrete class that implements the interface or extends the abstract class.
A class that implements an interface can be used by other code that only knows about the interface, which helps you to separate responsibilities, and be clear about what you want from the object. (The calling code will only know that the object can do anything specified in the interface; it will not know about any other methods it has.)
If you are using someone else's code that expects a Fooable (where that is the name of some interface), you are not really being asked for an object of some Fooable class (because there isn't really such a class). You are only being asked for an instance of some class that implements Fooable, i.e. which declares that it can do all the things in that interface. In short, something that "can be Foo'd".
You write a class that derives from the abstract class or implements the interface, and then instantiate that.
What you know is correct. You cannot create an object of abstract class or interface since they are incomplete class (interface is not even considered as a class.)
What you can do is to implement a subclass of abstract class which, of course, must not be abstract. For interface, you must create a class which implement the interface and implement bodies of interface methods.
Here are orginal tutorial on oracle site, http://download.oracle.com/javase/tutorial/java/IandI/abstract.html and http://download.oracle.com/javase/tutorial/java/concepts/interface.html
You can not instantiate the abstract class or an interface, but you can instantiate one of their subclasses/implementers.
You can't instantiate an abstract class or an interface, you can only instantiate one of their derived classes.
In your example
MyAbstractClass ABC = new MyAbstractClass("name") {
};
You are instantiating any class that implements Suprising.
public abstract class AbstractClass { ... }
public interface InterfaceClass { ... }
// This is the concrete class that extends the abstract class above and
// implements the interface above. You will have to make sure that you implement
// any abstract methods from the AbstractClass and implement all method definitions
// from the InterfaceClass
public class Foo extends AbstractClass implements InterfaceClass { ... }
NO, we can't create object out of an interface or Abstract class because
Main intention of creating an object is to utilize the wrapped methods and data.
As interface don't have any concrete implementation hence we cannot.
For abstract class we may have concrete method or abstract method or both.
There is no way for the API developer to restrict the use of the method thats don't have implementation.
Hope help.
No, you are not creating the instance of your abstract class here. Rather you are creating an instance of an anonymous subclass of your abstract class. And then you are invoking the method on your abstract class reference pointing to subclass object.
public class Testing extends JDialog {
public MyClass myClass;
public Testing() {
}
}
given the above code, is it possible to override a method in myClass in Testing class?
say myClass has a method named computeCode(), will it be possible for me to override it's implementations in Testing? sorry it's been a long time since I've coded.
if you want to override a method from MyClass then your testing class must extend that. for overriding a method one must complete IS-A relationship whereas your code comes under HAS-A relationship.
Yes, it is generally possible (note that as others have correctly mentioned - you'd need to extend it to override the method). Refer to this sample:
public class Animal {
public void testInstanceMethod() {
System.out.println("The instance method in Animal.");
}
}
public class Cat extends Animal {
public void testInstanceMethod() {
System.out.println("The instance method in Cat.");
}
public static void main(String[] args) {
Cat myCat = new Cat();
Animal myAnimal = myCat;
myAnimal.testInstanceMethod();
}
}
Not only is it possible, but it is a key feature in polymorphism an code reusability.
Note, however, that MyClass.computeCode might be final - in this case, it cannot be overridden.
You override methods of classes that you extend. Therefore, in your example your Testing class could override the various existing methods of JDialog. If you wanted to override computeCode() from MyClass (assuming it's not final), you should make Testing extend MyClass.
public class Testing extends MyClass
{
#Override
public int computeCode()
{
return 1;
}
}
You can override a class's method only in a subclass (a class that extends the class whose method you want to override). However, given your skeletal code, you can (within Testing) have a nested class that extends MyClass and force an instance of that nested class into the myClass instance variable... so, the answer must be "yes".
Whether that's the best choice (as opposed to using interfaces, rather than subclassing concrete classes, and relying on Dependency Injection to get the implementations most suited for your testing), that's a different question (and my answer would be, unless you're testing legacy code that you can't seriously refactor until it's well test-covered... then, probably not;-).
See, if you want to override method from MyClass then you need to extend it.
As per your code, it seems you want to make a wrapper wround MyClass.
Wrapper means, calling implemented class method will call method of MyClass.
I am just clearing how wrapping works as below.
public class Testing extends JDialog {
public MyClass myClass;
public Testing() {
}
public void someMethod() {
//Add some more logic you want...
...
..
myClass.computeCode();
}
}
thanks.
The wording of the question is confused and lost.
Here are some key points:
You can't #Override something that you didn't inherit to begin with
You can't #Override something that is final
Here's a small example:
import java.util.*;
public class OverrideExample {
public static void main(String[] args) {
List<String> list = new ArrayList<String>(
Arrays.asList("a", "b", "c")
) {
#Override public String toString() {
return "I'm a list and here are my things : " + super.toString();
}
};
System.out.println(list);
// prints "I'm a list and here are my things : [a, b, c]"
}
}
Here, we have an anonymous class that #Override the toString() method inherited from java.util.ArrayList.
Note that here, it's not class OverrideExample that overrides the ArrayList.toString(); it's the anonymous class that (implicitly) extends ArrayList that does.
All the above answers are valid. But, if you want to extend JDialog but still if you want to override a method of another class it is possible through interfaces. Interfaces won't have method definitions but will have method declarations. More about interfaces, you can read at http://java.sun.com/docs/books/tutorial/java/concepts/interface.html
In your case, you can make use of interface like this
public interface MyInterface{
public void myMethod();
}
public class Testing extends javax.swing.JDialog implements MyIterface{
public void myMethod(){
// code for your method
}
}
Since Testing class has already inherited JDialog, there is no way let it inherit MyClass again unless to implement an interface. What you can do is to use some design pattern. However this is not overriding, since there is no inheritance. The Adapter is the one you need. Again you are losing the flexibility of polymorphism.
public class Testing extends JDialog {
MyClass myClass = new MyClass();
public Testing() {
}
public void methodA(){
myClass.methodA();
}
}
class MyClass {
public void methodA(){}
}