Clarification on Interface concept - java

interface A
{
public void printValue();
}
public class Test
{
public static void main (String[] args)
{
A a1 = new A() {
public void printValue()
{
System.out.println("A");
}
};
a1.printValue();
}
}
We cannot create an instance of an interface, but what is new A() doing in this code? I have seen this type of code used mostly with Comparators. Please explain.

new A() {} is an instantiation of an anonymous class that implements interface A.
It is a short-cut that can be useful if you need an instance of a class that implements an interface only in one place, so you don't want to define a normal class. This way you define the class at the same place it is being used.
In your code sample, it doesn't seem very useful, but usually it is used by passing the anonymous class instance to some method that accepts a parameter of the type of the interface.

new A() in below is where you are instantiating a concrete class (which we say anonymous) which implements the interface A
A a1 = new A() {
public void printValue(){
System.out.println("A");
}
};

In your code, interface A is used as an Anonymous class. You can use them if you need to use a local class only once. it's more over same as lambda expressions.
Read more: http://docs.oracle.com/javase/tutorial/java/javaOO/anonymousclasses.html
Read about lambda expression: http://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html

Related

Cannot define extra methods in an Anonymous Inner Class in Java

When defining extra methods (that do not override the super class methods) in an Anonymous Inner Class the code compiles fine without any issues but if I try to call the extra method it throws an error. So is it only possible to override methods in the sub class when extending with an anonymous inner class? If it is so can anyone please explain me why?
Here's what my code looks like
class SomeClass {
public static void main(String[] args) {
SomeOtherClass a = new SomeOtherClass() {
#Override
public void methodFromSuperClass() {
System.out.println("Method from super class!");
}
public void subClassMethod() {
System.out.println("Sub class method");
}
};
a.methodFromSuperClass(); //This works fine
a.subClassMethod(); // But calling this extra method throws an error
}
}
This is the error that I'm getting
SomeClass.java:20: error: cannot find symbol
a.subClassMethod();
^
symbol: method subClassMethod()
location: variable a of type SomeOtherClass
1 error
This situation is exactly the same as if the anonymous class had a name:
class SomeOtherClass {
public void methodFromSuperClass() { }
}
class Subclass extends SomeOtherClass {
#Override
public void methodFromSuperClass() {
System.out.println("Method from super class!");
}
public void subClassMethod() {
System.out.println("Sub class method");
}
}
And you did:
SomeOtherClass a = new Subclass();
a.subClassMethod();
Wouldn't you agree that you shouldn't be able to call subClassMethod here? After all, the compiler knows that a is of type SomeOtherClass, but not which subclass of SomeOtherClass it is. It doesn't analyse your code that far back to see that you actually assigned an instance of Subclass to it.
The situation with anonymous classes is basically the same. It's just that this time, the subclass doesn't have a name in your code, but it's still a subclass, and the same reasoning that "the compiler doesn't analyse your code that far back" applies.
Since the anonymous subclass has no name, you can't do something like Subclass a = new Subclass(); as in the named subclass example, but since Java 10, you can do:
var a = new SomeOtherClass() { ... };
var lets the compiler infer the type of the variable for you without you saying the type name. The compiler will infer the anonymous subclass as the type for a, and this will allow you to do:
a.subClassMethod();
Finally, it is totally allowed to declare extra members in anonymous classes - it's just rather hard to access them from anywhere other than inside the anonymous class, or the local scope, because the anonymous class has no name. Declaring extra members is still sometimes useful though, because you can access them in the overridden methods for example.
Your assumption is correct. It is not possible to call the unoverridden method this way.
Consider an example where you have declared an interface and instantiated it with a concrete class, then you still only have access to the methods defined in the interface and not in the class.
public interface MyInterface{
public void someMethod();
}
public class MyImpl implements MyInterface{
//someMethod() implementation
// ...
// newMethod()
public void newMethod(){
//some implementation
}
}
public class Main{
public static void main(String[] args){
MyInterface inter = new MyImpl();
inter.someMethod(); // this call is ok
inter.newMethod(); // this call leads to a Symbol not found Exception,
// because MyInterface has no method named newMethod...
}
}
Hope it is now clearer what is meant by this

