Abstract class 'instantiation' with a body of its methods - java

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.
}
})

Related

Java: Abstract Class Invocation via Main Method

Okay, people are probably going to run to flag this as a duplicate, just by reading the title and without really reading the question. So please know that I HAVE tried to look at other questions on this platform, but have not found something that clears my doubts exactly. Kindly allow me to reach out and ask my question. Thanks in advance.
Interface is absolutely abstract and cannot be instantiated; A Java abstract class also cannot be instantiated, but can be invoked if a main() exists.
I do not completely understand the latter part of the statement. Is this talking about the main method being directly within the abstract class itself ? Is it talking about invoking the abstract class via a child's main method ? Or both ?
Secondly, I have seen examples like the following.
abstract class Printer
{
public void print() { … };
}
public class TestPrinter
{
public static void main( String[] args )
{
// use of anonymous class
final Printer p = new Printer()
{
#override
public void print()
{
...
}
}
}
}
And have been told that an anonymous class is at work. But, I seriously do not understand how, since the variable 'p' is clearly being assigned to... and it's an abstract class variable!! How is that even possible? I thought abstract classes can not be instantiated or initialized.
Any help would be appreciated.
final Printer p = new Printer()
{
#override
public void print()
{
...
}
}
This means that an anonymous class is created which extends Printerand the variable p is referring to subclass instance.
This is simply polymorphism in action. By creating anonymous class here, you are creating a subclass of Printer and using polymorphism you are using the superclass reference variable p to refer to object of subclass which is anonymous but extends Printer because of the syntax below
Printer p = new Printer(){...}
and this is not only limited to abstract class, you can also create an anonymous class which implements and interface. Consider below example.
package com.test;
public interface SomeInterface {
public void SomeMethod();
}
and a class below
package com.test;
public class TestAnonymous {
public static void main(String[] args) {
SomeInterface obj = new SomeInterface() {
#Override
public void SomeMethod() {
System.out
.println("Yaayy!!! Creating an anonymous class which implements SomeInterface ");
}
};
obj.SomeMethod();
}
}
which prints out
Yaayy!!! Creating an anonymous class which implements SomeInterface
What is means that the syntax creates an anonymous class which either extends the abstract class or implements the interface of which reference variable is used to instantiate. It calls method of the subclass.
You can refer jsl.https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.9.1
Now your question
Interface is absolutely abstract and cannot be instantiated; A Java abstract class also cannot be instantiated, but can be invoked if a main() exists
What I understand from your questions is whether you want to know whether main method can be run in abstract class without instantiating it, The answer is YES
package com.test;
public abstract class AbstractClass {
public static void main(String[] args) {
System.out.println("main method in abstract class");
}
}
compile and invoke it using java AbstractClass and it should print
main method in abstract class
IF you want to know whether the abstract class constructor is invoked when instantiating the anynomous class or not, then also the answer is YES.
Whenver a subclass constructor is called, it invokes super class constructor by making a super() call. So abstract class constructor will also get called.
http://www.thejavageek.com/2013/07/21/initialization-blocks-constructors-and-their-order-of-execution/
An abstract class is just like any other class - except for the fact that it cannot be instantiated directly. I presume you know the use for such a facility. Hence it can very well have a main(), which is a static method, not an instance method
The anonymous class in your example, extends the abstract class (or implements an interface, if one is specified). So p is not assigned to an abstract class instance, but to an instance of a class which extends the abstract class
A Java abstract class also cannot be instantiated, but can be invoked if a main() exists.
It is nonsense. Any static method of an abstract class can be invoked. Not just main().
Secondly, I have seen examples like the following ... and have been told that an anonymous class is at work.
That is correct.
But, I seriously do not understand how, since the variable 'p' is clearly being assigned to... and it's an abstract class variable!! How is that even possible? I thought abstract classes can not be instantiated or initialized.
It is the anonymous class that is being instantiated here, which extends the abstract class, and provides an implementation of the abstract method. The reference to that class is being stored into Person p, because Person is a superclass of the anonymous class. You can do that for any other class or interface. There's nothing new here.
A Java abstract class also cannot be instantiated, but can be invoked if a main() exists.
Since main() method is static an can be invoked without instantiation. e.g.
abstract class AbstractClass{
public static void main(String[] args){
}
}
The same was not true for interface till Java7, With Java8 you can have static main method inside interface hence same would be true for Java8
You second question, while creating an instance of Printer you have defined the sub-class of Printer as well but you can not use this defined implementation of Printer again(since there is no name associated with the implementation), Hence, its anonymous.

