Let assume that we develop a simple blog website backend and the app have three or more POJO classes like Post
, User
, Category
.
All class have the same fields such as id
, createdDate
, updateDate
.
As java-programmers, we apply Encapsulation to all the fields in a class using private
access modifier. My question is very simple: Can we perform encapsulation using default access modifier with Inheritance?
The code:
public abstract class BaseModel {
String id;
LocalDateTime createdDate;
LocalDateTime updatedDate;
// getters and setters
}
public class Post extends BaseModel{
private String slug;
private String name;
private String title;
// other fields, getters and setters
}
public class Category extends BaseModel{
private String name;
private String slug;
// other fields, getters and setters
}
CodePudding user response:
Protected modifier
The common practice it to use protected
access modifier to encapsulate class members within the Parent class.
Package private fields and methods will not be visible to subclasses located outside the package of the Parent class. Conversely, protected
variables and behavior will be accessible to any subclass regardless of its location.
Composition vs Inheritance
Inheritance is not always beneficial, in-fact there are many cases where it isn't. You need to consider all pros and cons before making class-design decisions like whether a particular class will derive from another class.
What are the benefits of extending the BaseModel
?
It doesn't feel like you can take advantage from the polymorphism here. Because the only behavior you can use with the parent type BaseModel
are getters and setters for dates of creation and update. And at the same time you'll not be able to access the specific behavior of subclasses.
It looks rather as a drawback because BaseModel
isn't designed for extension. I.e. it neither contains any useful implementations (I'm not taking getters/setters into account), no abstract methods are meant to be implemented by its subclasses (that would be a scenario of advantageous polymorphism).
In fact, you are extending BaseModel
just in order to reuse a couple of variables. That not a compelling reason to utilize inheritance.
Your example is a perfect case to substitute an IS A relationship (Post
is a BaseModel
) with HAS A relationship (Post
includes BaseModel
).
The design technic, when a class contains its instance field an instance of another class instead of extending this class, is called Composition.
As a general rule, composition is a more preferable approach than inheritance. As well as inheritance, it allows to reuse the behavior and at the same time it classes closely coupled.
If you make the BaseModel
a concrete class and apply composition to other classes, your code will look like that.
public class BaseModel {
private String id;
private LocalDateTime createdDate;
private LocalDateTime updatedDate;
// getters and setters
}
public class Post {
private BaseModel base;
private String slug;
private String name;
private String title;
// other fields, getters and setters
}
public class Category {
private BaseModel base;
private String name;
private String slug;
// other fields, getters and setters
}
CodePudding user response:
the default modifier signifies it's only accessible in the package. So if you are using a child class in a different package, the fields will not be accessible.
If that's want you want, great! It's encapsulated.
If that's not what you want, bummer... BUT you still have the protected modifier.
This let's a child class inherit the fields even if it's in a different package.
See this answer too: What is the difference between public, protected, package-private and private in Java?