I recently saw implementing where a interface is implemented in a class and in another class we have a static final variable of the interface type and it somehow was able to complete computation from the class that had implemented the interface .
My question is how will the interface variable handle this if more than one class has a implementation of the interface. Am I missing something or it is just guessing where the implementation of interface is .
This is for java language
public interface DemoMe{
public void doSomething();
}
public class MainClass implements demoMe {
public void doSomething(){
System.out.println("Something was done ");
}
}
public class AnotherClass {
private final DemoMe demoVariable;
public void useMe(){
demoVariable.doSomething();
}
}
here the AnotherClass somehow knows how to look for implementation of doSomething. can someone point me towards how this exactly works.
The variables in java interface are public static and final type. You whenever a class implements an interface. The interface variable become part of the class. Now these variable can be accessed using class reference or object reference. These variable are final so cannot be updated and static so always belong to the class. The interface itself need not to manage anything. The implementing class will take care of it.
Here we have defined an interface DemoMe with one method and one variable. Now DemoMeOne class implements the interface. The need to provide the definition for methods coming from interface. The doSomething() method simply prints a statement an access the variable from interface. Now we define an other class which instantiate the DemoMeOne class and access the interface method and variable.
interface DemoMe{
public void doSomething();
public int variable = 100;
}
class DemoMeOne implements DemoMe {
public void doSomething(){
System.out.println("Something was done.");
System.out.println("Access interface variable: " + variable);
}
}
class MainClass {
public static void main(String[] args) {
DemoMeOne demoMeOne = new DemoMeOne();
System.out.println("Variable from interface using DemoMeOnce class: " + DemoMeOne.variable);
System.out.println("Variable from interface using DemoMeOnce object reference: " + demoMeOne.variable);
System.out.println("Variable from interface using interface itself: " + DemoMe.variable);
demoMeOne.doSomething();
}
}
output:
Variable from interface using DemoMeOnce class: 100
Variable from interface using DemoMeOnce object reference: 100
Variable from interface using interface itself: 100
Something was done.
Access interface variable: 100
Related
Can we have a class inside an interface which has different methods of the interface implemented in it. I have a doubt here that why Java allows writing Inner classes inside interfaces and where can we use it.
In the program below I have written a class inside Interface and implemented the methods of the interface. In the implementation class of the interface I have just called the inner class methods.
public interface StrangeInterface
{
int a=10;int b=5;
void add();
void sub();
class Inner
{
void add()
{
int c=a+b;
System.out.println("After Addition:"+c);
}
void sub()
{
int c=a-b;
System.out.println("After Subtraction:"+c);
}
}
}
abstract public class StrangeInterfaceImpl implements I {
public static void main(String args[])
{
StrangInterface.Inner i=new StrangeInterface.Inner();
i.add();
i.sub();
}
}
You can define a class inside an interface. Inside the interface, the inner class is implicitly public static.
From JLS Section 9.1.4:
The body of an interface may declare members of the interface, that is, fields (§9.3), methods (§9.4), classes (§9.5), and interfaces (§9.5).
From JLS Section 9.5:
Interfaces may contain member type declarations (§8.5).
A member type declaration in an interface is implicitly static and public. It is permitted to redundantly specify either or both of these modifiers.
The only restriction on the inner class defined inside the interface or any other class, for that matter, is that, you have to access them using the enclosing member name.
Apart from that, there is no relation between them. The inner class will result in completely a different class file after compilation.
For e.g., if you compile the following source file:
interface Hello {
class HelloInner {
}
}
Two class files will be generated:
Hello.class
Hello$HelloInner.class
Can we have a class inside an interface which has different methods of the interface implemented in it.
IMHO But interfaces are not meant to for that purpose.
If you write inner class in an interface it is always public and static.
It's equivalent to
public interface StrangeInterface
{
public static class Inner{
}
and the variable inside the interface also explicitly public static variables.
An interface might provide its own implementation as a default.
Note that unless you declare the inner class implements the interface, there's no relation between the two other than it's an inner class. When a class is very tightly related to the interface this isn't intrinsically unreasonable, although I'd be suspicious it's a generally-useful pattern.
to summarize "where can we use it" by defining a class inside an interface:
1. to provide default implementation for an interface
2. if argument or return type for interface method/s is class
w.r.t your code
interface StrangeInterface {
int a = 10;
int b = 5;
void add();
void sub();
class Inner implements StrangeInterface {
public void add() {
int c = a + b;
System.out.println("After Addition:" + c);
}
public void sub() {
int c = a - b;
System.out.println("After Subtraction:" + c);
}
}
}
class MyTest implements StrangeInterface {
public void add() {
System.out.println("My own implementation for add : " + (a +b));
}
public void sub() {
System.out.println("My own implementation for sub : " + (a- b));
}
}
public class StrangeInterfaceImpl {
public static void main(String args[]) {
StrangeInterface.Inner i = new StrangeInterface.Inner(); // calling default implementation
i.add();
i.sub();
MyTest t = new MyTest(); // my own implementation
t.add();
t.sub();
}
}
I have abstract class and interface like this
abstract class ParentClass
{
int VALUE;
public abstract void display();
public void display2()
{
System.out.println("this is abstract class method");
}
}
interface parentInterface
{
int VALUE=88;
abstract void display();
void display2();
}
the child class extends and implements the above like following
class ChildClass extends ParentClass implements parentInterface
{
ChildClass()
{
super.VALUE=0;
//VALUE=0; //<=will give ambiguous property
}
#Override
public void display()
{
System.out.println("Current Class-"+this.getClass());
System.out.println("Integer value-"+super.VALUE);
}
public void display2()
{
//to call the method of abstract class
//call by using super.display2();
System.out.println("this is implemented method");
}
}
So, my question is How can i access interface VALUE variable in ChildClass ??
You can access the VALUE from interface using parentInterface.VALUE as variables in interfaces are public static final by default.
And the abstract class's VALUE can be accessed using this.VALUE as it is a member variable.
variables in interface are implicitly public static final.
static - because Interface cannot have any instance.
final - the value assigned to the interface variable is a true constant that cannot be re-assigned by program code.
Interface variables can be accessed using <Interface>.VALUE whereas the variables from the parent class are inherited and hence can be accessed using this.VALUE.
if any subclass class is implementing an interface which has instance
members and if both subclass and interface are in the same package
then that static members can be accessed from the child class without
even using the Interface name.
Thats why you are getting the ambiguous error. Please put Interface in some other package and then it should not show such an error else you will have to access it like super.VALUE
/**
* this is my class, yadayada. Needs to be subclassed to be useful.
*/
public abstract class MyClass {
...
public static void myMethod() {
// What is the name of the subclass that's using this?
System.out.println("Called from class " + this.getClass().class.getName());
// Doesn't work because there's no "this" in a static method.
}
}
Edit: this is what I want to happen:
public class FooClass extends MyClass {
...
}
FooClass.myMethod(); // I would like this to print "Called from class FooClass"
I'm all out of ideas.
Edit: And for those who wonder why I'm doing it this way, it's actually an Android question of sorts.
Android defines a class called BroadcastReceiver. You subclass this and register your subclass with the system. When an appropriate broadcast is sent, the system creates an instance of your subclass and calls one of its methods.
I want to create my own BroadcastReceiver subclass that contains a static method for registering itself. But I also want it to be subclassable. It sort of looks like this:
/**
* My special-purpose BroadcastReceiver. Subclass this to use it.
*/
public class MyClass extends BroadcastReceiver {
public static scheduleAnAlarm(long when) {
// do some class-specific stuff
AlarmManager.scheduleBroadcast(MyClass.class, when);
}
public void onBroadcast() {
System.out.println("You should subclass MyClass for it to be useful");
}
}
My problem is that I want to register the subclass to be instantiated, not MyClass.
You can't. That is you cannot get the class of a subclass from a static method.
When Java invokes a static method on a class (even one that is abstract) no subclass is required therefore none is loaded by the class loader. Therefore there is not necessarily any subclass to get. Even if there was, there could be multiple subclasses so how could Java decide which one you want?
Edit, even with your edit you can't get the subclass. There is a trick you can use with exceptions to get the calling class. You can throw / catch an exception and then walk down the stack trace one level to get the calling method / class. Not recommended!
I guess you want the class name, then something like below may work:
System.out.println("Called from class " + MyClass.class.getName());
this will not work in static context the class instance which you can access there is MyClass.class
How about MyClass.class.getName()?
public class Foo extends MyClass{
public static void main(String[] args) {
myMethod();
}
}
and
public abstract class MyClass{
public static void myMethod() {
System.out.println("Called from class " + MyClass.class.getName());
}
}
I have a question about interface and class implementing interface.
This is my code:
interface iMyInterface {
public iMethod1();
}
public class cMyClass implements iMyInterface {
public iMethod1() {
// some code
}
protected iMethod2() {
// some code
}
}
I would like to create an instance of iMyInterface as this :
iMyInterface i = new cMyClass();
i.iMethod1();
It's ok, but how can I call iMethod2() from my interface instance? Is this working and safe:
((cMyClass)i).iMethod2();
Thanks for help.
Yes, that will work (if you change the declaration of cMyClass to implement iMyInterface) and it's safe so long as the reference really does refer to an instance of cMyClass.
However, it's a generally bad idea. The whole point of using an interface is to be able to work with any implementation - it's to separate the abstraction from the implementation. If you're then going to require a specific implementation, you might as well make the type of i just cMyClass to start with.
So suppose instead of calling the cMyClass constructor yourself, you receive a method parameter of type iMyInterface - it's a bad idea to cast to cMyClass at that point, as it could be a different implementation of the interface.
(On a separate note, it's a good idea to start following Java naming conventions, which state that classes and interfaces should be Pascal-cased - so ditch the c and i prefixes.)
It will work (provided that cMyClass implements iMyInterface and you are in scope of protected modifier) but that is not the correct OO approch.
If you want to use iMethod2 consider:
adding it to the interface
create another interface containing that method
Use cMyClass myClass = new cMyClass();
There is some another alternative to cast Interface to a class. Here is example how.
interface iMyInterface {
void iMethod1();
}
public class cMyClass implements iMyInterface {
private iMyInterface myInterface;
public cMyClass() {
myInterface = this;
}
public void iMethod1(){
System.out.println("Print from cMyClass iMethod1()");
}
protected void iMethod2() {
System.out.println("Print from cMyClass iMethod2()");
}
/**
* Getter so we can access to the interface methods.
* #return
*/
public iMyInterface getMyInterface() {
return myInterface;
}
}
And to get values from your interface, here is the code example.
public class Main {
public static void main(String[] args) {
cMyClass myClass = new cMyClass();
myClass.getMyInterface().iMethod1();
myClass.iMethod2();
}
}
Output:
Print from cMyClass iMethod1()
Print from cMyClass iMethod2()
I think this is a good example how you can separate interface code from the class code. Just create instance of the interface and every method use through getter with that interface.
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.