Java: new AbstractClass(){} What is this declaration called? - java

In my application there is an abstract class which is used multiple time as follows:
public class Myclass{
int amount;
String name;
public void printResultsFromDB(){
new MyabstractClass(name){
#Override
String getDataFromDB(){
//some implementation
}
};
}
}
public abstract MyabstractClass{
String name;
public MyabstractClass(String name){
this.name = name;
}
abstract String getDataFromDB();
void execute(){
//Some implementation
}
}
I want to know what line number 5 in code called?
I know we cannot instantiate an abstract class. Is this declaration called an anonymous class?

This is called an anonymous type in Java. It allows you to implement an interface or extend an abstract class without needing a named class for it.
This is especially useful if the interface or abstract class is implemented very often and creating a new class for each implementation would end up in a confusing mess of classes. A good example for this is Java's Runnable interface that simply allows to pass a void method to a method which takes no arguments.
You can find more on this here: http://docs.oracle.com/javase/tutorial/java/javaOO/anonymousclasses.html

It is a anonymous class which will allow you to implement an interface.
From the Oracle docs:
The anonymous class expression consists of the following:
The new operator
The name of an interface to implement or a class to extend. In this example, the anonymous class is implementing the interface
HelloWorld.
Parentheses that contain the arguments to a constructor, just like a normal class instance creation expression. Note: When you
implement an interface, there is no constructor, so you use an
empty pair of parentheses, as in this example.
A body, which is a class declaration body. More specifically, in the body, method declarations are allowed but statements are not.

You're not instantiating an abstract class. It's an anonymous inner class that extends MyabstractClass. It still has to provide an implementation of any abstract methods.
It's meant for cases where you want to provide some custom implementation for one case but you don't expect to reuse it anywhere else.

Related

Is this a valid abstract class?

