Site Search:

Use abstract classes and interfaces


Back OCAJP



When a class is marked with the abstract keyword, it can not be instantiated; when a method in an abstract class is marked with the abstract keyword, the methods can not have a body. An abstract class can have abstract method, non-abstract method, both abstract and non-abstract methods, or no method at all. The first concrete class that extends an abstract class have to override all the abstract methods. Since an abstract class need to be extended, it can not be marked as final; an abstract methods can not be marked as private or final.


OCAJP>cat test.java 
class test {
  public static void main(String...args) throws Exception{
    //aClass1 a = new aClass1();  //error: aClass1 is abstract; cannot be instantiated
    realOne r = new realOne();
    new realOne3();
  }
}
//class abstract aClass{}  //error: <identifier> expected
//final abstract class aClass1{}  //error: illegal combination of modifiers: abstract and final
abstract class aClass1{}
abstract class aClass2{
  abstract void unfinished();
  //abstract void unfinished2(){}  //error: abstract methods cannot have a body
  void normalOne() {}
  //private abstract void unfinished3();  //error: illegal combination of modifiers: abstract and private
  //final abstract void unfinished3();  //error: illegal combination of modifiers: abstract and final
}
abstract class aClass4{
  void normalOne(){}
}
class aClass5{
  //abstract void unfinished();  //error: aClass5 is not abstract and does not override abstract method unfinished() in aClass5
}
class realOne extends aClass4{}
//class realOne2 extends aClass2{}  //error: realOne3 is not abstract and does not override abstract method unfinished() in aClass2
class realOne3 extends aClass2{
  void unfinished() {}
}

OCAJP>javac test.java 
OCAJP>java test


The purpose for abstract class is to allow approach goal little by little. The abstract class that extends another abstract class inherits all of its methods, both abstract or non-abstract. The extending class can choose to override some of the abstract methods, it can also add more abstract methods. The first concrete class that extending abstract class have to override all the abstract methods either by its superclasses or by itself.


OCAJP>cat test.java 
class test {
  public static void main(String...args) throws Exception{
    real r = new real();
    r.buildTreeHouse();
    System.out.println(r.year);
    wish w = r;
    System.out.println(w.liveInTreeHouse());
    System.out.println(w.year);
  }
}
abstract class wish{
  //abstract int a; //error: modifier abstract not allowed here
  int year = 2010;
  abstract boolean liveInTreeHouse();
}
abstract class idea extends wish{
  public idea() {year++;}  
  abstract void ownALand();
  void saveMoney() {System.out.println("Better to save some money");}
}
abstract class plan extends idea{
  public plan() {year++;}
  abstract void buyHouse();
  public void ownALand(){buyHouse();}  //non-abstract can call abstract method, since finally all will be real
}
class real extends plan{
  void buyHouse() {saveMoney();}
  void buildTreeHouse() {System.out.println("idea->plan->blue print->permission->build->inspection->treehouse");} 
  boolean liveInTreeHouse() {year++; return true;}
  void enjoyView(){}
  void bbqInYard(){}
  void haveFunWithKids(){}
  void geekHome(){}
  void growVegi(){}
  //...
}
OCAJP>javac test.java 
OCAJP>java test
idea->plan->blue print->permission->build->inspection->treehouse
2012
true
2013




Java defines an interface with interface keyword. An interface is abstract. When abstract modifier is omitted, compiler adds it for you. The abstract and final modifiers are illegal combination in java. The access modifier for top-level interface is either public or default. A class implements an interface have to implement all the abstract methods of the interface. All the interface members (abstract methods, default methods, interface variables, static interface methods) in an interface have to be public.

Interface can optionally have public static final variables. Since interface can not be instantiated, these interface variables can only be accessed via interface name or the implementing class's class name.

Java 8 introduced a new feature: besides abstract methods, interface can optionally have default method. A default method must be marked with default keyword. If a method is marked with default, it must provide a method body. A default method defines an abstract method with a default implementation. Classes can optionally override the default method, if they choose not to, the default implementation is used.

Java 8 also introduced public static interface method, which is accessed via the name of the interface.
static interface methods can be inherited by extending interfaces, however can not be inherited by implementing classes.


OCAJP>cat test.java 
class test {
  public static void main(String...args) throws Exception{
    duck2 d = new duck2();
    duck3 d3 = new duck3();
    d.donnotTouch();
    d3.donnotTouch();
    d.touchMe();
    d3.touchMe();
    System.out.println("invar1 from duck2, duck3, canCry, subCanCry");
    System.out.println(duck2.invar1);
    System.out.println(duck3.invar1);
    System.out.println(canCry.invar1);
    System.out.println(subCanCry.invar1);
    System.out.println("invar2 from duck2, duck3, canCry, subCanCry");
    System.out.println(duck2.invar2);
    System.out.println(duck3.invar2);
    System.out.println(canCry.invar2);
    System.out.println(subCanCry.invar2);
    System.out.println("interfaceMethod() from canCry, subCanCry");
    //duck2.interfaceMethod();  //error: cannot find symbol
    canCry.interfaceMethod();
    subCanCry.interfaceMethod();
  }
}
abstract interface canCry{
  public abstract void cry();
  //private abstract void a();  //error: modifier private not allowed here
  //final abstract void b();  //error: modifier final not allowed here 
  //interface variable
  public static final String invar1 = "no constructor to initialize me";
  public static final String invar2 = "no constructor to initialize invar2";
  //static interface method
  static void interfaceMethod() {System.out.println("only accessible via interface name");}  //public by default
  //default interface method
  default void donnotTouch() {System.out.println("if no override, println is the default method");}  //public by default
  //public default final static void touchMe() {}//error: modifier final not allowed here
  //public default static void touchMe() {}  //error: illegal combination of modifiers: static and default
  public default void touchMe() {System.out.println("in touchMe");} 
}
interface subCanCry extends canCry{  //abstract omitted
  //interface variable
  static final String invar1 = "no relationship in invar1 defined in canCry, happen to have same name";
  //static interface method
  public static void interfaceMethod() {System.out.println("access from subCanCry interface name only");}
  //default interface method
  public default void donnotTouch() {System.out.println("why not?");}
}
//class duck implements subCanCry{}  //error: duck is not abstract and does not override abstract method cry() in canCry
abstract class duck1 implements subCanCry{}
class duck2 implements subCanCry{
  public void cry(){}
}
class duck3 implements subCanCry{
  //void cry(){}  //error: attempting to assign weaker access privileges; was public
  public void cry(){}
  public void touchMe(){System.out.println("override touchMe in duck3");}
}
OCAJP>javac test.java 
OCAJP>java test
why not?
why not?
in touchMe
override touchMe in duck3
invar1 from duck2, duck3, canCry, subCanCry
no relationship in invar1 defined in canCry, happen to have same name
no relationship in invar1 defined in canCry, happen to have same name
no constructor to initialize me
no relationship in invar1 defined in canCry, happen to have same name
invar2 from duck2, duck3, canCry, subCanCry
no constructor to initialize invar2
no constructor to initialize invar2
no constructor to initialize invar2
no constructor to initialize invar2
interfaceMethod() from canCry, subCanCry
only accessible via interface name
access from subCanCry interface name only


Here is a question: interface is so similar to abstract class with abstract methods only, that interface looks just a redundant feature.

Interface have a key difference from abstract class. While abstract can only extends a single superclass; interface can extends multiple interfaces, also an class can implement multiple interfaces. By introducing interface, java got multiple inheritance feature to some extent.

Back OCAJP