Inheritance, Interfaces, and Polymorphism
Abstract Classes and Interfaces
আপনি একটি free preview lesson দেখছেন।
Lesson Overview
আগের lesson-এ ContentItem class-এ একটি default implementation রেখেছিলাম:
public int calculateEstimatedMinutes() {
return 0;
}
এই implementation compile করে, কিন্তু domain perspective-এ দুর্বল।
একটি content item-এর estimated duration যদি সবসময় content type অনুযায়ী calculate করতে হয়, তাহলে generic parent-এর 0 return করা meaningful নয়।
আরও বড় সমস্যা হলো child class methodটি override করতে ভুলে যেতে পারে।
public class InteractiveLesson
extends ContentItem {
}
এখন:
interactiveLesson
.calculateEstimatedMinutes();
return করবে:
0
যদিও zero-minute lesson business perspective-এ invalid হতে পারে।
এমন situation-এ parent class বলতে পারে:
সব concrete child class-কে এই behavior implement করতেই হবে।
এর জন্য Java-তে abstract method এবং abstract class রয়েছে।
অন্যদিকে কিছু behavior shared state-এর অংশ নয়; এটি একটি capability বা contract।
Examples:
Publishable
Downloadable
Gradable
Completable
একটি class multiple capabilities support করতে পারে।
এর জন্য Java interface ব্যবহার করে।
এই lesson-এ আমরা শিখব:
- Abstract class কী
- Abstract method
- Concrete behavior এবং shared state
- Abstract constructor
- Interface কী
implements- Multiple interfaces
- Interface references
defaultএবংstaticmethods- Abstract class এবং interface-এর পার্থক্য
- Shared identity বনাম shared capability
- কখন কোন abstraction ব্যবহার করা উচিত
- Unnecessary inheritance এবং interface explosion avoid করা
Learning Objectives
এই lesson শেষ করার পর আপনি পারবেন:
- Abstract class declare করতে
- Abstract method তৈরি করতে
- Concrete subclass-কে required behavior implement করতে বাধ্য করতে
- Abstract class-এর constructor এবং shared state ব্যবহার করতে
- Interface define এবং implement করতে
- Interface type reference ব্যবহার করতে
- একটি class-এ multiple interfaces implement করতে
- Abstract class এবং interface-এর মধ্যে appropriate choice করতে
- Capability-based interface design করতে
- Overly broad এবং unnecessary interfaces identify করতে
The Problem with Meaningless Default Behavior
Parent:
public class ContentItem {
public int calculateEstimatedMinutes() {
return 0;
}
}
Child override করতে পারে:
@Override
public int calculateEstimatedMinutes() {
return durationInMinutes;
}
কিন্তু override বাধ্যতামূলক নয়।
public class AudioLesson
extends ContentItem {
}
এখন inherited 0 silently ব্যবহার হবে।
Meaningless default implementation-এর পরিবর্তে আমরা methodটি abstract করতে পারি।
What Is an Abstract Method?
Abstract method শুধু contract declare করে।
এটির method body থাকে না।
public abstract int calculateEstimatedMinutes();
Notice:
abstractkeyword আছে- Method body নেই
- শেষে semicolon আছে
Wrong:
public abstract int calculateEstimatedMinutes() {
return 0;
}
Abstract method-এর implementation থাকে না।
What Is an Abstract Class?
যে class abstract keyword দিয়ে declare করা হয়, সেটি abstract class।
public abstract class ContentItem {
}
Abstract class:
- Shared state রাখতে পারে
- Constructor রাখতে পারে
- Concrete methods রাখতে পারে
- Abstract methods রাখতে পারে
- Directly instantiate করা যায় না
- Child classes-এর common foundation হতে পারে
Declaring an Abstract Parent
public abstract class ContentItem {
private final long id;
private final String title;
private boolean published;
protected 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 abstract int calculateEstimatedMinutes();
public abstract String getContentType();
public boolean publish() {
if (published) {
return false;
}
published = true;
return true;
}
public final long getId() {
return id;
}
public final String getTitle() {
return title;
}
public final boolean isPublished() {
return published;
}
}
এখানে:
calculateEstimatedMinutes()
getContentType()
abstract।
কিন্তু:
publish()
getId()
getTitle()
isPublished()
concrete methods।
Abstract Class Cannot Be Instantiated
Invalid:
ContentItem content =
new ContentItem(
1L,
"General Content"
);
Compile হবে না।
কারণ ContentItem incomplete abstraction।
এটি জানে না:
Content type কী?
Duration কীভাবে calculate হবে?
Concrete child object তৈরি করতে হবে।
ContentItem content =
new VideoLesson(
1L,
"Abstract Classes",
"https://cdn.liveklass.io/video/1",
18
);
Why Prevent Direct Instantiation?
যদি generic ContentItem domain-এ meaningful না হয়, direct creation prevent করা উচিত।
Valid content types:
VideoLesson
ArticleLesson
QuizLesson
Abstract parent নিশ্চিত করে:
- Generic incomplete object তৈরি হবে না
- Required specialized behavior implement হবে
- Common state centralize থাকবে
- Parent type polymorphically ব্যবহার করা যাবে
Abstract Class Can Have a Constructor
Abstract class instantiate করা যায় না, কিন্তু constructor থাকতে পারে।
protected ContentItem(
long id,
String title
) {
this.id = id;
this.title = title;
}
Child constructor parent constructor call করবে।
public VideoLesson(
long id,
String title,
String videoUrl,
int durationInMinutes
) {
super(
id,
title
);
this.videoUrl =
videoUrl;
this.durationInMinutes =
durationInMinutes;
}
Abstract constructor shared parent state initialize করে।
Why Is the Constructor protected?
protected ContentItem(...)
ContentItem direct instantiate করা যায় না।
Constructor মূলত subclasses-এর জন্য।
protected intent প্রকাশ করে:
This constructor supports subclass construction.
A public constructorও technically possible, কিন্তু abstract class-এর ক্ষেত্রে caller direct instantiate করতে পারে না।
protected অনেক সময় clearer।
Concrete Child Must Implement Abstract Methods
Parent:
public abstract int calculateEstimatedMinutes();
Concrete child:
public class VideoLesson
extends ContentItem {
private final int durationInMinutes;
@Override
public int calculateEstimatedMinutes() {
return durationInMinutes;
}
@Override
public String getContentType() {
return "VIDEO";
}
}
Concrete child required abstract methods implement না করলে compile error হবে।
An Abstract Child May Defer Implementation
public abstract class MediaLesson
extends ContentItem {
protected MediaLesson(
long id,
String title
) {
super(
id,
title
);
}
}
MediaLesson নিজেও abstract হলে parent abstract methods implement না করেও থাকতে পারে।
Later concrete child implementation দেবে।
public class VideoLesson
extends MediaLesson {
@Override
public int calculateEstimatedMinutes() {
return durationInMinutes;
}
@Override
public String getContentType() {
return "VIDEO";
}
}
তবে hierarchy unnecessary deep করা উচিত নয়।
Abstract and Concrete Methods Together
Abstract class-এর শক্তি হলো shared implementation এবং required specialization একসঙ্গে রাখা।
Shared:
public boolean publish() {
if (published) {
return false;
}
published = true;
return true;
}
Specialized:
public abstract int calculateEstimatedMinutes();
এতে parent বলতে পারে:
Publication lifecycle সবার জন্য same
Duration calculation type-specific
Template Behavior
Parent একটি complete algorithm define করতে পারে, কিন্তু একটি specific step child-এর কাছে delegate করতে পারে।
public final boolean publish() {
if (published) {
return false;
}
if (!isReadyForPublication()) {
return false;
}
published = true;
return true;
}
protected abstract boolean isReadyForPublication();
Child:
@Override
protected boolean isReadyForPublication() {
return videoUrl.startsWith(
"https://"
);
}
Parent publication flow control করছে।
Child শুধু readiness rule provide করছে।
এটিকে template-style behavior বলা যায়।
Why Make the Template Method final?
public final boolean publish()
Child পুরো publication algorithm override করতে পারবে না।
এটি parent invariant protect করে।
Child শুধু allowed extension point implement করে:
isReadyForPublication()
এতে parent control এবং child customization balanced থাকে।
Complete Abstract ContentItem
public abstract class ContentItem {
private final long id;
private final String title;
private boolean published;
protected 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 abstract int calculateEstimatedMinutes();
public abstract String getContentType();
protected abstract boolean isReadyForPublication();
public final boolean publish() {
if (published) {
return false;
}
if (!isReadyForPublication()) {
return false;
}
published = true;
return true;
}
public final long getId() {
return id;
}
public final String getTitle() {
return title;
}
public final boolean isPublished() {
return published;
}
@Override
public String toString() {
return "ContentItem{"
+ "id="
+ id
+ ", title='"
+ title
+ '\''
+ ", type="
+ getContentType()
+ ", estimatedMinutes="
+ calculateEstimatedMinutes()
+ ", published="
+ published
+ '}';
}
}
What Is an Interface?
Interface একটি behavioral contract define করে।
public interface Downloadable {
String getDownloadUrl();
}
Interface বলে:
যে class এই interface implement করবে, তাকে download URL provide করতে হবে।
Interface সাধারণত shared object state own করে না।
এটি capability express করে।
Implementing an Interface
public class VideoLesson
extends ContentItem
implements Downloadable {
private final String videoUrl;
@Override
public String getDownloadUrl() {
return videoUrl;
}
}
implements keyword interface contract accept করে।
Interface Methods Are Public Contracts
Interface method:
String getDownloadUrl();
Conceptually এটি:
public abstract String getDownloadUrl();
Implementation অবশ্যই public হতে হবে।
Wrong:
@Override
protected String getDownloadUrl() {
return videoUrl;
}
Compile হবে না।
Correct:
@Override
public String getDownloadUrl() {
return videoUrl;
}
Interface as a Capability
Consider:
public interface Downloadable {
String getDownloadUrl();
}
Only relevant classes implement করবে।
VideoLesson
implements Downloadable
ArticleLesson
implements Downloadable
কিন্তু live stream content download support না করলে implement করবে না।
LiveVideoLesson
এভাবে unsupported method parent class-এ force করতে হয় না।
Multiple Interfaces
Java class শুধু একটি class extend করতে পারে।
কিন্তু multiple interfaces implement করতে পারে।
public class QuizLesson
extends ContentItem
implements Gradable,
Completable {
}
Syntax:
implements FirstInterface,
SecondInterface
এতে class multiple behavioral contracts support করতে পারে।
A Gradable Interface
public interface Gradable {
int calculateScore(
int correctAnswers
);
boolean hasPassed(
int correctAnswers
);
}
Implementation:
public class QuizLesson
extends ContentItem
implements Gradable {
private final int questionCount;
private final int passingScore;
@Override
public int calculateScore(
int correctAnswers
) {
if (
correctAnswers < 0
|| correctAnswers > questionCount
) {
throw new IllegalArgumentException(
"Correct answer count is invalid."
);
}
return correctAnswers
* 100
/ questionCount;
}
@Override
public boolean hasPassed(
int correctAnswers
) {
return calculateScore(
correctAnswers
) >= passingScore;
}
}
Interface Reference
Interface type reference implementing object hold করতে পারে।
Gradable assessment =
new QuizLesson(
1L,
"Java Quiz",
10,
70
);
Caller interface contract use করতে পারে।
int score =
assessment.calculateScore(
8
);
boolean passed =
assessment.hasPassed(
8
);
Caller quiz-এর title, publication state বা internal fields জানে না।
সে শুধু grading capability-এর ওপর depend করছে।
Interface-Based Polymorphism
একাধিক unrelated classes same interface implement করতে পারে।
public class QuizLesson
implements Gradable {
}
public class Assignment
implements Gradable {
}
Common parent class প্রয়োজন নেই।
Method:
public static void printResult(
Gradable gradable,
int correctAnswers
) {
System.out.println(
gradable.calculateScore(
correctAnswers
)
);
}
এটি different implementations accept করতে পারে।
Abstract Class vs Interface: Core Difference
Abstract class সাধারণত shared identity, state এবং implementation-এর foundation।
Interface সাধারণত shared behavior বা capability contract।
Example:
VideoLesson is a ContentItem
VideoLesson is Downloadable
QuizLesson is Gradable
Here:
ContentItem → Common type hierarchy
Downloadable → Capability
Gradable → Capability
Abstract Class Can Store Instance State
public abstract class ContentItem {
private final long id;
private final String title;
private boolean published;
}
Each object-এর own state থাকে।
Interface সাধারণত instance fields রাখে না।
Interface Fields Are Constants
Interface-এ field declare করলে এটি implicitly:
public static final
Example:
public interface Downloadable {
int MAX_DOWNLOAD_ATTEMPTS = 3;
}
Conceptually:
public static final int MAX_DOWNLOAD_ATTEMPTS =
3;
Per-object state নয়।
Interface-এ mutable instance state রাখা যায় না।
Avoid Using Interfaces as Constant Containers
Weak:
public interface AppConstants {
String PLATFORM_NAME =
"LiveKlass";
int MAX_TITLE_LENGTH =
150;
}
এটি behavioral contract নয়।
Focused constants appropriate class-এর কাছে রাখা better।
Course.MAX_TITLE_LENGTH
অথবা dedicated configuration class।
Interface Can Have Default Methods
Modern Java interface concrete default method রাখতে পারে।
public interface Downloadable {
String getDownloadUrl();
default boolean hasDownloadAvailable() {
String url =
getDownloadUrl();
return url != null
&& !url.isBlank();
}
}
Implementing classes methodটি inherit করবে।
Why Use a Default Method?
Default method useful হতে পারে যখন:
- Contract-এর ওপর based common behavior আছে
- Existing implementations break না করে interface evolve করতে হয়
- Behavior simple এবং natural
- Shared instance fields প্রয়োজন নেই
Example:
default boolean hasDownloadAvailable()
শুধু interface method getDownloadUrl() ব্যবহার করে।
Default Method Can Be Overridden
@Override
public boolean hasDownloadAvailable() {
return isPublished()
&& Downloadable
.super
.hasDownloadAvailable();
}
InterfaceName.super.method() দিয়ে default implementation call করা যায়।
এটি advanced syntax হলেও conceptually parent method-এর super.method()-এর মতো।
Interface Static Methods
Interface static methodও রাখতে পারে।
public interface Downloadable {
static boolean isSecureUrl(
String url
) {
return url != null
&& url.startsWith(
"https://"
);
}
}
Call:
Downloadable.isSecureUrl(
videoUrl
);
Static interface method implementing object-এর instance method নয়।
Private Interface Methods
Modern Java interface private helper method রাখতে পারে।
private static boolean isPresent(
String value
) {
return value != null
&& !value.isBlank();
}
এগুলো default বা static methods-এর duplication reduce করতে পারে।
Beginner code-এ simple interface prefer করুন।
Multiple Default Method Conflict
Suppose:
public interface Publishable {
default String getStatus() {
return "PUBLISHABLE";
}
}
public interface Downloadable {
default String getStatus() {
return "DOWNLOADABLE";
}
}
Class implements both:
public class VideoLesson
implements Publishable,
Downloadable {
}
Compiler বুঝবে না কোন default method use করবে।
Classকে override করতে হবে।
@Override
public String getStatus() {
return "VIDEO";
}
Java ambiguity silently resolve করে না।
Interface Inheritance
একটি interface অন্য interface extend করতে পারে।
public interface ScoredAssessment
extends Gradable,
Completable {
}
Interface multiple interfaces extend করতে পারে।
Class inheritance-এর single-parent restriction এখানে apply করে না।
Interface Does Not Mean No Implementation
Old oversimplification:
Interfaces contain only abstract methods.
Modern Java-তে interface রাখতে পারে:
- Abstract methods
defaultmethodsstaticmethods- Private helper methods
- Constants
তবুও interface-এর central purpose behavioral contract।
Abstract Class Can Implement an Interface
public abstract class ContentItem
implements Publishable {
}
Abstract class interface method immediately implement না করেও abstract থাকতে পারে।
Later concrete child implementation দিতে পারে।
অথবা abstract parent common implementation দিতে পারে।
@Override
public final boolean publish() {
// Shared implementation
}
A Publishable Interface
public interface Publishable {
boolean publish();
boolean isPublished();
}
Abstract parent:
public abstract class ContentItem
implements Publishable {
private boolean published;
@Override
public final boolean publish() {
if (published) {
return false;
}
if (!isReadyForPublication()) {
return false;
}
published = true;
return true;
}
@Override
public final boolean isPublished() {
return published;
}
protected abstract boolean isReadyForPublication();
}
এখানে:
- Interface external capability declare করেছে
- Abstract class shared implementation দিয়েছে
- Child readiness behavior customize করছে
When to Use an Abstract Class
Abstract class consider করুন যখন:
1. Types Share a Meaningful Base Identity
VideoLesson is a ContentItem
ArticleLesson is a ContentItem
2. Shared Instance State Exists
id
title
published
3. Shared Construction Rules Exist
ID validation
Title validation
Initial publication state
4. Shared Concrete Behavior Exists
publish()
getTitle()
isPublished()
5. Controlled Extension Points Are Needed
protected abstract boolean isReadyForPublication();
When to Use an Interface
Interface consider করুন যখন:
1. A Capability Must Be Expressed
Downloadable
Gradable
Completable
Searchable
2. Unrelated Classes Can Support the Behavior
QuizLesson and Assignment are Gradable
3. Multiple Contracts Are Needed
implements Gradable,
Completable,
Publishable
4. Caller Should Depend on Behavior, Not Concrete Type
void grade(
Gradable assessment
)
5. External Implementation Must Be Replaceable
NotificationSender
PaymentGateway
ContentStorage
Dependency design Lesson 6-এ বিস্তারিত শেখানো হবে।
Abstract Class vs Interface Table
| Abstract Class | Interface |
|---|---|
extends দিয়ে use হয় | implements দিয়ে use হয় |
| একটি class শুধু একটি class extend করতে পারে | Multiple interfaces implement করা যায় |
| Instance fields রাখতে পারে | Instance fields রাখতে পারে না |
| Constructor থাকতে পারে | Constructor থাকে না |
| Abstract এবং concrete methods রাখতে পারে | Abstract, default, static methods রাখতে পারে |
| Shared state এবং base identity-এর জন্য useful | Capability এবং contract-এর জন্য useful |
| Protected members থাকতে পারে | Methods generally public contract |
| Stronger structural relationship | Flexible behavioral relationship |
Use Both When Appropriate
A class একই সঙ্গে:
- একটি abstract parent extend করতে পারে
- Multiple interfaces implement করতে পারে
public class VideoLesson
extends ContentItem
implements Downloadable,
Completable {
}
Meaning:
VideoLesson is a ContentItem
VideoLesson is Downloadable
VideoLesson is Completable
Capability Interface Naming
Interfacesকে meaningful capability হিসেবে name করা যায়।
Common patterns:
Downloadable
Gradable
Publishable
Completable
NotificationSender
ContentRenderer
PaymentGateway
Avoid vague names:
Helper
Manager
Processor
Common
GenericService
Interface name callerকে contract-এর purpose জানানো উচিত।
Avoid Interface Explosion
Weak design:
HasId
HasTitle
CanPublish
CanCalculateDuration
CanShowTitle
CanReturnType
প্রতিটি one-method behavior-এর জন্য interface তৈরি করা codebase fragmented করতে পারে।
Tiny interface useful হতে পারে, কিন্তু শুধু তখনই যখন:
- Real substitutable implementations আছে
- Caller independently capabilityটি use করে
- Boundary meaningful
- Interface future dependency reduce করে
Do Not Create an Interface for Every Class
Unnecessary:
public interface CourseServiceInterface {
}
public class CourseService
implements CourseServiceInterface {
}
যদি:
- শুধু একটি implementation
- No replacement need
- No external boundary
- No testing advantage
- Contract meaningless
তাহলে interface extra abstraction হতে পারে।
Interface Before Implementation Is Not Always Better
“Program to interfaces” মানে every concrete class-এর আগে interface বানানো নয়।
Better meaning:
যেখানে callers interchangeable behavior থেকে benefit পায়, সেখানে concrete implementation-এর পরিবর্তে stable contract-এর ওপর depend করুন।
Abstraction real need থেকে আসা উচিত।
Avoid Abstract Classes Used Only as Utility Containers
Weak:
public abstract class StringUtils {
public static String normalize(
String value
) {
return value.strip();
}
}
Class abstract করে instantiation prevent করা technically possible।
কিন্তু utility class হলে clearer:
public final class StringUtils {
private StringUtils() {
}
}
Abstract class inheritance design-এর জন্য, utility container হিসেবে নয়।
Avoid Empty Abstract Parents
public abstract class BaseEntity {
}
If it provides:
- No meaningful contract
- No shared behavior
- No shared invariant
- No useful polymorphic role
তাহলে hierarchy unnecessary হতে পারে।
Common base class শুধু naming consistency-এর জন্য তৈরি করা উচিত নয়।
Marker Interfaces
Empty interface:
public interface PremiumContent {
}
এটি marker interface।
কোনো method নেই; শুধু type marker হিসেবে কাজ করে।
Java ecosystem-এ historical examples আছে:
Serializable
Cloneable
কিন্তু modern application design-এ marker interface often avoid করা যায়।
Alternatives:
- Annotation
- Explicit property
- Capability method
- Separate policy
Empty interface real polymorphic contract না দিলে value সীমিত।
A Complete Combined Example
Publishable.java
public interface Publishable {
boolean publish();
boolean isPublished();
}
Downloadable.java
public interface Downloadable {
String getDownloadUrl();
default boolean hasDownloadAvailable() {
String url =
getDownloadUrl();
return url != null
&& !url.isBlank();
}
}
Gradable.java
public interface Gradable {
int calculateScore(
int correctAnswers
);
boolean hasPassed(
int correctAnswers
);
}
ContentItem.java
public abstract class ContentItem
implements Publishable {
private final long id;
private final String title;
private boolean published;
protected 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 abstract int calculateEstimatedMinutes();
public abstract String getContentType();
protected abstract boolean isReadyForPublication();
@Override
public final boolean publish() {
if (published) {
return false;
}
if (!isReadyForPublication()) {
return false;
}
published = true;
return true;
}
@Override
public final boolean isPublished() {
return published;
}
public final long getId() {
return id;
}
public final String getTitle() {
return title;
}
}
VideoLesson.java
public final class VideoLesson
extends ContentItem
implements Downloadable {
private final String videoUrl;
private final int durationInMinutes;
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
public int calculateEstimatedMinutes() {
return durationInMinutes;
}
@Override
public String getContentType() {
return "VIDEO";
}
@Override
protected boolean isReadyForPublication() {
return Downloadable.isSecureUrl(
videoUrl
);
}
@Override
public String getDownloadUrl() {
return videoUrl;
}
}
The previous interface needs the static method:
public interface Downloadable {
String getDownloadUrl();
default boolean hasDownloadAvailable() {
String url =
getDownloadUrl();
return url != null
&& !url.isBlank();
}
static boolean isSecureUrl(
String url
) {
return url != null
&& url.startsWith(
"https://"
);
}
}
ArticleLesson.java
public final class ArticleLesson
extends ContentItem
implements Downloadable {
private static final int WORDS_PER_MINUTE =
200;
private final String content;
private final String downloadUrl;
public ArticleLesson(
long id,
String title,
String content,
String downloadUrl
) {
super(
id,
title
);
if (
content == null
|| content.isBlank()
) {
throw new IllegalArgumentException(
"Article content is required."
);
}
this.content =
content.strip();
this.downloadUrl =
downloadUrl == null
? ""
: downloadUrl.strip();
}
@Override
public int calculateEstimatedMinutes() {
int wordCount =
content.split(
"\\s+"
).length;
return Math.max(
1,
wordCount
/ WORDS_PER_MINUTE
);
}
@Override
public String getContentType() {
return "ARTICLE";
}
@Override
protected boolean isReadyForPublication() {
return content.length()
>= 20;
}
@Override
public String getDownloadUrl() {
return downloadUrl;
}
}
QuizLesson.java
public final class QuizLesson
extends ContentItem
implements Gradable {
private static final int MINUTES_PER_QUESTION =
2;
private final int questionCount;
private final int passingScore;
public QuizLesson(
long id,
String title,
int questionCount,
int passingScore
) {
super(
id,
title
);
if (questionCount <= 0) {
throw new IllegalArgumentException(
"Question count must be positive."
);
}
if (
passingScore < 0
|| passingScore > 100
) {
throw new IllegalArgumentException(
"Passing score must be between 0 and 100."
);
}
this.questionCount =
questionCount;
this.passingScore =
passingScore;
}
@Override
public int calculateEstimatedMinutes() {
return questionCount
* MINUTES_PER_QUESTION;
}
@Override
public String getContentType() {
return "QUIZ";
}
@Override
protected boolean isReadyForPublication() {
return questionCount > 0;
}
@Override
public int calculateScore(
int correctAnswers
) {
if (
correctAnswers < 0
|| correctAnswers > questionCount
) {
throw new IllegalArgumentException(
"Correct answer count is invalid."
);
}
return correctAnswers
* 100
/ questionCount;
}
@Override
public boolean hasPassed(
int correctAnswers
) {
return calculateScore(
correctAnswers
) >= passingScore;
}
}
Main.java
public class Main {
public static void main(
String[] args
) {
ContentItem video =
new VideoLesson(
1L,
"Abstract Classes",
"https://cdn.liveklass.io/video/abstract",
18
);
ContentItem article =
new ArticleLesson(
2L,
"Interfaces",
"Interfaces define behavioral contracts for Java classes.",
"https://cdn.liveklass.io/articles/interfaces.pdf"
);
QuizLesson quiz =
new QuizLesson(
3L,
"Abstraction Assessment",
10,
70
);
video.publish();
article.publish();
quiz.publish();
printContent(
video
);
printContent(
article
);
printContent(
quiz
);
printDownload(
(Downloadable) video
);
printDownload(
(Downloadable) article
);
printGrade(
quiz,
8
);
}
private static void printContent(
ContentItem content
) {
System.out.println(
content.getContentType()
+ ": "
+ content.getTitle()
);
System.out.println(
"Estimated minutes: "
+ content
.calculateEstimatedMinutes()
);
System.out.println(
"Published: "
+ content.isPublished()
);
System.out.println();
}
private static void printDownload(
Downloadable downloadable
) {
System.out.println(
"Download available: "
+ downloadable
.hasDownloadAvailable()
);
System.out.println(
"Download URL: "
+ downloadable
.getDownloadUrl()
);
System.out.println();
}
private static void printGrade(
Gradable gradable,
int correctAnswers
) {
System.out.println(
"Score: "
+ gradable.calculateScore(
correctAnswers
)
);
System.out.println(
"Passed: "
+ gradable.hasPassed(
correctAnswers
)
);
}
}
Possible output:
VIDEO: Abstract Classes
Estimated minutes: 18
Published: true
ARTICLE: Interfaces
Estimated minutes: 1
Published: true
QUIZ: Abstraction Assessment
Estimated minutes: 20
Published: true
Download available: true
Download URL: https://cdn.liveklass.io/video/abstract
Download available: true
Download URL: https://cdn.liveklass.io/articles/interfaces.pdf
Score: 80
Passed: true
Avoid Unnecessary Casting in Real Design
Previous Main used:
printDownload(
(Downloadable) video
);
কারণ variable compile-time type ছিল:
ContentItem
Better design যখন downloadable behavior প্রয়োজন, তখন reference শুরু থেকেই interface type হতে পারে।
Downloadable downloadableVideo =
new VideoLesson(...);
অথবা method call-এর আগে concrete variable রাখা যায়।
VideoLesson video =
new VideoLesson(...);
printContent(video);
printDownload(video);
Repeated casting avoid করা ভালো।
Polymorphic methods এবং collections পরবর্তী lesson-এ বিস্তারিত শেখানো হবে।
Design Decision: Abstract Parent or Interface Only?
Could we remove ContentItem and use interfaces only?
Possible:
public interface ContentItem {
long getId();
String getTitle();
int calculateEstimatedMinutes();
}
Then each class independently state store করবে।
This may be appropriate if:
- Shared state নেই
- Shared constructor rules নেই
- Implementations unrelated
- Multiple class inheritance freedom প্রয়োজন
But current domain-এ:
id
title
published
publication lifecycle
সত্যিকার অর্থে shared।
তাই abstract class reasonable।
Design Decision: Abstract Class Only?
Could Downloadable be parent method?
public abstract String getDownloadUrl();
Then every content type download support করতে বাধ্য হবে।
Quiz lesson যদি downloadable না হয়, hierarchy invalid contract impose করবে।
Capability interface better।
Engineering Note: Abstraction Has a Cost
Each abstract class বা interface introduces:
- New concept
- New name
- New dependency
- More files
- More navigation
- More contracts to understand
- Potential compatibility obligations
Use abstraction when it removes meaningful coupling or expresses a real model।
Do not create abstractions only because:
“Enterprise code should have interfaces.”
Common Mistakes
Giving an Abstract Method a Body
public abstract int calculate() {
return 0;
}
Invalid।
Instantiating an Abstract Class
new ContentItem(...)
Invalid।
Forgetting to Implement Abstract Methods
Concrete child compile করবে না।
Making an Interface Implementation Non-Public
Interface methods public contract।
Implementation visibility reduce করা যায় না।
Using an Abstract Class Only for Constants
Abstract class inheritance model-এর জন্য।
Creating an Interface for Every Concrete Class
Real substitutability না থাকলে unnecessary abstraction।
Putting Shared Mutable State in an Interface
Interface instance state own করে না।
Forcing Every Child to Support Every Capability
Download capability separate interface হওয়া উচিত যদি সব content downloadable না হয়।
Using Marker Interfaces Without a Real Need
Empty type markers often annotation বা explicit property দিয়ে clearer হতে পারে।
Overusing Default Methods
Interface gradually shared implementation-heavy abstract class-এর substitute হয়ে যেতে পারে।
Default methods small contract-related behavior-এর জন্য রাখুন।
Creating Deep Abstract Hierarchies
ContentItem
→ MediaContent
→ DownloadableMedia
→ TimedMedia
→ VideoLesson
প্রতিটি layer justified না হলে complexity বাড়ে।
Practice Exercises
Exercise 1: Make ContentItem Abstract
Existing concrete parentকে abstract করুন।
Add:
public abstract int calculateEstimatedMinutes();
public abstract String getContentType();
Verify করুন direct instantiation compile করে না।
Exercise 2: Create Completable
Define:
public interface Completable {
boolean complete();
boolean isCompleted();
}
Decide which content types should implement it।
Explain whether completion state content object-এর নাকি learner progress object-এর responsibility।
Exercise 3: Create Downloadable
Implement in:
VideoLesson
ArticleLesson
Do not implement in QuizLesson unless domain requirement supports it।
Exercise 4: Abstract or Interface?
Choose an appropriate abstraction:
- All lesson types share ID, title, publication state
- Some content can be downloaded
- Quiz and assignment can be graded
- Email and SMS can send notifications
- All prices have amount and currency
Possible choices:
Abstract class
Interface
Immutable value object
Explain each।
Exercise 5: Find the Broad Contract
Review:
public abstract class ContentItem {
public abstract void download();
public abstract int calculateScore();
}
Explain why this parent contract is too broad।
Refactor with capability interfaces।
Exercise 6: Default Method
Add to Downloadable:
default boolean hasDownloadAvailable()
Use getDownloadUrl() to calculate the result।
Exercise 7: Prevent Invalid Publication Flow
Create abstract:
protected abstract boolean isReadyForPublication();
Keep parent:
public final boolean publish()
Implement different readiness rules in video and article lessons।
Predict the Result
Question 1
public abstract class ContentItem {
public abstract int calculate();
}
Can this compile?
new ContentItem();
Question 2
public class VideoLesson
extends ContentItem {
}
Will it compile if VideoLesson is concrete and does not implement calculate()?
Question 3
public interface Downloadable {
String getDownloadUrl();
}
Can implementation be:
protected String getDownloadUrl() {
return url;
}
Question 4
Can a class extend one abstract class and implement two interfaces?
Question 5
Can an abstract class contain a fully implemented method?
Question 6
Can an interface contain a default method with a body?
Predict the Result Answers
Answer 1
না।
Abstract class directly instantiate করা যায় না।
Answer 2
না।
Concrete child required abstract method implement করতে হবে।
Answer 3
না।
Interface method public contract। Implementation public হতে হবে।
Answer 4
হ্যাঁ।
class QuizLesson
extends ContentItem
implements Gradable,
Completable
Answer 5
হ্যাঁ।
Abstract class concrete এবং abstract methods দুটোই রাখতে পারে।
Answer 6
হ্যাঁ।
Modern Java interface default method support করে।
Knowledge Check
Question 1
Abstract class কী?
Question 2
Abstract method কী?
Question 3
Abstract class instantiate করা যায় না কেন?
Question 4
Abstract class constructor রাখতে পারে কি?
Question 5
Concrete child abstract method implement না করলে কী হয়?
Question 6
Interface কী represent করে?
Question 7
implements কী করে?
Question 8
একটি class কয়টি interfaces implement করতে পারে?
Question 9
Interface method implementation public হতে হয় কেন?
Question 10
Abstract class এবং interface-এর main difference কী?
Question 11
Interface field কী ধরনের member হয়?
Question 12
Default method কী?
Question 13
Abstract class এবং interface একসঙ্গে ব্যবহার করা যায় কি?
Question 14
Every class-এর interface প্রয়োজন কি?
Question 15
Capability interface কখন useful?
Knowledge Check Answers
Answer 1
একটি incomplete base class, যা shared state ও behavior রাখতে পারে এবং direct instantiate করা যায় না।
Answer 2
Implementation ছাড়া declared method, যা concrete childকে implement করতে হয়।
Answer 3
Classটি complete concrete object contract provide করে না।
Answer 4
হ্যাঁ। Constructor child object-এর parent state initialize করে।
Answer 5
Compile error হয়, unless child classও abstract হয়।
Answer 6
একটি behavioral contract বা capability।
Answer 7
Classকে interface contract গ্রহণ এবং implement করতে বলে।
Answer 8
Multiple।
Answer 9
Interface method external public contract হিসেবে defined।
Answer 10
Abstract class shared state, constructor এবং base implementation রাখতে পারে। Interface flexible capability contract define করে এবং multiple implement করা যায়।
Answer 11
Implicitly public static final constant।
Answer 12
Interface-এর concrete method, যা implementations inherit বা override করতে পারে।
Answer 13
হ্যাঁ।
Answer 14
না। Real substitutability বা boundary না থাকলে interface unnecessary হতে পারে।
Answer 15
যখন কিছু types একটি behavior support করে কিন্তু same base class share করা প্রয়োজন নেই।
Lesson Summary
এই lesson-এ আমরা শিখেছি:
- Meaningless parent default behavior invalid state hide করতে পারে
- Abstract method required specialization enforce করে
- Abstract class direct instantiate করা যায় না
- Abstract class shared fields, constructors এবং concrete methods রাখতে পারে
- Abstract constructor child object-এর parent state initialize করে
- Concrete child required abstract methods implement করে
- Abstract child implementation defer করতে পারে
- Parent shared algorithm এবং child-specific step combine করতে পারে
- Final template method parent invariant protect করতে পারে
- Interface behavioral contract বা capability represent করে
- Class
implementsদিয়ে interface গ্রহণ করে - Interface methods public contract
- একটি class multiple interfaces implement করতে পারে
- Interface references implementation-independent polymorphism দেয়
- Abstract class shared identity এবং state-এর জন্য useful
- Interface shared capability এবং replaceable behavior-এর জন্য useful
- Interface fields instance state নয়; constants
- Modern interfaces default, static এবং private helper methods রাখতে পারে
- Default method conflict হলে classকে resolve করতে হয়
- Abstract class একটি interface implement করতে পারে
- একই class abstract parent extend এবং multiple interfaces implement করতে পারে
- Broad parent contract unsupported child behavior force করতে পারে
- Capability interfaces broad hierarchy avoid করতে সাহায্য করে
- Every class-এর interface তৈরি করা প্রয়োজন নেই
- Interface explosion codebase fragmented করতে পারে
- Empty abstract parent বা marker interface meaningful abstraction নাও হতে পারে
- Abstraction real domain বা dependency need থেকে আসা উচিত
- Abstract class এবং interface complementary tools, competitors নয়
Next Lesson
পরবর্তী lesson:
Polymorphic Methods and Collections
আমরা শিখব:
- Parent এবং interface type parameters
- Multiple implementations একই method-এ pass করা
- Polymorphic collections
- Runtime dispatch inside loops
- Common operations without type-specific conditions
- Safe casting
- Pattern matching with
instanceof - Casting কখন necessary
- Repeated type checks কখন design smell
- Polymorphic return values