Is this a valid abstract class?
I know that abstract classes cannot be instantiated, so I'm suspicious of the instance variable language and constructor Programmer. It also implements a writeCode method that is not declared as default. If I recall correctly, the only methods that can be implemented in an abstract class are those with default implementations.
public abstract class Programmer {
private String language;
public Programmer (String language) {
this.language = language;
}
public void writeCode() {
System.out.println("Written in " + language);
}
}
If it is a valid abstract class, can someone explain why it contains a constructor?
Also, more broadly speaking, can abstract classes have instance variables? If so, why? Doesn't that seem counter to the idea that abstract classes cannot be instantiated?
Finally, I would love it if someone addresses the writeCode method. Why is it implemented, without a default modifier?
Thanks!
Yes, this is a valid abstract class.
Abstract classes can have constructors, instance variables and concrete methods.
The main difference with regular classes is that they can also declare abstract methods, delegating implementation to the non-abstract child classes (this is not the case here, you have no abstract methods).
Another difference is that they cannot be initialized directly, even if they do provide an accessible constructor.
The constructor(s) of an abstract class are typically used to initialize values internally, and to invoke from child classes or anonymously.
See documentation here.
Example
Given...
public abstract class Programmer {
private String language;
public Programmer(String language) {
this.language = language;
}
public void writeCode() {
System.out.println("Written in " + language);
}
}
... and...
public class JavaProgrammer extends Programmer {
public JavaProgrammer() {
super("Java");
}
}
Concrete child class
new JavaProgrammer().writeCode(); // prints "Java"
Anonymous class (note the empty class body {})
new Programmer("JavaScript"){}.writeCode(); // prints "JavaScript"
As you say, abstract classes cannot be instantiated. However, when a subclass of any abstract class is created, the first sentence in its constructor is a call to super(), which is nothing but a representation of the constructor of its parent class, the abstract class.
An abstract class can have instance variables and methods. It is even possible to have an abstract class without any abstract method. However, an abstract method can only be declared in an abstract class.
You are mixing abstract classes and interfaces concepts. An interface cannot have instance variables, and any implemented method must be prefixed with the static or default modifier.
This is correct example of abstract class. Answering your questions:
default keyword is used (as of java 8) in interfaces, where you can implement default method implementation, abstract class can have a method implementation just as any normal java class
having constructor in abstract class imposes having a constructor in extending class so that the underlying abstract class can be properly constructed (e.g. fields instantiated etc)
abstract class cannot be instantiated but as any other class can have private fields and internally make use of them, should they be protected then extending classes will also be able to directly access them.
It seems to me you're confusing abstract class with interface.
The abstract class contains a constructor because when the instantiated class based on the abstract class is created it will call super() to execute the code from the abstract class.
The instance variable is a similar thing. The class that is developed from the abstract class would then have access to the language and be able to work with it.
In terms of the default, that would be best practice but there is no absolute requirement for it to be there.
Abstract classes are partial implementations. Sometimes, as in the case above, the only thing that prevents the class from being instantiated is the abstract modifier itself!
If an abstract class has constructors then it means that subclasses must invoke one of the constructors (by calling super(...) in their constructor.
More broadly it seems that you're confusing Interfaces and Abstract Classes. Interfaces are a contract, they specify how a class should behave but provide no implementation whatsoever. Abstract Classes are a specific partial implementation of some code.
Interfaces are used (broadly) when you require someone else to provide behaviour but you don't care how it works. Abstract Classes are used when you want to assist people in providing behaviour, but you still require them to provide some details.
Since these definitions overlap, it's not unusual to see both Abstract Classes and Interfaces provided, e.g. the various Adapters in java.swing.*.

Why doesn't interfaces implement methods and override them?

I already read the post of research effort required to post a SO question. I am ashamed again to post this question to a pile of million questions. But I still don't get the idea of interfaces in java. They have unimplemented methods and then defined for every class in which they are implemented. I searched about it. Interfaces were used to support multiple inheritance in java and also to avoid (Deadly) Diamond Death of inheritance. I also came across Composition vs Inheritance and that inheritance is not for code reuse and its for polymorphism. So when I have a common code as a class to extend it will not be supported due to multiple inheritance which gives the option to use Interfaces(Correct me if I am wrong). I also came across that its not possible in most cases to define a generic implementation. So what is the problem in having a common definition (not a perfect generic implementation) of the interface method and then Override it wherever necessary and why doesn't java support it. Eg. When I have 100 classes that implements an interface 70 of them have a common implementation while others have different implementation. Why do I have to define the common method in interface over 70 classes and why can't I define them in Interface and then override them in other 30 classes which saves me from using same code in 70 classes. Is my understanding of interfaces wrong?
First, an interface in Java (as of Java 7) has no code. It's a mere definition, a contract a class must fulfill.
So what is the problem in having a common definition (not a perfect
generic implementation) of the interface method and then Override it
wherever necessary and why doesn't java support it
Yes you can do that in Java, just not with interfaces only. Let's suppose I want from this Example interface to have a default implementation for method1 but leave method2 unimplemented:
interface Example {
public void method1();
public String method2(final int parameter);
}
abstract class AbstractExampleImpl implements Example {
#Override
public void method1() {
// Implement
}
}
Now classes that want to use this method1 default implementation can just extend AbstractExampleImpl. This is more flexible than implementing code in the interface because if you do so, then all classes are bound to that implementation which you might not want. This is the advantage of interfaces: being able to reference a certain behavior (contract) without having to know how the class actually implements this, for example:
List<String> aList = MyListFactory.getNewList();
MyListFactory.getNewList() can return any object implementing List, our code manipulating aList doesn't care at all because it's based on the interface.
What if the class that uses interface already is a Sub-class. Then we
can't use Abstract class as multiple inheritance is not supported
I guess you mean this situation:
class AnotherClass extends AnotherBaseClass
and you want to extend AbstractExampleImpl as well. Yes, in this case, it's not possible to make AnotherClass extend AbstractExampleImpl, but you can write a wrapped inner-class that does this, for example:
class AnotherClass extends AnotherBaseClass implements Example {
private class InnerExampleImpl extends AbstractExampleImpl {
// Here you have AbstractExampleImpl's implementation of method1
}
}
Then you can just internally make all Example methods being actually implemented by InnerExampleImpl by calling its methods.
Is it necessary to have the interface in AnotherClass?
I guess you mean AnotherClass implements Example. Well, this is what you wanted: have AnotherClass implement Example with some default implementation as well as extend another class, or I understood you wrong. Since you cannot extend more than one class, you have to implement the interface so you can do
final Example anotherClass = new AnotherClass();
Otherwise this will not be possible.
Also for every class that implements an interface do I have to design
an inner class?
No, it doesn't have to be an inner class, that was just an example. If you want multiple other classes have this default Example implementation, you can just write a separate class and wrap it inside all the classes you want.
class DefaultExampleImpl implements Example {
// Implements the methods
}
class YourClass extends YetAnotherClass implements Example {
private Example example = new DefaultClassImpl();
#Override
public void method1() {
this.example.method1();
}
#Override
public String method2(final int parameter) {
return this.example.method2(parameter);
}
}
You can create an abstract class to implement that interface, and make your those classes inherit that abstract class, that should be what you want.
A non abstract class that implements and interface needs to implement all the methods from the interface. A abstract class doesn't have to implement all the methods but cannot initiated. If you create abstract class in your example that implements all the interface methods except one. The classes that extend from these abstract class just have to implement the one not already implemented method.
The Java interfaces could have been called contracts instead to better convey their intent. The declarer promise to provide some functionality, and the using code is guaranteed that the object provides that functionality.
This is a powerful concept and is decoupled from how that functionality is provided where Java is a bit limited and you are not the first to notice that. I have personally found that it is hard to provide "perfect" implementations which just need a subclass or two to be usable in a given situation. Swing uses adapters to provide empty implementations which can then be overrides as needed and that may be the technique you are looking for.
The idea of the interface is to create a series of methods that are abstract enough to be used by different classes that implement them. The concept is based on the DRY principle (Don't repeat yourself) the interface allows you to have methods like run() that are abstract enough to be usuable for a game loop, a players ability to run,
You should understand the funda of interface first. Which is
It is use to provide tight coupling means tight encapsulation
It helps us to hide our code from the external environment i.e. from other class
Interface should have only definition and data which is constant
It provide facility to class open for extension. Hence it cannot be replace by the any other class in java otherwise that class will become close for extension. which means class will not be able to extend any other class.
I think you are struggling with the concept of Object Oriented Design more than anything. In your example above where you state you have 100 classes and 70 of them have the same method implementation (which I would be stunned by). So given an interface like this:
public interface Printable
{
void print();
}
and two classes that have the "same" implementation of print
public class First implements Printable
{
public void print()
{
System.out.println("Hi");
}
}
public class Second implements Printable
{
public void print()
{
System.out.println("Hi");
}
}
you would instead want to do this:
public abstract class DefaultPrinter implements Printable
{
public void print()
{
System.out.println("Hi");
}
}
now for First and Second
public class First extends DefaultPrinter
{
}
public class Second extends DefaultPrinter
{
}
Now both of these are still Printable . Now this is where it gets very important to understand how to properly design object hierarchies. If something IS NOT a DefaultPrinter YOU CANNOT AND SHOULD NOT make the new class extend DefaultPrinter

Java initializing abstract classes

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.

Anonymous class definition based on interface... maybe?

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();
}
}

