OO
Encapsulation
Access Levels
Default Access
aka Package access level
If no OOP#Access Specifiers are used with a member, it becomes default.
OOP#Access specifiers applied to classes
- Top-level classes other than the main public class can have only default (unspecified) package level access in Java.
Sealed Classes
Sealed classes restrict which classes can inherit them, enhancing encapsulation and giving more control.
Introduced in Version#17.
public abstract sealed class Shape permits Circle, Rectangle {
// Common methods and fields
}
public final class Circle extends Shape {
// Circle-specific implementation
}
public final class Rectangle extends Shape {
// Rectangle-specific implementation
}
Inheritance
- Implemented by extends keyword
Types of Inheritance in Java
- OOP#Single Inheritance
- OOP#Multilevel Inheritance
- OOP#Hierarchical Inheritance
- OOP#Hybrid Inheritance
OOP#Multiple inheritance not allowed
Inheritance in case of #Default Access
- Are fields and methods with
default
access inherited?
Only if the subclass is located in the same package as the superclass.
- How is multiple inheritance handled in case of methods with
default
access?
In case both parent interfaces have a default method with same method signature, the implementing class should explicitly tell which one its trying to use or it should override the default method.
//If I1 and I2 both have a fun() as default method
class C implements I1, I2{
I1.super.fun(); //Use I1's fun() method
}
Polymorphism
Overriding
Overriding by return types
Before Java 5 it wasn't possible to override a method based on its return type. Now, we can override a method if its return types are in the same direction as the subclass, that is, if the methods have OOP#Covariant Return Types.
Features
OOP#Object Context Qualifiers
this
- OOP#Self-referencesuper
- OOP#Super
Inner Class
Anonymous Inner Class
main(){
A obj = new A();{
func(){
Syso("This is an anonymous class")
}
}
}
OR (post Java 8)
main(){
A obj = () -> Syso("anonymous class")
}
Member Inner Class
If class B is inside class A => B is a member and an inner class
main(){
A obj = new A();
A.B obj1 = obj.new B();
}
//If j is member of class B
obj1.j=5;
.class
files generated in this case:
A.class
A$B.class
'Qualified this' construct
Member classes have an implicit reference to an instance of the enclosing (outer) class. Qualified This refers to this instance.
If the outer class is A and inner class is B, you can refer to this instance of A from B as A.this
.
Since we are using a qualifier along with this
, to form a fully qualified identifier, it is called "Qualified" this
.
Reference
In Effective Java inside the item "Item 22: Favor static member classes over nonstatic" Josh Bloch says:
Each instance of a nonstatic member class is implicitly associated with an enclosing instance of its containing class. Within instance methods of a nonstatic member class, you can invoke methods on the enclosing instance or obtain a reference to the enclosing instance using the qualified this construct. ^064042