Search code examples
javaconstructorabstract-classdefaultabstract

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!


Solution

  • 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"