Are there good reasons for a public constructor of an abstract class

It is not possible to create an object by directly calling the constructor of an abstract class. The constructor of an abstract class can be called only from a derived class. It therefore seems to me that constructors of an abstract class must be either protected or package-private (the latter for the unusual cases of restricting use of a constructor to derived classes within the package). Yet Java allows the constructor of an abstract class to be public.
Are there any circumstances in which it is useful to declare the constructor of an abstract class to be public, rather than protected or package-private?
This is not quite a duplicate of the question "Abstract class constructor access modifier": clearly you can declare a constructor to be public; I want to know whether there is ever any good reason to do so. It seems to me that there is not. I see that C# has a similar peculiarity.
The answer is the same for java:
THere's no reason for a public constructor for an abstract class. I'd assume that the reason that the compiler doesn't complain is as simple that they just didn't spend time covering that since it really doesn't matter if it's public or protected. (source)
You can't call a constructor of an abstract class from anything other than a direct subclass.
So adding a special rule for access modifiers of constructors of abstract classes wouldn't add something useful to the language.
One thing that looks like an exception from this rule - if the abstract class only defines a default constructor, then the subclass does not have to implement a constructor: this is legal:
public abstract class A {
public A() {}
}
public class B extends A {}
So we can create a B by calling new B() - but note, that we still create a B and not an A. And, again, it doesn't matter if the constructor in A is public or protected. It just shouldn't be private, but the compiler will notice and complain...
Actually we invoke an "invisible" public default constructor on B which does a simple super() call...
The visibility also infuences what is shown in the javadoc (if it's selected to exclude certain visibility levels). As it doesn't matter otherwise, that could be a usage for a public constructor of an abstract class.
If you provide no constructor, then the default constructor is public if the class is public. Easiest option would be to allow that, rather than forcing protected constructors.
In that sense the reverse question may make it clear: why didn't they force protected constructors in abstract classes? Because public constructors won't change anything, so it would just take time and add complexity.
Call me a heretic, but ... I see at least one use for a constructor in an abstract class.
That is: to specify what the constructor parameters look like.
Specify an abstract constructor (thus making the class abstract). Derived classes have to implement this constructor with its specific signature to lose abstract status.
I see no other way to specify mandatory constructor signatures (help me out if you do).
You can have a public constructor if you do not define in a constructor in the sub-class.
example
abstract class Animal {
String name;
public void Animal(String name) {
this.name = name;
}
}
class Cat extends Animal{
public String sayMayName() {
return this.name;
}
}
myCat = new Cat("tester");
name = myCat.sayMyName();
if no constructor is defined the parent class constructor will be called, if it is not public it will not work. This I think is more elegantly done with a factory pattern, but I used it in practice in PHP and it works fine.

Categories