Inheritance, Interfaces, and Polymorphism
Parent Construction, `super`, and Inherited Access
You are viewing a free preview lesson.
Lesson Overview
একটি child object তৈরি করলে শুধু child class-এর constructor execute হয় না।
তার parent অংশও initialize হতে হয়।
Consider:
VideoLesson videoLesson =
new VideoLesson(
1L,
"Inheritance Basics",
"https://cdn.liveklass.io/videos/inheritance",
18
);
VideoLesson একটি ContentItem।
তাই objectটির মধ্যে conceptually দুই ধরনের state আছে:
ContentItem state:
id
title
published
VideoLesson state:
videoUrl
durationInMinutes
VideoLesson constructor শুধু video-specific state initialize করলেই যথেষ্ট নয়।
Parent-এর required stateও validভাবে initialize করতে হবে।
এই কাজের জন্য Java super(...) ব্যবহার করে।
এই lesson-এ আমরা শিখব:
- Parent constructor কেন execute হয়
super(...)- Automatic
super() - Constructor execution order
- Parent constructor validation
this(...)এবংsuper(...)- Inherited members
- Parent-এর
privatestate protectedaccess- কেন fields সাধারণত
privateরাখা ভালো finalmethod এবংfinalclass- Safe inheritance API design
Learning Objectives
এই lesson শেষ করার পর আপনি পারবেন:
- Child object creation-এর সময় parent constructor কেন প্রয়োজন explain করতে
super(...)দিয়ে parent constructor call করতে- Automatic
super()কখন add হয় বুঝতে - Parent এবং child constructor execution order predict করতে
this(...)এবংsuper(...)-এর relationship explain করতে- Parent-এর
privatefields child direct access করতে পারে না কেন বুঝতে - Inherited public এবং protected members ব্যবহার করতে
protectedfield-এর design risk explain করতেfinalmethod দিয়ে overriding prevent করতেfinalclass দিয়ে inheritance prevent করতে
A Child Object Contains Parent State
Parent class:
public class ContentItem {
private final long id;
private final String title;
private boolean published;
public ContentItem(
long id,
String title
) {
if (id <= 0) {
throw new IllegalArgumentException(
"Content ID must be positive."
);
}
if (
title == null
|| title.isBlank()
) {
throw new IllegalArgumentException(
"Content title is required."
);
}
this.id = id;
this.title = title.strip();
this.published = false;
}
}
Child class:
public class VideoLesson
extends ContentItem {
private final String videoUrl;
private final int durationInMinutes;
}
A VideoLesson object-এর নিজের fields:
videoUrl
durationInMinutes
এবং inherited parent state:
id
title
published
থাকে।
তাই child object creation-এর সময় parent portion initialize হওয়া বাধ্যতামূলক।
Calling the Parent Constructor
Child constructor থেকে parent constructor call করতে:
super(...)
Example:
public class VideoLesson
extends ContentItem {
private final String videoUrl;
private final int durationInMinutes;
public VideoLesson(
long id,
String title,
String videoUrl,
int durationInMinutes
) {
super(
id,
title
);
this.videoUrl =
videoUrl;
this.durationInMinutes =
durationInMinutes;
}
}
এখানে:
super(
id,
title
);
ContentItem(long, String) constructor call করছে।
Why super(...) Is Necessary
Parent class fields:
private final long id;
private final String title;
Child class directভাবে এগুলো assign করতে পারে না।
Wrong:
public VideoLesson(
long id,
String title
) {
this.id = id;
this.title = title;
}
Compile হবে না।
কারণ:
idএবংtitleContentItem-এরprivatefields- Field initialization parent class-এর responsibility
- Parent constructor validationও preserve করতে হবে
Correct:
super(
id,
title
);
Parent নিজের state নিজে initialize করে।
Parent Validation Is Reused
Parent constructor:
public ContentItem(
long id,
String title
) {
if (id <= 0) {
throw new IllegalArgumentException(
"Content ID must be positive."
);
}
if (
title == null
|| title.isBlank()
) {
throw new IllegalArgumentException(
"Content title is required."
);
}
this.id = id;
this.title = title.strip();
}
Child constructor:
public VideoLesson(
long id,
String title,
String videoUrl,
int durationInMinutes
) {
super(
id,
title
);
// Child validation
}
এখন প্রতিটি child class-এ parent validation duplicate করতে হচ্ছে না।
VideoLesson
ArticleLesson
QuizLesson
সবাই same parent creation rules follow করবে।
Constructor Execution Order
Child object তৈরি হলে constructor execution parent থেকে child-এর দিকে যায়।
Example hierarchy:
Object
└── ContentItem
└── VideoLesson
Creation:
new VideoLesson(...);
Conceptual execution order:
1. Object constructor
2. ContentItem constructor
3. VideoLesson constructor
Java সবসময় parent state আগে initialize করে।
তারপর child-specific initialization complete করে।
Observing Constructor Order
public class ContentItem {
public ContentItem(
long id,
String title
) {
System.out.println(
"ContentItem constructor"
);
}
}
public class VideoLesson
extends ContentItem {
public VideoLesson(
long id,
String title
) {
super(
id,
title
);
System.out.println(
"VideoLesson constructor"
);
}
}
Usage:
new VideoLesson(
1L,
"Inheritance"
);
Output:
ContentItem constructor
VideoLesson constructor
Parent constructor body আগে execute হয়েছে।
Why Parent Runs First
Child class parent state এবং behavior-এর ওপর depend করতে পারে।
Example:
public class VideoLesson
extends ContentItem {
public VideoLesson(
long id,
String title
) {
super(
id,
title
);
System.out.println(
getTitle()
);
}
}
getTitle() meaningful result দিতে parent title আগে initialize হওয়া প্রয়োজন।
Initialization order object-কে partially initialized parent state থেকে protect করে।
super(...) Must Be the First Statement
Wrong:
public VideoLesson(
long id,
String title
) {
System.out.println(
"Creating video"
);
super(
id,
title
);
}
Compile হবে না।
Correct:
public VideoLesson(
long id,
String title
) {
super(
id,
title
);
System.out.println(
"Creating video"
);
}
Constructor chaining call সবসময় first statement হতে হয়।
Automatic super()
যদি child constructor explicit super(...) না লেখে, compiler first statement হিসেবে:
super();
add করার চেষ্টা করে।
Example:
public class ContentItem {
public ContentItem() {
}
}
public class VideoLesson
extends ContentItem {
public VideoLesson() {
}
}
Child constructor conceptually:
public VideoLesson() {
super();
}
When Automatic super() Fails
Parent class:
public class ContentItem {
public ContentItem(
long id,
String title
) {
}
}
Parent-এর no-argument constructor নেই।
Child:
public class VideoLesson
extends ContentItem {
public VideoLesson() {
}
}
Compiler automaticভাবে:
super();
call করতে চাইবে।
কিন্তু ContentItem() constructor নেই।
তাই compile error হবে।
Correct child constructor:
public VideoLesson(
long id,
String title
) {
super(
id,
title
);
}
Compiler-Provided Parent Constructor
Previous module থেকে rule:
কোনো class-এ constructor declare না করা হলে compiler একটি no-argument constructor provide করে।
Parent:
public class ContentItem {
}
Compiler conceptually provides:
public ContentItem() {
}
তাই child constructor explicit super() ছাড়া compile করতে পারে।
কিন্তু parent-এ parameterized constructor add করলে automatic no-argument constructor আর থাকে না।
Do Not Add a Weak No-Argument Constructor Just to Satisfy Inheritance
Problem solve করার জন্য কেউ parent-এ লিখতে পারে:
public ContentItem() {
}
এতে child compile করবে।
কিন্তু parent required state হারাতে পারে:
id = 0
title = null
এটি invalid object creation allow করতে পারে।
Better:
public VideoLesson(
long id,
String title
) {
super(
id,
title
);
}
Parent invariants weaken করে inheritance convenient করা উচিত নয়।
Parent Constructor Is Not Inherited
Child class parent constructor inherit করে না।
Parent:
public ContentItem(
long id,
String title
) {
}
এই কারণে automatically child-এর এমন constructor পাওয়া যাবে না:
new VideoLesson(
1L,
"Inheritance"
);
Child-কে নিজের constructor declare করতে হয়।
public VideoLesson(
long id,
String title
) {
super(
id,
title
);
}
Methods inherited হতে পারে।
Constructors inherited হয় না।
Child Constructor Can Add More Required State
Parent state:
id
title
Child state:
videoUrl
durationInMinutes
Complete constructor:
public VideoLesson(
long id,
String title,
String videoUrl,
int durationInMinutes
) {
super(
id,
title
);
if (
videoUrl == null
|| videoUrl.isBlank()
) {
throw new IllegalArgumentException(
"Video URL is required."
);
}
if (durationInMinutes <= 0) {
throw new IllegalArgumentException(
"Video duration must be positive."
);
}
this.videoUrl =
videoUrl.strip();
this.durationInMinutes =
durationInMinutes;
}
Validation ownership:
ContentItem validates:
id
title
VideoLesson validates:
videoUrl
durationInMinutes
প্রতিটি class নিজের state-এর rules own করছে।
Multiple Parent Constructors
Parent class multiple constructors expose করতে পারে।
public class ContentItem {
private final long id;
private final String title;
private final boolean published;
public ContentItem(
long id,
String title
) {
this(
id,
title,
false
);
}
public ContentItem(
long id,
String title,
boolean published
) {
this.id = id;
this.title = title;
this.published =
published;
}
}
Child matching parent constructor choose করতে পারে।
public VideoLesson(
long id,
String title
) {
super(
id,
title
);
}
অথবা:
public VideoLesson(
long id,
String title,
boolean published
) {
super(
id,
title,
published
);
}
তবে child constructor যেন parent lifecycle rule bypass না করে।
যদি content শুধু publish() method-এর মাধ্যমে publish হওয়া উচিত হয়, constructor দিয়ে arbitrary published state expose করা weak design হতে পারে।
this(...) and super(...)
Previous module-এ আমরা constructor chaining-এর জন্য this(...) শিখেছি।
this(...)
same class-এর অন্য constructor call করে।
super(...)
parent class-এর constructor call করে।
They Cannot Both Be First
A constructor-এ first statement একটিই হতে পারে।
Invalid:
public VideoLesson(
long id,
String title
) {
this(
id,
title,
"default-url",
1
);
super(
id,
title
);
}
Compile হবে না।
যদি this(...) call করেন, delegated constructor eventually super(...) call করবে।
Valid Constructor Chaining
public class VideoLesson
extends ContentItem {
private final String videoUrl;
private final int durationInMinutes;
public VideoLesson(
long id,
String title,
String videoUrl
) {
this(
id,
title,
videoUrl,
1
);
}
public VideoLesson(
long id,
String title,
String videoUrl,
int durationInMinutes
) {
super(
id,
title
);
if (
videoUrl == null
|| videoUrl.isBlank()
) {
throw new IllegalArgumentException(
"Video URL is required."
);
}
if (durationInMinutes <= 0) {
throw new IllegalArgumentException(
"Duration must be positive."
);
}
this.videoUrl =
videoUrl.strip();
this.durationInMinutes =
durationInMinutes;
}
}
Flow:
Three-argument VideoLesson constructor
→ Four-argument VideoLesson constructor
→ ContentItem constructor
Actual execution order still:
ContentItem initialization
VideoLesson initialization
Inherited Members
Child object parent-এর accessible members use করতে পারে।
Parent:
public class ContentItem {
private final String title;
public String getTitle() {
return title;
}
public boolean publish() {
return true;
}
}
Child:
public class VideoLesson
extends ContentItem {
public void printTitle() {
System.out.println(
getTitle()
);
}
}
getTitle() inherited public method।
Private Members Are Part of the Object but Not Directly Accessible
Parent:
private final String title;
Child object-এর মধ্যে title state আছে।
কিন্তু child class direct access করতে পারে না।
Invalid:
public void printTitle() {
System.out.println(
title
);
}
কারণ title parent-এর private implementation detail।
Valid:
public void printTitle() {
System.out.println(
getTitle()
);
}
Parent controlled method expose করেছে।
Private Does Not Mean “Not Inherited” in the Physical Sense
একটি common oversimplification:
Private fields are not inherited.
Better mental model:
- Child object-এর parent portion-এ private state exists
- Child class source code সেই field direct access করতে পারে না
- Parent public বা protected methods সেই state access করতে পারে
- Child inherited methods use করে state-এর সঙ্গে interact করতে পারে
Example:
videoLesson.publish();
publish() parent-এর private published field change করতে পারে।
Child method নিজে fieldটি direct access করতে পারে না।
Using Parent Queries Instead of Exposing Fields
Parent:
public boolean isPublished() {
return published;
}
Child:
public boolean canStartPlayback() {
return isPublished();
}
এতে parent state encapsulated থাকে।
Child parent-এর public contract use করছে।
The protected Modifier
protected member:
- Same package থেকে accessible
- Subclasses থেকে accessible
- Cross-package subclass access-এর কিছু specific rules আছে
Example:
protected String getContentTypeLabel() {
return "Content";
}
Child:
public class VideoLesson
extends ContentItem {
public void printType() {
System.out.println(
getContentTypeLabel()
);
}
}
Protected Fields
Technically:
public class ContentItem {
protected String title;
}
Child direct access করতে পারে।
public class VideoLesson
extends ContentItem {
public void renameInternally(
String title
) {
this.title =
title;
}
}
কিন্তু এতে encapsulation দুর্বল হয়।
Child:
- Validation bypass করতে পারে
- Parent invariant ভাঙতে পারে
- Parent implementation-এর সঙ্গে tightly coupled হয়
- Field representation change হলে break করতে পারে
Prefer Private Fields with Protected Behavior
Weak:
protected String title;
Stronger:
private String title;
protected final boolean hasValidTitle() {
return title != null
&& !title.isBlank();
}
অথবা:
protected final String getTitleForSubclass() {
return title;
}
তবে public getter already appropriate হলে separate protected getter প্রয়োজন নেই।
Best choice depend করে parent API design-এর ওপর।
Protected Methods as Extension Points
Parent intentionally child customization allow করতে পারে।
public class ContentItem {
public boolean publish() {
if (!canPublish()) {
return false;
}
return markAsPublished();
}
protected boolean canPublish() {
return true;
}
private boolean markAsPublished() {
return true;
}
}
Child:
public class VideoLesson
extends ContentItem {
@Override
protected boolean canPublish() {
return hasVideoUrl();
}
}
এখানে protected method একটি deliberate extension point।
তবে overriding এবং template behavior Lesson 3 ও Lesson 4-এ বিস্তারিত শেখানো হবে।
protected Should Be Intentional
কোনো member protected করার অর্থ:
Subclasses এই member-এর ওপর depend করতে পারে।
এটি inheritance API-এর অংশ।
Future parent refactoring harder হতে পারে।
Ask:
- Child-এর কি সত্যিই এই behavior প্রয়োজন?
- Public method যথেষ্ট কি?
- Private helper দিয়ে parent নিজেই rule enforce করতে পারে কি?
- Composition better কি?
- আমরা কি accidental subclass API তৈরি করছি?
Package-Private and Inheritance
No modifier:
boolean validateTitle() {
}
এটি package-private।
Same package-এর child access করতে পারে।
Different package-এর child direct access করতে পারে না।
Example:
io.liveklass.content.ContentItem
io.liveklass.video.VideoLesson
যদি method package-private হয়, VideoLesson access করতে পারবে না।
Package organization inheritance visibility affect করে।
Public Members
Public parent methods সব child objects-এর public API-এর অংশ হয়ে যায়।
Parent:
public boolean publish() {
}
Child object:
videoLesson.publish();
এটি inherited public operation।
এই কারণে parent public API carefully design করা জরুরি।
একটি method parent-এ public করলে সব current এবং future child types সেই contract inherit করতে পারে।
Parent API Should Be Valid for Every Child
Suppose parent:
public void download() {
}
কিন্তু LiveStreamLesson download support করে না।
Child যদি লিখতে বাধ্য হয়:
@Override
public void download() {
throw new UnsupportedOperationException();
}
তাহলে parent contract হয়তো too broad।
Better design হতে পারে:
interface Downloadable
শুধু downloadable content types implement করবে।
Interfaces Lesson 4-এ শেখানো হবে।
The final Method
Parent method final হলে child override করতে পারে না।
public final long getId() {
return id;
}
Child:
@Override
public long getId() {
return 999L;
}
Compile হবে না।
Why Make a Method Final?
A method final হতে পারে যখন:
- Parent invariant depend করে
- Behavior বদলানো unsafe
- Identity rule consistent থাকা দরকার
- Security বা lifecycle step override হওয়া উচিত নয়
- Parent algorithm stable রাখতে হয়
Example:
public final boolean isPublished() {
return published;
}
তবে every method final করলে inheritance usefulness কমে।
Only deliberate non-overridable behavior final করুন।
Final Method and Encapsulation
Suppose parent identity:
private final long id;
public final long getId() {
return id;
}
Child identity query redefine করতে পারবে না।
এতে parent contract stable থাকে।
কিন্তু getter final করা সবসময় প্রয়োজন নয়।
Design risk real হলে ব্যবহার করুন।
The final Class
A class final হলে extend করা যায় না।
public final class CourseCode {
}
Invalid:
public class SpecialCourseCode
extends CourseCode {
}
Compile হবে না।
Why Make a Class Final?
A class final হতে পারে যখন:
- Class immutable contract protect করতে হবে
- Inheritance meaningful নয়
- Security-sensitive behavior alter করা উচিত নয়
- Value object specialization invalid
- Class extension-এর জন্য designed হয়নি
- Composition preferred
Examples:
public final class CourseCode
public final class Money
Value object-এর equality এবং immutability subclass দিয়ে দুর্বল হওয়া prevent করা যায়।
Non-Final Class Is an Extension Decision
A class final না হলে technically extend করা যায়।
কিন্তু technically extendable হওয়া মানেই class inheritance-এর জন্য well-designed নয়।
Inheritance-friendly class design require করে:
- Stable protected/public contract
- Documented invariants
- Safe override points
- Constructor rules
- Equality considerations
- Substitutability
Public class automatically good base class নয়।
Engineering Note: Design for Inheritance or Prevent It
A useful principle:
A classকে inheritance-এর জন্য deliberately design করুন, অথবা inheritance prevent করার কথা বিবেচনা করুন।
Accidental inheritance risky।
Parent changes children break করতে পারে।
Child overrides parent assumptions violate করতে পারে।
Internal domain classes-এর ক্ষেত্রে:
finalclass- Interfaces
- Composition
অনেক সময় safer choice।
A Complete Example
ContentItem.java
public class ContentItem {
private final long id;
private final String title;
private boolean published;
public ContentItem(
long id,
String title
) {
if (id <= 0) {
throw new IllegalArgumentException(
"Content ID must be positive."
);
}
if (
title == null
|| title.isBlank()
) {
throw new IllegalArgumentException(
"Content title is required."
);
}
this.id = id;
this.title = title.strip();
this.published = false;
}
public final long getId() {
return id;
}
public final String getTitle() {
return title;
}
public final boolean isPublished() {
return published;
}
public boolean publish() {
if (published) {
return false;
}
if (!canPublish()) {
return false;
}
published = true;
return true;
}
protected boolean canPublish() {
return true;
}
}
VideoLesson.java
public class VideoLesson
extends ContentItem {
private final String videoUrl;
private final int durationInMinutes;
public VideoLesson(
long id,
String title,
String videoUrl
) {
this(
id,
title,
videoUrl,
1
);
}
public VideoLesson(
long id,
String title,
String videoUrl,
int durationInMinutes
) {
super(
id,
title
);
if (
videoUrl == null
|| videoUrl.isBlank()
) {
throw new IllegalArgumentException(
"Video URL is required."
);
}
if (durationInMinutes <= 0) {
throw new IllegalArgumentException(
"Video duration must be positive."
);
}
this.videoUrl =
videoUrl.strip();
this.durationInMinutes =
durationInMinutes;
}
@Override
protected boolean canPublish() {
return videoUrl.startsWith(
"https://"
);
}
public String getVideoUrl() {
return videoUrl;
}
public int getDurationInMinutes() {
return durationInMinutes;
}
}
canPublish() override এখানে শুধু preview।
Method overriding পরবর্তী lesson-এ বিস্তারিত explain করা হবে।
ArticleLesson.java
public class ArticleLesson
extends ContentItem {
private final String content;
public ArticleLesson(
long id,
String title,
String content
) {
super(
id,
title
);
if (
content == null
|| content.isBlank()
) {
throw new IllegalArgumentException(
"Article content is required."
);
}
this.content =
content.strip();
}
@Override
protected boolean canPublish() {
return content.length()
>= 20;
}
public String getContent() {
return content;
}
}
Main.java
public class Main {
public static void main(
String[] args
) {
VideoLesson video =
new VideoLesson(
1L,
"Parent Construction",
"https://cdn.liveklass.io/videos/super",
15
);
ArticleLesson article =
new ArticleLesson(
2L,
"Inherited Access",
"Private state should remain encapsulated."
);
System.out.println(
video.publish()
);
System.out.println(
article.publish()
);
System.out.println(
video.getTitle()
);
System.out.println(
article.getTitle()
);
}
}
Possible output:
true
true
Parent Construction
Inherited Access
Construction Flow of VideoLesson
Creation:
new VideoLesson(
1L,
"Parent Construction",
"https://cdn.liveklass.io/videos/super",
15
);
Flow:
1. VideoLesson four-argument constructor selected
2. super(id, title) invoked
3. ContentItem validates id
4. ContentItem validates title
5. ContentItem initializes id, title, published
6. Control returns to VideoLesson constructor
7. VideoLesson validates videoUrl
8. VideoLesson validates duration
9. VideoLesson initializes its own fields
10. Fully constructed object returned
যদি parent validation fail করে:
new VideoLesson(
-1L,
"Parent Construction",
"https://example.com/video",
15
);
Child initialization পর্যন্ত execution পৌঁছাবে না।
Object creation fail করবে।
Parent Failure Stops Child Construction
Parent:
if (id <= 0) {
throw new IllegalArgumentException(
"Content ID must be positive."
);
}
Child-specific fields তখনো assign হবে না।
Caller কোনো partially created VideoLesson পাবে না।
Constructor exception object creation prevent করে।
Avoid Calling Overridable Methods from Constructors
Dangerous parent constructor:
public ContentItem(
long id,
String title
) {
this.id = id;
this.title = title;
validateContent();
}
Suppose validateContent() child override করেছে এবং child field use করে।
@Override
protected void validateContent() {
if (videoUrl.isBlank()) {
}
}
Parent constructor execute হওয়ার সময় videoUrl এখনো initialize হয়নি।
Result:
NullPointerException
Unexpected behavior
Partially initialized state access
Practical rule:
Constructor থেকে overridable method call avoid করুন।
Constructor নিজের private বা final helper ব্যবহার করতে পারে।
Safe Constructor Helper
public ContentItem(
long id,
String title
) {
validateId(id);
validateTitle(title);
this.id = id;
this.title = title.strip();
}
private static void validateId(
long id
) {
}
private static void validateTitle(
String title
) {
}
Private এবং static helper child override করতে পারে না।
Initialization predictable থাকে।
Common Mistakes
Forgetting the Parent Constructor
public VideoLesson(
long id,
String title
) {
}
Parent no-argument constructor না থাকলে compile error।
Adding an Invalid No-Argument Parent Constructor
public ContentItem() {
}
শুধু child compilation সহজ করার জন্য required invariants weaken করা উচিত নয়।
Writing super(...) After Other Statements
super(...) first statement হতে হবে।
Trying to Access Parent Private Fields
this.title =
title;
Child থেকে parent private field access করা যায় না।
Making Fields Protected for Convenience
protected String title;
Child validation bypass করতে পারে।
Private fields এবং controlled methods prefer করুন।
Assuming Constructors Are Inherited
Parent constructor child automatically পায় না।
Using Both this(...) and super(...)
এক constructor-এ directভাবে দুটো call করা যায় না।
Calling Overridable Methods from Parent Constructor
Child state initialize হওয়ার আগে overridden method execute হতে পারে।
Making Every Method Final
Inheritance extension points হারিয়ে যেতে পারে।
Only invariant-critical behavior final করুন।
Leaving Every Class Open for Extension
Technically extendable class safe inheritance base নাও হতে পারে।
Practice Exercises
Exercise 1: Add QuizLesson
Parent:
ContentItem
Child fields:
questionCount
passingScore
Constructor:
super(id, title)call করবে- Question count positive validate করবে
- Passing score
0–100validate করবে
Exercise 2: Predict Constructor Order
Create:
ContentItem
→ VideoLesson
→ LiveVideoLesson
Each constructor একটি message print করবে।
Predict output when:
new LiveVideoLesson(...);
Exercise 3: Fix Missing Parent Constructor Call
Parent:
public ContentItem(
long id,
String title
) {
}
Child:
public VideoLesson(
String videoUrl
) {
this.videoUrl =
videoUrl;
}
Refactor child constructor so parent state validভাবে initialize হয়।
Exercise 4: Replace Protected Field
Weak parent:
protected boolean published;
Child direct mutation:
published = true;
Refactor parent to:
- Keep field private
- Expose meaningful query
- Expose controlled publication behavior
Exercise 5: Choose final
Decide whether each should be final:
- Immutable
CourseCodeclass ContentItem.getId()ContentItem.publish()- Mutable
VideoLessonclass Moneyclass
Explain each decision।
Exercise 6: this(...) and super(...)
Create two VideoLesson constructors:
VideoLesson(
long id,
String title,
String videoUrl
)
and:
VideoLesson(
long id,
String title,
String videoUrl,
int durationInMinutes
)
Shorter constructor default duration 1 দিয়ে complete constructor delegate করবে।
Exercise 7: Find the Constructor Risk
Review:
public ContentItem(
String title
) {
this.title =
title;
prepare();
}
protected void prepare() {
}
Explain why child override করলে construction unsafe হতে পারে।
Predict the Result
Question 1
public class Parent {
public Parent() {
System.out.println(
"Parent"
);
}
}
public class Child
extends Parent {
public Child() {
System.out.println(
"Child"
);
}
}
new Child();
Question 2
Parent:
public Parent(
int value
) {
}
Child:
public Child() {
}
Will it compile if parent has no no-argument constructor?
Question 3
public class Parent {
private int value;
}
Can child directভাবে লিখতে পারে?
value = 10;
Question 4
public final class CourseCode {
}
Can another class extend it?
Question 5
public final void publish() {
}
Can a child override publish()?
Predict the Result Answers
Answer 1
Parent
Child
Parent constructor first execute হয়।
Answer 2
না।
Compiler automatic super() call করতে চাইবে, কিন্তু matching parent constructor নেই।
Answer 3
না।
Fieldটি parent class-এর private member।
Answer 4
না।
Final class extend করা যায় না।
Answer 5
না।
Final method override করা যায় না।
Knowledge Check
Question 1
Child object তৈরির সময় parent constructor কেন execute হয়?
Question 2
super(...) কী করে?
Question 3
super(...) constructor body-এর কোথায় থাকতে হয়?
Question 4
Explicit super(...) না থাকলে compiler কী চেষ্টা করে?
Question 5
Parent no-argument constructor না থাকলে কী হতে পারে?
Question 6
Constructors কি inherited হয়?
Question 7
this(...) এবং super(...)-এর difference কী?
Question 8
একই constructor-এ directভাবে দুটো ব্যবহার করা যায় কি?
Question 9
Child কি parent-এর private field direct access করতে পারে?
Question 10
Parent private state child কীভাবে use করতে পারে?
Question 11
Protected field risky কেন?
Question 12
Protected method কখন useful?
Question 13
Final method কী prevent করে?
Question 14
Final class কী prevent করে?
Question 15
Constructor থেকে overridable method call risky কেন?
Knowledge Check Answers
Answer 1
Child object-এর parent portion এবং inherited state validভাবে initialize করতে।
Answer 2
Parent class-এর matching constructor call করে।
Answer 3
First statement হিসেবে।
Answer 4
Automatic super() call add করার চেষ্টা করে।
Answer 5
Explicit matching super(...) না দিলে compile error হবে।
Answer 6
না। Child নিজের constructors declare করে।
Answer 7
this(...) same class-এর অন্য constructor call করে। super(...) parent constructor call করে।
Answer 8
না। দুটোই first statement হতে চায়।
Answer 9
না।
Answer 10
Parent-এর public বা protected methods ব্যবহার করে।
Answer 11
Child direct mutation করে parent invariants bypass করতে পারে এবং implementation coupling বাড়ে।
Answer 12
Parent deliberately subclass customization বা internal collaboration allow করলে।
Answer 13
Child method overriding।
Answer 14
Class inheritance বা subclass creation।
Answer 15
Parent constructor চলার সময় child fields এখনো initialize নাও হতে পারে।
Lesson Summary
এই lesson-এ আমরা শিখেছি:
- Child object-এর মধ্যে parent state এবং child state থাকে
- Parent portion child-এর আগে initialize হয়
super(...)parent constructor call করে- Parent constructor validation child classes reuse করে
super(...)first statement হতে হয়- Explicit call না থাকলে compiler
super()add করার চেষ্টা করে - Parent no-argument constructor না থাকলে explicit matching call প্রয়োজন
- Constructors inherited হয় না
- Child constructor additional required state initialize করতে পারে
this(...)same-class constructor chaining করেsuper(...)parent construction initiate করে- One constructor directভাবে দুটো call করতে পারে না
- Parent private state child object-এর অংশ, কিন্তু child class direct access করতে পারে না
- Public এবং protected methods inherited access provide করতে পারে
- Protected fields encapsulation এবং invariants দুর্বল করতে পারে
- Private fields with controlled behavior generally safer
- Protected methods intentional extension points হতে পারে
- Public parent methods সব child types-এর contract-এর অংশ
finalmethod overriding prevent করেfinalclass inheritance prevent করে- Every class automatically safe inheritance base নয়
- Constructor থেকে overridable method call unsafe initialization তৈরি করতে পারে
- Parent এবং child প্রত্যেকে নিজের state validation-এর দায়িত্ব নেয়
Next Lesson
পরবর্তী lesson:
Method Overriding and Runtime Polymorphism
আমরা শিখব:
- Method overriding
@Override- Parent reference এবং child object
- Runtime method dispatch
super.method()- Overloading বনাম overriding
- Static method hiding
- Fields কেন polymorphic নয়
- Parent contract preserve করা