Abstract class 'instantiation' with a body of its methods

I am starting java programming and I came across abstract classes. I know that you cannot instantiate them without creating concrete classes which extend them to become the subclass. However, I got really confused when I tried this code and it runs ok.
abstract class Communication{
public void FirstMethod()
{
System.out.println("I am first method()\n");
}
}
public class Main{
public static void main(String[] args){
Communication communication = new Communication() {
#Override
public void FirstMethod(){
super.FirstMethod();
}
};
communication.FisrtMethod();
}
}
Output is: I am first method().
If I modify it to:
Communication communication = new Communication() {
#Override
public void FirstMethod(){
System.out.println("I've been called from Main");
}
};
The output is: I've been called from Main.
Could somebody please explain if this is a kind of instantiation or what concept is this?
This is termed as
Anonymous Class
Definition:
An inner class declared without a class name is known as an anonymous inner class.
In case of anonymous inner classes, we declare and instantiate them at the same time. Generally, they are used whenever you need to override the method of a class or an interface.
This is called anonymous inner class. This way you can implement an interface or abstract class without having to find a name for it and instantiate it at the same time. This concept is useful when you use a certain implementation just once.
The construct looks always like that:
new SomeClass() {
//implementation of methods
};
This is known as anonymous class. The anonymous class definition allows you to provide a class definition within code and it has no formal name. The anonymous class expression has the class definition and instance creation expression.This is not limited to abstract classes but also for interfaces and concrete classes.
For example
abstract class A { }
// so the anonymous class expression is
A a = new A() {// class definition };
// This will actually create an instance of a
// class that extends the abstract class A
// that java will create at run time
You can even use anonymous class expression in the method arguments.Example of this is a Comparator in Collections.sort() method;
Collections.sort(listOfValues,new Comparator<Value>(){
public int compare(Value v1, Value v2){
// method implemetation.
}
})

Java Anonymous Class - minimal example

I'm trying to understand Java anonymous classes.
Looking here:
https://docs.oracle.com/javase/tutorial/java/javaOO/anonymousclasses.html
And here:
http://docstore.mik.ua/orelly/java-ent/jnut/ch03_12.htm
I understand the basic syntax, but the examples are non-minimal.
What are the absolute minimal requirements to define a anonymous class in Java?
Edit>>>
Essentially this:
public class MyClass {
InnerClass instance = new InnerClass();
public class InnerClass{
public void print(){
System.out.println("First Call");
}
};
public void redefineInstance(){
instance = new InnerClass(){
public void print(){
System.out.println("Second Call");
}
};
}
public static void main(String[] args) throws Exception{
MyClass myobject = new MyClass();
myobject.instance.print();
myobject.redefineInstance();
myobject.instance.print();
}
}
The most minimal example:
interface Foo {}
public static void main (String[] args)
{
Foo foo = new Foo() {};
}
Literally a declaration of an interface, and then usage as an anonymous class with no additional declarations.
Practically speaking, it does nothing. However, as we add bits in:
interface Foo {
public void bar();
}
public static void main (String[] args) throws java.lang.Exception
{
Foo foo = new Foo() {
public void bar() {
System.out.println("Hello");
}
};
}
It becomes a full-fledged helper class for our method.
The most common use for early/mid level programming would be overriding Listeners to do specific actions. We know the Listener is listening for something, and we want it to do something as a result of the Listener, so we craft the Listener and say "Do this when you are triggered."
Here's the example of a really complex ActionListener tutorial: https://docs.oracle.com/javase/tutorial/uiswing/events/actionlistener.html
But typically, if it's something that's mundane like "run a method on click", you'll use an anonymous in-line declaration that just calls a method for you.
I suppose the "absolute minimal requirement" to create an anonymous class is to have a place in your code that requires an instance of a non-final class or interface of some kind.
Meaning, if I have a method in MyClass:
public static void gimmeMyObject(MyObject c)
I can define an anonymous class that extends MyObject as long as MyObject is not final:
//Somewhere in a method
MyClass.gimmeMyObject(new MyObject() {
public String myMethod() {
return "I'm anonymous";
}
});
That anonymous class will be passed in as a MyObject.
However, I could not do this if the method required a String or Integer, for example, because those are final classes.
For the above example, the non-anonymous class would translate to:
public class MyAnonObject extends MyObject { //In actuality, an anonymous class doesn't have a name, though.
public String myMethod() {
return "I'm anonymous";
}
}
As Compass has already said, the absolute minimum is not useful.
Following is an example of a 'useful' inner class:
JButton ok = new JButton();
ok.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("abc");
}
});
So instead of having to define an inner class or a helper class for an ActionListener you only use once, you can just have it as an inline or anonymous class to remove clutter and increase readability.
How about this example?
//interface
interface Message{
String greet();
}
Message is a anonymous class in this example,
greet() is the only method inside this anonymous class.
//Passing an anonymous inner class as an argument
obj.displayMessage(new Message(){
public String greet(){
return "Hello";
}
});
You can think of an anonymous class as just basically the instantiation part of creating a new instance of an object. You essentially just don't declare it and give it a name. This is normally passed into method parameters as shown below.
Object someObj; is an object declaration.
someObj = new Objct(parm a,...) is the instantiation of the object.
//example of anonymous classes:
public void foo(Bar barObj){// takes a Bar object parameter
//does stuff
}
//you can call the foo method in this way
Bar barObject= new Bar();
foo(barObject){}
// or you can call the Bar anonymously
foo(new Bar()){}
In the anonymous example you instantiate a new Bar inside the method parameter. You can do this when you just need something local and don't need it to be used anywhere but in that method call. it also then gives you access to the accessible methods that are inside of the anonymous class. so you could do something like
foo(new Bar().barMethod){}. It just kind of depends what you are working with.

