Composition, inheritance and delegation are 3 main methods to reuse classes.
Delegation is not a familiar concept for me, and it is not directly supported. However, I think I have used its content before. It just put a member object in the new class and expose all method to the new one.
About inheritance, it always calls the super() constructor even if you don’t called it literally in derived class. As a result, if the base class don’t have a constructor without any parameters, and you don’t call base class constructor literally in derived class, you will get a compile time error.
Upcasting is brought by inheritance. Basically, it means a reference of base class can refer to an instance of derived class. Making good use of this feature help DRY. In some cases, whether using inheritance depends on if upcasting is necessary.
“Final” usually means “unchangeable”.
If a data is final, then it can either initialize in compile time or run time, and cannot be changed since then. If it is static and final, it has only one piece of storage that cannot be changed.
For non-static final, it can be left blank when declaration, but then must be decided in constructor. In conclusion, a final field must be assigned either with an expression at definition of the field or in every constructor. Of course, if it is static, assignment in constructor is also impossible.
If a reference is final, then it cannot refer to another Object. The object itself can also be changed. You cannot make object unchangeable by using final.
If a parameter of a method is final, it cannot be changed in method. It is usually used to transfer data to anonymous inner class.
Making a method final is to prevent derived class change it. Historically, it may also improve the efficiency, but now this purpose is less useful.
As a result, a private method implies final. People can add final modifier to private method, but it is meaningless. Note that in derived class, you can define method with same name and parameter types, but it is NOT overriding, since private methods are totally invisible in derived class.
If a class is final, it cannot have any derived class.
Expecting a method to be final means it cannot be override. However, your expectation may not be reasonable. An example is Vector class in previous version of Java. Final methods make late implement of Collections use ArrayList instead.
At the end of this captor, it emphasize again that statics are initialized at the first use of the class, it can be when the first object of that class (includes derived class) is constructed, or when a static field or static method is accessed.