This question already has answers here:
Can we instantiate an abstract class?
(16 answers)
Closed 9 years ago.
When I create the object of an Abstract class, I have to do like this just like an interface.
AbstractClass abstractClass = new AbstractClass() {
#Override
public void abstractMethod() {
}
};
Does this mean that the object of AbstractClass is an anonymous inner class object?
AbstractClass abstractClass = new AbstractClass() {
#Override
public void abstractMethod() {
}
};
This block of code means that you are creating an anonymous class which extends AbstractClass. You can also use the same notation for an interface also.
SomeInterface someImplementingClass = new SomeInterface(){/*some code here*/};
This means you are creating a class that implements SomeInterface.
Note that there are certain limitation when you are creating an anonymous class. As and anonymous class is already extending the parent type, you cannot make it extend another class as in java you can extend only on class.
This code will help understand concept of overriding methods in anonymous classes
class Anonymous {
public void someMethod(){
System.out.println("This is from Anonymous");
}
}
class TestAnonymous{
// this is the reference of superclass
Anonymous a = new Anonymous(){ // anonymous class definition starts here
public void someMethod(){
System.out.println("This is in the subclass of Anonymous");
}
public void anotherMethod(){
System.out.println("This is in the another method from subclass that is not in suprerclass");
}
}; // and class ends here
public static void main(String [] args){
TestAnonymous ta = new TestAnonymous();
ta.a.someMethod();
// ta.a.anotherMethod(); commented because this does not compile
// for the obvious reason that we are using the superclass reference and it
// cannot access the method in the subclass that is not in superclass
}
}
This outputs
This is in the subclass of Anonymous
Remember that anotherMethod is implemented in implemented in the subclass that is created as anonymous class. and a is the reference variable of type Anonymous i.e. superclass of the anonymous class. So the statement ta.a.anotherMethod(); gives compiler error as anotherMethod() is not available in Anonymous.
An object is not a class object (in this context). It is derived from a class. In Java there is a difference between classes and objects, as compared to e.g. prototype based languages (e.g. JavaScript) where this difference does not exist.
In your example you create an anonymous class, create an object of that anonymous class and assign it to a variable; all in one step.
Anonymous classes are always inner classes: http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.9.5
http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.1.3
One fundamental properties of attract classes is the fact that there could be no direct instance of this type. Only classes that implement the complete interface of an class can be instantiated.
In order to create an object you need a non abstract class first, by extending the abstract class.
Abstract classes does not have any instances (objects of it's type). I recommend Mavia to take a look at following link for clearness:
http://docs.oracle.com/javase/tutorial/java/IandI/abstract.html
You cannot create an object of an abstract class. They are non-instantiable. What you are doing when you do this is creating a sort of dynamic subclass object, and instantiating that (at the same time). More or less, yes, you can create it the same way as an interface. See this answer for more information.
In fact here you create both: an anonymous inner class, that extends AbstractClass as well as an instance of this anonyomous class, the object. You do not and cannot create an instance of AbstractClass.
Also you declare a variable named abstractClass that has the Type AbstractClass. Inside this variable you store a newly created instance of your newly defined subclass of AbstractClass.
EDIT: You can of course not reuse the anonymous inner class, since it is anonymous, and the only place where an instance of it can be created or rather is created is right here.
Here might be a loop or function in which case you would be able to create many instances of this anonymous inner class. But it would still be only this piece of code where instances are created.
Related
Suppose I have these classes:
public class ChildClass extends ParentClass
{
// some class definition here
}
public abstract class ParentClass
{
public static void printClass()
{
// get the class that extends this one (and for example, print it)
}
// some class definition here
}
Lets say when calling ParentClass.printClass() I want to print the name of the class (like doing System.out.println(ParentClass.class)). When then extending ParentClass (for example like in ChildClass) and calling ChildClass.printClass(), I want it to print the name of the extending class (like doing System.out.println(ChildClass.class)). Is this somehow possible?
I've found a way to get the class from inside a static method by using MethodHandles.lookup().lookupClass(), but when using it inside of ParentClass.printClass and extending ParentClass, then calling printClass on the extending Class, I always get the class of ParentClass.
static methods are best thought of as living entirely outside of the class itself. The reason they do show up in classes is because of the design of java (the language) itself: Types aren't just types with a hierarchy, they also serve as the primary vehicle for java's namespacing system.
Types live in packages, packages are the top level namespace concept for types. So how do you refer to a method? There's only one way: Via the type system. Hence, static methods do have to be placed inside a type. But that's about where it ends.
They do not inherit, at all. When you write:
ChildClass.lookupClass()
The compiler just figures out: Right, well, you are clearly referring to the lookupClass() method in ParentClass so that is what I will compile. You can see this in action yourself by running javap -c -p MyExample. The same principle applies to non-static methods, even.
For instance methods, the runtime undoes this maneuvre: Whenever you invoke a method on any object, the runtime system will always perform dynamic dispatch; you can't opt out of this. You may write:
AbstractList<String> list = new ArrayList<String>();
list.sort(someComparator);
and you can use javap to verify that this will end up writing into the class file that the method AbstractList::sort is invoked. But, at runtime the JVM will always check what list is actually pointing at - it's an instance of ArrayList, not AbstractList (that's obvious: AbstractList is abstract; no object can ever be directly instantiated as `new AbstractList). If ArrayList has its own take on the sort method, then that will be called.
The key takeaway of all that is: Static methods do not inherit, therefore, this dynamic dispatch system is not available to them, therefore, what you want cannot be done in that fashion.
So what to do?
It feels like what you're doing is attempting to associate a hierarchy to properties that apply to the class itself. In other words, that you want there to be a hierarchical relationship between the notion of 'ParentClass's lookupClass method and ChildClass's lookupClass method - lookupClass is not a thing you ask an instance of ChildClass or ParentClass - you ask it at the notion of the these types themselves.
If you think about it for a moment, constructors are the same way. You don't 'ask' an instance of ArrayList for a new arraylist. You ask ArrayList, the concept. Both 'do not really do' inheritance and cannot be abstracted into a type hierarchy.
This is where factory classes come in.
Factory classes as a concept are just 'hierarchicalizing' staticness, by removing static from it: Create a sibling type to your class hierarchy (ParentClassFactory for example):
abstract class ParentClassFactory {
abstract ParentClass create();
abstract void printClass();
}
and then, in tandem with writing ChildClass, you also write ChildClassFactory. Generally factories have just one instance - you may want to employ the singleton pattern for this. Now you can do it just fine:
class ChildClassFactory extends ParentClassFactory {
private static final ChildClassFactory INSTANCE = new ChildClassFactory();
public static ChildClassFactory instance() { return INSTANCE; }
public ParentClass create() { return new ChildClass(); }
public void printClass() { System.out.println(ChildClass.class); }
}
// elsewhere:
// actually gets the ChildClassFactory singleton:
ParentClassFactory factory = ....;
factory.printClass(); // will print ChildClass!
Quoting #RealSkeptic:
Static methods are not inherited. The fact that you can call ChildClass.printClass() is just syntactic sugar. It actually always calls ParentClass.printClass(). So you can't do something like that with a static method, only an inheritable non-static one.
I am trying to find out, if it is possible to create anonymous inner class as abstract. I thought, that it doesn't make sense because I am trying to create instance of the abstract class, but the message from compiler confused me:
Class 'Anonymous class derived from Test' must either be declared abstract or implement abstract method 'method()' in Test
Code:
abstract class Test{
abstract void method();
}
Test o = new Test(){};
If it is possible to declare anonymous class as abstract, please let me know how to do that.
I would be greatful for answer.
See JLS Sec 15.9.5 (emphasis mine):
15.9.5. Anonymous Class Declarations
An anonymous class declaration is automatically derived from a class instance creation expression by the Java compiler.
An anonymous class is never abstract (§8.1.1.1).
An anonymous class is always implicitly final (§8.1.1.2).
An anonymous class is always an inner class (§8.1.3); it is never static (§8.1.1, §8.5.1).
you can't and does not make sense to declare anonymous class as abstract class as anonymous are used as local class only once.
i think you are getting this error because of similar issue Class must either be declared abstract or implement abstract method error
As quoted by Andy Turner the answer to your question is NO.
However I think you wanted to know something different.
Why do you get this compiler message?
Well the compiler is a bit misleading here. It offers two possible solutions based on that you are declaring a class (that anonymous class) and then also want to create an instance of that class:
make the derived class (which an anonymous class always is) abstract,
this is fine for normal and inner classes but it is not possible for anonymous classes, so the compiler should not suggest it in the first place
implement all methods and have no abstract methods in your anonymous class declaration
So to solve your actual problem: simply implement method() so your anonymous class declaration contains no more abstract methods
abstract class Test{
abstract void method();
}
Test o = new Test()
{
void method()
{
// do something
};
};
Now everything is declared and the compiler should not complain any more.
Is it important to save all class code as individual .java files like following way?
Outer.java,
Inner.java,
Test.java
Or can I make a single java file as Test.java. Please explain anonymous class, how can we create anonymous class in java, and what is the advantage/disadvantage over normal class?
class Outer {
private int data = 50;
class Inner {
void msg() {
System.out.println("Data is: " + data);
}
}
}
class Test {
public static void main(String args[]) {
Outer obj = new Outer();
Outer.Inner in = obj.new Inner();
in.msg();
}
}
See the Code Conventions for the Java programming language:
Each Java source file contains a single public class or interface.
When private classes and interfaces are associated with a public
class, you can put them in the same source file as the public class.
The public class should be the first class or interface in the file.
I think this should answer your question. As I stated in my comment, it's not recommended to write a file that contains several unrelated classes. However, if you have an associated classes with that one public class you have in the file, you can place them in the same source file.
An anonymous class in Java is a class not given a name and is both declared and instantiated in a single statement. You should consider using an anonymous class whenever you need to create a class that will be instantiated only once.
Although an anonymous class can be complex, the syntax of anonymous class declarations makes them most suitable for small classes that have just a few simple methods.
An anonymous class must always implement an interface or extend an abstract class. However, you don’t use the extends or implements keyword to create an anonymous class. Instead, you use the following syntax to declare and instantiate an anonymous class:
new interface-or-class-name() { class-body }
Within the class body, you must provide an implementation for each abstract method defined by the interface or abstract class. Here’s an example that implements an interface named runnable, which defines a single method named run:
runnable r = new runnable()
{
public void run()
{
//code for the run method goes here
}
};
Here are a few other important facts concerning anonymous classes:
An anonymous class cannot have a constructor. Thus, you cannot pass parameters to an anonymous class when you instantiate it.
An anonymous class can access any variables visible to the block within which the anonymous class is declared, including local variables.
An anonymous class can also access methods of the class that contains it.
yes you can do this , but it should be in small programming,
while in big application you have to make class individual, Java strongly recommended that to make class different file, but it depends on you to do so.
Can someone explain this line of code for me?
SomeAbstractClass variable = new SomeAbstractClass() { };
This properly instantiaties and stores the abstract instance in the variable. What is happening? An anonymous class that extends the abstract class, maybe? Any keywords I can use to look up information about this? (the abstract class also happens to be generic if that has any relevance)
The line above is creating an anonymous subclass of SomeAbstractClass, which will not be abstract. Of course, this will work only if the base class has no abstract methods to implement.
Actually, I cannot visualize an useful instance (besides "documentation" features, see the comment below) of the line above, unless you are implementing and/or overriding methods between curly braces. That is a quite common technique if the base class/interface happens to have few methods to implement and the implementation is simple. You can even refer to the final variables of the surrounding method and parameters, thus making a closure.
You are creating an anonymous class which is a subclass of your abstract class. Like was pointed out in comments, you are looking at an anonymous extends.
Something like follows would work if you had abstract methods to implement:
MyAbstractClass someObjectOfThatClass = new MyAbstractClass(){
#Override
public void someAbstractMethod(){
}
}
You can do the same with interfaces as they can also contain abstract methods. A practical example would be adding an ActionListener to a JButton:
myJButton.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e){
// code
}
});
Java gives you the ability to create anonymous subclasses inline. You often see this in the context of anonymous inner classes with Swing event handling, but there are many other applications as well.
In your example, you are creating a class that extends SomeAbstractClass anonymously and assigning it to a SomeAbstractClass reference. It would be just as if you created a separate class like this
public class SomeConcreteClass extends SomeAbstractClass {
}
and later did this
SomeAbstractClass variable = new SomeConcreteClass();
As noted by #Stefano, your approach only works if your anonymous concrete class has no abstract methods, which would be true because SomeAbstractClass has no abstract methods.
I saw this Java snippet in the book Spring in Action, but I'm not familiar with the language construct.
new RowMapper() {
public Object mapRow() throws SQLException, DataAccessException {
Motorist motorist = new Motorist();
motorist.setId(rs.getInt(1));
motorist.setEmail(rs.getString(2));
motorist.setPassword(rs.getString(3));
motorist.setFirstName(rs.getString(4));
motorist.setLastName(rs.getString(5));
return motorist;
}
}
According the Spring documentation, RowMapper is an interface. It looks to me like an anonymous class definition based on the RowMapper interface. The new keyword is a little confusing, making me wonder if this also creates one instance of the anonymous class. I would guess yes, because if the class has no name, how will you ever create an instance after the line that defines it?
Can anyone confirm my guesses that:
this is an anonymous class definition based on the RowMapper interface, and
it creates a single instance of that class?
This is an anonymous class definition based on the RowMapper interface
That's precisely what it is.
It creates a single instance of that class?
Yep. That's correct.
That code is implementing the interface in an anonymous way.
The syntax would be similar to:
Runnable runnable = new Runnable() {
public void run() {
}
};
Note the semicolon at the end of the declaration. Here the runnable object, though holds the reference to the Runnable interface actually contains the implemented object. That's runtime polymorphism for you!
Your guesses are entirely correct. An anonymous class definition may be based on either a non-final class or on an interface, and you must implement all abstract (or interface) methods. The only available syntax for declaring anonymous classes is new, which also has the effect of instantiating exactly one instance of the anonymous class (in the course of the program, though, many instances of the same anonymous class could be created, if this code is executed several times).
Interface tells what methods the built class instance should have or if thy are label interfaces, then what kind of behavior to associate with it.
Anonymous classes are classes that basically while instantiating a class instance thy are also extending it with custom code. So if you are instantiating a interface, then you must write all the methods described with that interface, and as long as you do at least that much, then compiler will be happy. This is what is done here.
IS this is an anonymous class definition based on the RowMapper interface?
Yes. As you can see mapRow() function has been written. And if you debug the code you can see, that is not a class of an instance of interface, but class that extends interface. In case of abstract class or just class, it would be same - extended. So if class is final you cant write anonymous class for it.
Does it create a single instance of that class?
Well, it extends it and makes an instance of it. It will be single instance and any sequent call to it would result in a different class. If you debug the code, then you can even see different class names dynamically associated with it.
Solely from the code above and without knowing about RowMapper, all you can assume is that a new anonymous class based on RowMapper (which may be an interface or a class) is instantiated.
Declaring Anonymous class and in below example it creates two instances .
public class Multithread {
void test(){
new Runnable() {
#Override
public void run() {
System.out.println("1");
}
}.run();
new Runnable() {
#Override
public void run() {
System.out.println("11");
}
}.run();}
public static void main(String[] args) {
new Multithread().test();
}
}