How to do a one-time operation under abstract class

I am developing a webApplication based on Java EE.
I have an abstract class, in which I need to have a one-time operation (a database call).
So below in the sample code, I pasted it inside its constructor, but don't know why the constructor is not getting invoked.
Please tell me how to solve this.
public abstract class Preethi {
Preethi()
{
System.out.println("hirerew");
}
public static void main(String args[])
{
int a = 12;
if(a==0)
System.out.println("a");
if (a==12)
System.out.println("12");
}
}
You never create an instance of abstract class Preethi. Why do you expect the constructor to get called? Make a non-abstract subclass and create an instance of it and then the constructor will be called. main is static, it can be called without Preethi being realized.
public class X extends Preethi
{ /* Your implementation here */}
Then in main:
public static void main(String [] args)
{
Preethi preethi = new X(); // This will call the constructor of Preethi
}
Constructor is not being invoked because main() method is called without instantiating a main class.
To invoke it - you need to create an object of Preethi explicitly.
UPD. as anio suggests - you need to subclass Preethi and instantiate it.
Although abstract classes cannot be used to instantiate objects, they can be used to create object references, because Java's approach to run-time polymorphism is implemented through the use of superclass references. Thus, it must be possible to create a reference to an abstract class so that it can be used to POINT TO A SUBCLASS object.
You can make it not abstract, or create a subclass that invokes super() on your abstract class.
See the code below:
public abstract class Preethi {
// constructor:
Preethi() {
System.out.println("hirerew");
}
public static void main(String[] args) {
// call the constructor:
new Preethi() {}; // "{}" needed because our class is abstract.
}
}
The point here is that you don't always have to create a new class, but can define a 'one-time' class next to the constructor. For example:
public abstract class A {
public abstract void foo();
public A() { foo(); }
}
You could do the following:
A a = new A() {
public void foo() {
System.out.println("hello");
}
};
The output would simply be "hello". A similar method could also be utilized for interfaces.
You are not creating object of Preethi. In order to make call to constructor, You have to remove abstract keyword from class and create it's object
Or create anonymous inner class and it's object as :
new Preethi() {
// abstract method impl
};
Or create sub class of Preethi, and create object of it.
FYI: You can create object references of any abstract class or interfaces. You can not create object of them.
And I think making main class abstract really does not make any sense. Atlease to me.(Tell me if I am wrong)

How to create an object of an abstract class and 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.

Categories

Resources