The question is inspired by the topic. Why does java need a protected constructor

I wanted to use the class java.util.Calendar as a protected constructor. But first I looked at the source and, with surprise, I found out that this class is abstract. Always believed that you cannot create an instance of an abstract class. But you can get an object of class Calendar using

Calendar cal = Calendar.getInstance(); 

What then is the essence of the prohibition to create an instance of an abstract class? I just can't write in the code for new Calendar ()? And through some other methods can I safely get an instance of this class? That is, is it true that "if a class is abstract, then its default constructor is protected"?

    2 answers 2

    If you look into the implementation of getInstance, you will see that this method calls another static method createCalendar, and already it creates not objects of the abstract class Calendar, but objects inheriting from this class, for example BuddhistCalendar. Since BuddhistCalendar inherits Calendar, implicit coercion to this type is allowed.

      Let's distinguish between a declared and a real type of object. The link that you have refers to the declared type, a type known at compilation. But the real type of the object can be any derived from the declared type.

      For example, if you have a List<String> l , then the real object by reference may be, for example, of type ArrayList<String> .

      Now back to the subject. You cannot have an instance with a real type corresponding to an abstract class. Because such an object simply can not be constructed. But the declared type of Calendar means that there really is either Calendar (which is impossible, since it is abstract), or any type derived from it.

      Check :

       Calendar c = Calendar.getInstance(); System.out.println(c); 

      We get the output (in my case) java.util.GregorianCalendar[... is an instance of a derived type.


      The essence of the ban on creating an abstract class is that this class is not over , and must be over in the generated classes. For example, there are no methods in it. If this class is not ready for use, then it cannot be created. But the finished, ready-to-use generated classes can be instantiated.