SCJP cheat sheet. Part two

Part 1
Encapsulation and inheritance

  • Remember the difference in terms that define relationships between classes. IS-A is when one class inherits another class (extends) or implements an interface (implements). HAS-A is said when a reference to an object of another class is used in one class.
  • The code written on the principle of encapsulation contains private variables that are accessed through methods (setVarName and getVarName).
  • Inheritance is the basic concept behind polymorphism, type casting, overloading, and overriding methods.
  • In java, all classes are descendants of Object.


Polymorphism

  • Cannot change the type of reference variable. But a variable can refer to an object of a descendant of its class. That is, variables of different types can refer to one object. The main thing is that all these types are superclasses for the object class. Therefore, a variable of type Object can refer to an object of any type.
            List<Integer> list;
            list = new ArrayList<Integer>(); //ArrayList и LinkedList реализуют интерфейс List, поэтому мы можем так делать
            list = new LinkedList<Integer>(); 
            list = new String(); //Ошибка при компиляции
    
  • Only the type of reference variable determines which object methods you can call. In other words, if you want to use methods specific to this class, then you cannot call them from a variable of the superclass type.
    public  class Fruit {
        public void eat(){
            System.out.println("NomNomNom");
        }
    }
    
    class Apple extends Fruit{
        public void grow(){
            System.out.println("I'm growing");
        }
        public static void main(String[] args) throws InterruptedException {
            Fruit fruit;
            fruit = new Apple();
            fruit.eat(); //Метод eat описан в суперклассе, мы можем к нему обращаться
            fruit.grow(); //Ошибка! Метод grow специфичен для класса Apple, поэтому мы не можем обращаться к нему через переменную типа Fruit
        }
    }
    
  • Polymorphism only works with object methods, but not with static methods.


Overload and Override

  • Methods can be overloaded and overridden. Constructors are just overloaded.
  • When overriding methods
    1. Must have an unchanged list of arguments.
    2. Must have an immutable return type.
    3. The access level cannot be lower than the inherited method.
    4. Must not throw new exceptions.
  • Only inherited methods can be redefined.
  • You can access the redefinable method like this:
    public  class Fruit {
        public void eat(){
            System.out.println("NomNomNom");
        }
    }
    class Apple extends Fruit{
        public void grow(){
            System.out.println("I'm growing");
        }
        public void eat(){
            System.out.println("NomAppleNom");
        }
        public void test(){
            eat();//Вызовет переопределенный метод
            super.eat();//Вызовет метод суперкласса
        }
    }
    
  • When overloaded methods
    1. Must have a new argument list.
    2. May have a new return type.
    3. They can have a new level of access without restrictions.
    4. May throw new exceptions
  • Superclass methods can be overloaded in the descendant.
  • Polymorphism applies only to overriding - not to reloading.


Return Types

  • You can use null and arrays as the return value.
  • If the return type is primitive (byte, int, float etc), then java will perform implicit type conversion, if possible.
    public  class Fruit {
        public int eat(){
            byte b = 127; 
            return b; //Компилятор автоматически расширит byte b до int.
        }
        public int grow(){
            long l = 42;
            return l;  //Ошибка! Несмотря на то что int вполне может представить число 42 без потерь,
                            //нам необходимо использовать явное приведение return (int) l;
        }
    }
    

  • For void methods, you can use the return keyword if you want to abort the method.
  • If the method returns an object, you can use the descendants of the class of this object as the return value.


Constructors


  • Each class, when creating an object, first calls a constructor. The compiler automatically inserts a call to the constructor of the superclass without parameters into each constructor. Thus, the constructor of Object is always executed first, then the constructor of the first descendant of Object, and so on.
  • Constructors have the same name as the class, any level of access, but do not have a return value.
  • If you do not create a constructor, the compiler will create it for you. The generated constructor has no accepted arguments, and its body consists of calling the constructor of the superclass super () ;.
  • Abstract classes have a constructor, but interfaces do not.
  • If a superclass does not have a constructor without arguments, then you need to explicitly declare a super () call in the constructor of the class; and pass the necessary variables.
  • Constructors are never inherited, but they can be overloaded
  • Constructors can only be called directly from other constructors using this (); and super () ;.
  • Example:
    public  class Fruit {
        public Fruit(String str){
            System.out.println("Fruit constructor");
        }
    }
    class Apple extends Fruit{
        public Apple(){
            super("apple");
            System.out.println("Apple's constructor");
        }
    }
    public class GreenApple extends Apple{
        public GreenApple(){
           System.out.println("GreenApple's constructor");
        };
    Вывод:
    Fruit constructor
    Apple's constructor
    GreenApple's constructor
    }
    


Static Methods and Variables

  • Use static methods if its behavior does not depend on the state of the object.
  • Static methods have access only to static variables.
  • Static members are not tied to an object, but to a class.
  • Static methods cannot be overridden.


References:
SCJP Sun Certified Programmer for Java 6 Exam 310-065