Abstract class having a main?

Would using a main for an abstract class be bad practice in general or is it permissible due to the nature of Abstract classes being able to have a body?
Sure, an abstract class can have a main method, just as any class can have a main, and in fact it is one way of testing the abstract class -- if you create a concrete implementation of it within the main method. The only thing that you cannot do with an abstract class is to construct them as is, without extending them and implementing all abstract methods.
public abstract class Foo {
public abstract void bar();
public static void main(String[] args) {
// anonymous inner class representation
Foo foo = new Foo() {
// must implement all abstract methods
public void bar() {
System.out.println("bar");
}
};
foo.bar();
}
}
Edit: good point by VitalyGreck:
abstract classes are abstract because they don't implement some methods in their body. having bar() implemented inside the main() method (even static) confuses users of your class. Good practice is to make two separate classes, one of them - abstract, another - with implementation and static method enclosed. Or dynamically find the enclosing class (see stackoverflow.com/questions/936684/…) using reflection.
In other words -- just because it can be done, doesn't mean that it should be done.
You have no problemas having a main in your abstract class.
Static methods does not override, any subclass can also have the same static method.

Interface is not allowed inside methods

I have studied some books for OCPJP 7 certification and in the inner classes chapter there were some strange/incomplete informations. I've tried to create an interface inside a method, but it seems you can't do that, you can only create classes inside a method. Is there any reason why you can't do that or it's just a missing feature?
Sample code:
public class Outer {
public void method() {
class C {} // allowed
interface I {} // interface not allowed here
}
}
If you read carefully the Java Tutorials, you will see that:
You cannot declare an interface inside a block, because interfaces are inherently static.
This means that if you have an interface, like this one:
public class MyClass {
interface MyInterface {
public void test();
}
}
You will be able to do
MyClass.MyInterface something = new MyClass.MyInterface() {
public void test () { .. }
};
because MyInterface will be explicitly static. It doesn't make sense to be tied to an instance of the enclosing class, because it just provides some abstraction which doesn't have to be bound to a specific instance or a state of the enclosing class.
Same thing goes to the case, in which the interface is nested in a method. Nothing inside the method could be (explicitly) static (because non-static methods are tied to a specific instance of the enlosing class) and thus you can't have a local interface.

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)

This appears to create an object from an interface; how does it work?

interface Int {
public void show();
}
Int t1 = new Int() {
public void show() {
System.out.println("message");
}
to.show();
You're defining an anonymous class that implements the interface Int, and immediately creating an object of type thatAnonymousClassYouJustMade.
This notation is shorthand for
Int t1 = new MyIntClass();
// Plus this class declaration added to class Test
private static class MyIntClass implements Int
public void show() {
System.out.println("message");
}
}
So in the end you're creating an instance of a concrete class, whose behavior you defined inline.
You can do this with abstract classes too, by providing implementations for all the abstract methods inline.
What this special syntax for anonymous inner classes does under the hood is create a class called Test$1. You can find that class file in your class folder next to the Test class, and if you printed t1.getClass().getName() you could also see that.
i think your object has nothing to do with the interface. If you comment out the whole interface, still you will get the same output. Its just anonymous class created. I think, unless you use the class "implements" you cant implement the interface. But i dunno how naming collision doesn't happen in your case.

Categories

Resources