Inheritance, Interfaces, and Polymorphism

Inheritance and Type Hierarchies

ReadingPreview

আপনি একটি free preview lesson দেখছেন।

Lesson Overview

একটি application বড় হওয়ার সঙ্গে সঙ্গে এমন classes পাওয়া যায় যাদের মধ্যে কিছু state এবং behavior common।

ধরা যাক LiveKlass-এ তিন ধরনের lesson content আছে:

Video Lesson
Article Lesson
Quiz Lesson

প্রতিটি content-এর common information থাকতে পারে:

ID
Title
Published status
Estimated duration

আবার প্রত্যেক content type-এর কিছু নিজস্ব information থাকে:

Video Lesson:
Video URL
Video duration

Article Lesson:
Article content
Estimated reading time

Quiz Lesson:
Questions
Passing score

আমরা চাই না প্রতিটি class-এ common code blindly duplicate করতে।

একই সঙ্গে শুধু code reuse-এর জন্য ভুল inheritance hierarchy-ও তৈরি করতে চাই না।

Inheritance useful যখন:

  • Multiple types একটি meaningful common type share করে
  • Child object parent type হিসেবে ব্যবহার করা logically valid
  • Common contract এবং behavior সত্যিকার অর্থে shared
  • Relationshipটি একটি valid is-a relationship

এই lesson-এ আমরা শিখব:

  • Type hierarchy কী
  • Parent এবং child class
  • extends
  • Inherited fields এবং methods
  • Child-specific state এবং behavior
  • is-a relationship
  • Substitutability-এর foundation
  • Java single inheritance
  • Every class কীভাবে Object hierarchy-এর অংশ
  • কখন inheritance ব্যবহার করা উচিত নয়

Learning Objectives

এই lesson শেষ করার পর আপনি পারবেন:

  • Inheritance-এর purpose explain করতে
  • Parent এবং child class identify করতে
  • extends ব্যবহার করে simple hierarchy তৈরি করতে
  • Inherited behavior ব্যবহার করতে
  • Child class-এ additional state এবং behavior add করতে
  • Valid এবং invalid is-a relationship distinguish করতে
  • Parent type reference-এ child object assign করতে
  • Single inheritance-এর limitation বুঝতে
  • Code reuse এবং substitutability-এর পার্থক্য ব্যাখ্যা করতে
  • Inheritance-এর পরিবর্তে composition প্রয়োজন হতে পারে এমন design identify করতে

The Problem: Related Types with Repeated Code

Inheritance ছাড়া আমরা classes লিখতে পারি:

public class VideoLesson {

    private final long id;
    private final String title;

    private boolean published;

    public VideoLesson(
            long id,
            String title
    ) {
        if (id <= 0) {
            throw new IllegalArgumentException(
                    "Lesson ID must be positive."
            );
        }

        if (
                title == null
                || title.isBlank()
        ) {
            throw new IllegalArgumentException(
                    "Lesson title is required."
            );
        }

        this.id = id;
        this.title = title.strip();
        this.published = false;
    }

    public boolean publish() {
        if (published) {
            return false;
        }

        published = true;

        return true;
    }

    public long getId() {
        return id;
    }

    public String getTitle() {
        return title;
    }

    public boolean isPublished() {
        return published;
    }
}

Article lesson-এর জন্য প্রায় same code:

public class ArticleLesson {

    private final long id;
    private final String title;

    private boolean published;

    public ArticleLesson(
            long id,
            String title
    ) {
        if (id <= 0) {
            throw new IllegalArgumentException(
                    "Lesson ID must be positive."
            );
        }

        if (
                title == null
                || title.isBlank()
        ) {
            throw new IllegalArgumentException(
                    "Lesson title is required."
            );
        }

        this.id = id;
        this.title = title.strip();
        this.published = false;
    }

    public boolean publish() {
        if (published) {
            return false;
        }

        published = true;

        return true;
    }

    public long getId() {
        return id;
    }

    public String getTitle() {
        return title;
    }

    public boolean isPublished() {
        return published;
    }
}

Repeated code:

id
title
published
constructor validation
publish()
getId()
getTitle()
isPublished()

Duplication নিজে inheritance ব্যবহারের যথেষ্ট কারণ নয়।

প্রথমে দেখতে হবে types সত্যিই একটি common concept represent করে কি না।

এখানে:

VideoLesson is a ContentItem
ArticleLesson is a ContentItem
QuizLesson is a ContentItem

এই relationship meaningful।

তাই একটি common parent type useful হতে পারে।


What Is Inheritance?

Inheritance একটি class-কে অন্য class-এর accessible state এবং behavior reuse ও specialize করতে দেয়।

Parent class:

public class ContentItem {

}

Child class:

public class VideoLesson
        extends ContentItem {

}

VideoLesson এখন ContentItem-এর subclass।

ContentItem হলো VideoLesson-এর superclass।


Common Terminology

Inheritance আলোচনা করার সময় কয়েকটি term ব্যবহার করা হয়।

TermMeaning
Parent classযে class থেকে inherit করা হয়
Child classযে class parent-কে extend করে
SuperclassParent class-এর আরেকটি নাম
SubclassChild class-এর আরেকটি নাম
Base classParent class বোঝাতে ব্যবহৃত হয়
Derived classChild class বোঝাতে ব্যবহৃত হয়

Example:

public class ContentItem {

}
public class VideoLesson
        extends ContentItem {

}

এখানে:

ContentItem → Parent / Superclass / Base class
VideoLesson → Child / Subclass / Derived class

Creating a Parent Class

আমরা common state এবং behavior ContentItem-এ রাখব।

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 boolean publish() {
        if (published) {
            return false;
        }

        published = true;

        return true;
    }

    public long getId() {
        return id;
    }

    public String getTitle() {
        return title;
    }

    public boolean isPublished() {
        return published;
    }
}

এই class common content state own করছে।


Extending a Class

VideoLesson class ContentItem extend করতে পারে।

public class VideoLesson
        extends ContentItem {

}

এখন VideoLesson inheritedভাবে ব্যবহার করতে পারে:

publish()
getId()
getTitle()
isPublished()

তবে parent constructor call করার জন্য child constructor প্রয়োজন।

super(...) পরবর্তী lesson-এ বিস্তারিত শেখানো হবে।

এখানে minimal example:

public class VideoLesson
        extends ContentItem {

    public VideoLesson(
            long id,
            String title
    ) {
        super(
                id,
                title
        );
    }
}

Usage:

VideoLesson videoLesson =
        new VideoLesson(
                1L,
                "Introduction to Classes"
        );

videoLesson.publish();

System.out.println(
        videoLesson.getTitle()
);

System.out.println(
        videoLesson.isPublished()
);

Output:

Introduction to Classes
true

VideoLesson নিজের class-এ publish() declare করেনি।

Methodটি ContentItem থেকে inherited।


Inherited Behavior

Parent-এর accessible methods child object দিয়ে call করা যায়।

videoLesson.publish();
videoLesson.getTitle();
videoLesson.isPublished();

Conceptually:

VideoLesson object
├── ContentItem state and behavior
└── VideoLesson-specific state and behavior

Inheritance child object-কে parent-এর public API দেয়।


Adding Child-Specific State

Video lesson-এর একটি video URL থাকতে পারে।

public class VideoLesson
        extends ContentItem {

    private final String videoUrl;

    public VideoLesson(
            long id,
            String title,
            String videoUrl
    ) {
        super(
                id,
                title
        );

        if (
                videoUrl == null
                || videoUrl.isBlank()
        ) {
            throw new IllegalArgumentException(
                    "Video URL is required."
            );
        }

        this.videoUrl =
                videoUrl.strip();
    }

    public String getVideoUrl() {
        return videoUrl;
    }
}

এখন VideoLesson-এর দুই ধরনের behavior আছে।

Inherited:

publish()
getId()
getTitle()
isPublished()

নিজস্ব:

getVideoUrl()

Another Child Class

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();
    }

    public String getContent() {
        return content;
    }
}

Both child classes share parent behavior।

VideoLesson videoLesson =
        new VideoLesson(
                1L,
                "Classes and Objects",
                "https://cdn.liveklass.io/videos/1"
        );

ArticleLesson articleLesson =
        new ArticleLesson(
                2L,
                "Understanding Object State",
                "An object combines state and behavior."
        );

videoLesson.publish();
articleLesson.publish();

Type Hierarchy

Current hierarchy:

ContentItem
├── VideoLesson
└── ArticleLesson

Later আমরা যোগ করতে পারি:

ContentItem
├── VideoLesson
├── ArticleLesson
└── QuizLesson

Parent common type represent করে।

Children specialized forms represent করে।


The is-a Relationship

Inheritance design evaluate করার সবচেয়ে useful test:

Child কি সত্যিকার অর্থে parent-এর একটি type?

Examples:

VideoLesson is a ContentItem
ArticleLesson is a ContentItem
QuizLesson is a ContentItem

Natural এবং meaningful।

Invalid examples:

Enrollment is a Course
Course is a Learner
VideoLesson is a VideoPlayer

এগুলো natural type relationships নয়।


is-a Is More Than a Sentence

শুধু sentence grammatically possible হলেই inheritance correct নয়।

Example:

Square is a Rectangle

Mathematically true মনে হতে পারে।

কিন্তু যদি mutable Rectangle width এবং height independently change করতে দেয়, Square সেই contract safely follow করতে নাও পারে।

Therefore stronger question:

Parent-এর জায়গায় child object ব্যবহার করলে existing code কি logically correct থাকবে?

এটিই substitutability-এর foundation।


Substitutability

ধরা যাক একটি method যেকোনো content publish করে।

public static boolean publishContent(
        ContentItem content
) {
    return content.publish();
}

আমরা VideoLesson pass করতে পারি।

VideoLesson videoLesson =
        new VideoLesson(
                1L,
                "Java Classes",
                "https://cdn.liveklass.io/videos/1"
        );

publishContent(
        videoLesson
);

আমরা ArticleLesson-ও pass করতে পারি।

ArticleLesson articleLesson =
        new ArticleLesson(
                2L,
                "Object State",
                "Objects hold state."
        );

publishContent(
        articleLesson
);

কারণ:

VideoLesson is a ContentItem
ArticleLesson is a ContentItem

Parent type expect করা code child object accept করতে পারে।


Parent Reference and Child Object

Java allows:

ContentItem content =
        new VideoLesson(
                1L,
                "Java Classes",
                "https://cdn.liveklass.io/videos/1"
        );

Variable type:

ContentItem

Runtime object:

VideoLesson

এটি polymorphism-এর foundation।

Reference-এর compile-time type বলে caller কোন members use করতে পারবে।

content.publish();
content.getTitle();

Valid, কারণ methods ContentItem-এ declare করা।

কিন্তু:

content.getVideoUrl();

compile হবে না।

কারণ ContentItem type-এর contract-এ getVideoUrl() নেই।

যদিও runtime object একটি VideoLesson


Compile-Time Type vs Runtime Type

ContentItem content =
        new VideoLesson(
                1L,
                "Java Classes",
                "https://cdn.liveklass.io/videos/1"
        );

এখানে:

Compile-time type → ContentItem
Runtime type      → VideoLesson

Compile-time type determine করে কোন method calls compiler allow করবে।

Runtime type পরে overridden behavior select করতে পারে।

Method overriding এবং runtime dispatch Lesson 3-এ বিস্তারিত শেখানো হবে।


Why Use a Parent Reference?

এই code:

VideoLesson lesson =
        new VideoLesson(...);

valid এবং useful।

কিন্তু parent reference:

ContentItem lesson =
        new VideoLesson(...);

caller-কে common contract-এর ওপর depend করতে দেয়।

Caller শুধু জানে:

This is publishable content with an ID and title.

Caller-এর video-specific details জানার প্রয়োজন নেই।

এতে coupling কমতে পারে।


A Common Method for Multiple Child Types

Without common parent:

public static void printVideoTitle(
        VideoLesson lesson
) {
}

public static void printArticleTitle(
        ArticleLesson lesson
) {
}

With parent type:

public static void printTitle(
        ContentItem content
) {
    System.out.println(
            content.getTitle()
    );
}

Usage:

printTitle(
        videoLesson
);

printTitle(
        articleLesson
);

একটি method multiple related types handle করতে পারে।


Reuse Is Not the Primary Goal

Inheritance common code reuse করে।

কিন্তু inheritance-এর strongest purpose শুধু duplication remove করা নয়।

Primary purpose:

A child can safely be treated as its parent type.

যদি classes কিছু code share করে কিন্তু same type relationship না থাকে, inheritance wrong হতে পারে।

Example:

public class Course
        extends StringUtils {
}

Course কিছু string helper reuse করতে পারে, কিন্তু:

Course is a StringUtils

meaningless।

Better:

String normalized =
        CourseTitleNormalizer.normalize(
                title
        );

অথবা behaviorটি Course-এর own private method হতে পারে।


Inheritance Creates Coupling

Child class parent-এর design-এর ওপর depend করে।

Parent change করলে child behavior affect হতে পারে।

Examples:

  • Parent constructor change
  • Parent method contract change
  • Parent validation change
  • Parent protected state change
  • Parent method final হওয়া
  • Parent method override behavior change

Therefore:

Inheritance একটি strong relationship; শুধু কয়েকটি lines reuse করার জন্য ব্যবহার করবেন না।


Java Supports Single Class Inheritance

একটি class সরাসরি শুধু একটি class extend করতে পারে।

Valid:

public class VideoLesson
        extends ContentItem {

}

Invalid:

public class VideoLesson
        extends ContentItem,
                MediaResource {

}

Java multiple class inheritance support করে না।

একটি class multiple interfaces implement করতে পারে।

Interfaces পরে শেখানো হবে।


A Child Can Have Its Own Children

ContentItem
└── VideoLesson
    └── LiveVideoLesson

Technically possible:

public class LiveVideoLesson
        extends VideoLesson {

}

কিন্তু deep hierarchy দ্রুত complex হতে পারে।

Avoid automatically creating:

ContentItem
→ MediaContent
→ VideoContent
→ StreamableVideoContent
→ LiveStreamVideoLesson

প্রতিটি level meaningful contract না দিলে hierarchy maintain করা কঠিন হয়।

Practical rule:

Hierarchy যত shallow রাখা যায়, তত সহজে reason করা যায়।


Every Class Ultimately Extends Object

Java-তে কোনো explicit parent না থাকলে class implicitly Object extend করে।

public class Learner {

}

Conceptually:

public class Learner
        extends Object {

}

Object common methods দেয়:

equals()
hashCode()
toString()
getClass()

আগের module-এ আমরা এগুলোর কয়েকটি override করেছি।


A Class Cannot Extend Itself

Invalid:

public class ContentItem
        extends ContentItem {

}

Inheritance hierarchy circular হতে পারে না।

Also invalid conceptually:

A extends B
B extends A

Java compiler circular inheritance reject করবে।


Parent Object Is Not Automatically a Child

Child is a parent type:

VideoLesson is a ContentItem

কিন্তু every parent object child নয়।

ContentItem content =
        new ContentItem(
                1L,
                "General Content"
        );

এটি automatically VideoLesson নয়।

Therefore:

Every VideoLesson is a ContentItem
Not every ContentItem is a VideoLesson

Upcasting

Child reference parent type-এ assign করাকে commonly upcasting বলা হয়।

VideoLesson videoLesson =
        new VideoLesson(
                1L,
                "Java Classes",
                "https://cdn.liveklass.io/videos/1"
        );

ContentItem content =
        videoLesson;

Explicit cast প্রয়োজন নেই।

কারণ conversion safe:

Every VideoLesson is a ContentItem

Downcasting: A Brief Introduction

Parent reference থেকে child type-এ cast করা possible হতে পারে।

ContentItem content =
        new VideoLesson(
                1L,
                "Java Classes",
                "https://cdn.liveklass.io/videos/1"
        );

VideoLesson videoLesson =
        (VideoLesson) content;

এখন:

videoLesson.getVideoUrl();

possible।

কিন্তু wrong runtime type cast করলে:

ContentItem content =
        new ArticleLesson(
                2L,
                "Object State",
                "Article content"
        );

VideoLesson videoLesson =
        (VideoLesson) content;

Runtime-এ:

ClassCastException

Downcasting carefully ব্যবহার করতে হয়।

Repeated downcasting design smell হতে পারে।

Polymorphic methods এবং instanceof Lesson 5-এ বিস্তারিত শেখানো হবে।


When Inheritance Is Appropriate

Inheritance consider করা যায় যখন:

1. Valid is-a Relationship Exists

VideoLesson is a ContentItem

2. Child Can Follow Parent Contract

Parent expects publishable content হলে childও safely publish behavior support করবে।

3. Common Abstraction Has Domain Meaning

ContentItem application domain-এ meaningful concept।

4. Parent API Is Stable Enough

Children parent behavior-এর ওপর depend করতে পারবে।

5. Child Adds Specialization

Video URL
Article content
Quiz questions

When Inheritance Is Probably Wrong

1. Relationship Is has-a

Course has Lessons
Enrollment has Course

Use composition।


2. Only Goal Is Code Reuse

Course extends ValidationUtils

Wrong type relationship।


3. Child Cannot Respect Parent Rules

Parent method:

public void publish() {
}

Child যদি publish করা support না করে, child সম্ভবত parent type নয়।


4. Child Must Disable Most Parent Methods

Example:

@Override
public boolean publish() {
    throw new UnsupportedOperationException();
}

এটি indicate করতে পারে hierarchy wrong।


5. Hierarchy Becomes Deep and Fragile

Too many inheritance levels behavior trace করা কঠিন করে।


6. Differences Are Configurations, Not Types

Weak hierarchy:

FreeCourse extends Course
PaidCourse extends Course
DiscountedCourse extends Course

Price behavior composition বা field দিয়ে better model হতে পারে।

Course has a PricingPolicy

Composition lesson আগের module-এ শেখানো হয়েছে।

Module 3-এর Lesson 7-এ এই trade-off বিস্তারিত review করা হবে।


Designing a Simple Content Hierarchy

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 boolean publish() {
        if (published) {
            return false;
        }

        published = true;

        return true;
    }

    public long getId() {
        return id;
    }

    public String getTitle() {
        return title;
    }

    public boolean isPublished() {
        return published;
    }
}

VideoLesson.java

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
        );

        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;
    }

    public String getVideoUrl() {
        return videoUrl;
    }

    public int getDurationInMinutes() {
        return durationInMinutes;
    }
}

ArticleLesson.java

public class ArticleLesson
        extends ContentItem {

    private final String content;
    private final int estimatedReadingMinutes;

    public ArticleLesson(
            long id,
            String title,
            String content,
            int estimatedReadingMinutes
    ) {
        super(
                id,
                title
        );

        if (
                content == null
                || content.isBlank()
        ) {
            throw new IllegalArgumentException(
                    "Article content is required."
            );
        }

        if (estimatedReadingMinutes <= 0) {
            throw new IllegalArgumentException(
                    "Estimated reading time must be positive."
            );
        }

        this.content =
                content.strip();

        this.estimatedReadingMinutes =
                estimatedReadingMinutes;
    }

    public String getContent() {
        return content;
    }

    public int getEstimatedReadingMinutes() {
        return estimatedReadingMinutes;
    }
}

Main.java

public class Main {

    public static void main(
            String[] args
    ) {
        VideoLesson videoLesson =
                new VideoLesson(
                        1L,
                        "Introduction to Inheritance",
                        "https://cdn.liveklass.io/videos/inheritance",
                        18
                );

        ArticleLesson articleLesson =
                new ArticleLesson(
                        2L,
                        "Understanding Type Hierarchies",
                        "A type hierarchy models related types.",
                        7
                );

        videoLesson.publish();
        articleLesson.publish();

        printContentSummary(
                videoLesson
        );

        printContentSummary(
                articleLesson
        );
    }

    private static void printContentSummary(
            ContentItem content
    ) {
        System.out.println(
                "ID: "
                + content.getId()
        );

        System.out.println(
                "Title: "
                + content.getTitle()
        );

        System.out.println(
                "Published: "
                + content.isPublished()
        );

        System.out.println();
    }
}

Possible output:

ID: 1
Title: Introduction to Inheritance
Published: true

ID: 2
Title: Understanding Type Hierarchies
Published: true

একটি method দুই ধরনের child object handle করেছে।

এটাই polymorphism-এর foundation।


Design Observation: Is ContentItem Complete?

Current ContentItem directly instantiate করা যায়।

new ContentItem(
        1L,
        "General Content"
);

কিন্তু LiveKlass domain-এ যদি every content অবশ্যই specific type হয়:

Video
Article
Quiz

তাহলে generic ContentItem object meaningful নাও হতে পারে।

এই ক্ষেত্রে ContentItem abstract class করা যেতে পারে।

public abstract class ContentItem {

}

Abstract classes Lesson 4-এ বিস্তারিত শেখানো হবে।

এখন শুধু design questionটি মনে রাখুন:

Parent class নিজে complete object represent করে, নাকি শুধু children-এর common abstraction?


Common Mistakes

Using Inheritance Only to Remove Duplicate Code

Course extends ValidationHelper

Common type relationship নেই।


Confusing has-a with is-a

Wrong:

Enrollment extends Course

Correct:

Enrollment has a Course

Making Child Classes That Reject Parent Behavior

public class DraftOnlyContent
        extends ContentItem {

    @Override
    public boolean publish() {
        throw new UnsupportedOperationException();
    }
}

Parent contract child fulfil করছে না।


Assuming Parent Reference Exposes Child Methods

ContentItem content =
        new VideoLesson(...);

content.getVideoUrl();

Compile হবে না, কারণ methodটি parent type-এর contract-এ নেই।


Assuming Parent Object Is Automatically a Child

ContentItem content =
        new ContentItem(...);

VideoLesson video =
        (VideoLesson) content;

Runtime-এ ClassCastException হবে।


Creating Deep Hierarchies Too Early

Content
→ LearningContent
→ MediaContent
→ VideoContent
→ RecordedVideoContent
→ RecordedLesson

Requirements justify না করলে unnecessary complexity।


Exposing Parent Fields as protected by Default

Child access সহজ করার জন্য সব parent fields protected করা encapsulation দুর্বল করতে পারে।

Parent fields সাধারণত private রাখুন।

Parent methods দিয়ে controlled access দিন।

Inherited access Lesson 2-এ বিস্তারিত শেখানো হবে।


Practice Exercises

Exercise 1: Create QuizLesson

Create:

public class QuizLesson
        extends ContentItem

Additional fields:

questionCount
passingScore

Rules:

  • Question count positive
  • Passing score 0 থেকে 100-এর মধ্যে
  • Parent state super(...) দিয়ে initialize হবে

Exercise 2: Identify Valid is-a Relationships

নিচের relationshipগুলো valid inheritance কি না নির্ধারণ করুন:

  1. VideoLesson is a ContentItem
  2. Course is a Lesson
  3. Instructor is a User
  4. Enrollment is a Course
  5. QuizLesson is a ContentItem
  6. Course has a PricingPolicy

Exercise 3: Parent Reference

Create:

ContentItem content =
        new ArticleLesson(
                1L,
                "Java Objects",
                "Article content",
                5
        );

Determine which calls compile:

content.getTitle();
content.publish();
content.getContent();

Explain why।


Exercise 4: Common Method

Write:

static void publishAndPrint(
        ContentItem content
)

Methodটি:

  • Content publish করবে
  • Title print করবে
  • Published status print করবে

Call it with:

VideoLesson
ArticleLesson
QuizLesson

Exercise 5: Inheritance or Composition

Choose inheritance or composition:

  1. Course and Lesson
  2. VideoLesson and ContentItem
  3. Enrollment and Learner
  4. EmailNotification and Notification
  5. Course and PricingPolicy

Explain each decision।


Exercise 6: Find the Wrong Hierarchy

Review:

public class Course
        extends ArrayList<Lesson> {

}

A course contains lessons, but should a course be treated as an ArrayList?

Explain why composition may be stronger।


Predict the Result

Question 1

VideoLesson video =
        new VideoLesson(
                1L,
                "Inheritance",
                "https://example.com/video",
                10
        );

System.out.println(
        video.getTitle()
);

Will this compile even though getTitle() is not declared in VideoLesson?


Question 2

ContentItem content =
        new VideoLesson(
                1L,
                "Inheritance",
                "https://example.com/video",
                10
        );

System.out.println(
        content.getVideoUrl()
);

Will it compile?


Question 3

ContentItem first =
        new ArticleLesson(
                1L,
                "Objects",
                "Content",
                5
        );

ContentItem second =
        first;

first.publish();

System.out.println(
        second.isPublished()
);

Question 4

ContentItem content =
        new ContentItem(
                1L,
                "General"
        );

VideoLesson video =
        (VideoLesson) content;

What happens?


Predict the Result Answers

Answer 1

হ্যাঁ।

VideoLesson ContentItem থেকে getTitle() inherit করেছে।

Answer 2

না।

Reference-এর compile-time type ContentItem, এবং ContentItem-এ getVideoUrl() declare করা নেই।

Answer 3

true

Both references same object point করে।

Answer 4

Code compile করতে পারে, কিন্তু runtime-এ:

ClassCastException

কারণ actual object VideoLesson নয়।


Knowledge Check

Question 1

Inheritance কী?

Question 2

Parent class এবং child class কী?

Question 3

extends keyword কী করে?

Question 4

Inherited method কী?

Question 5

is-a relationship কী?

Question 6

Substitutability কী?

Question 7

Parent type reference কি child object hold করতে পারে?

Question 8

Parent reference দিয়ে child-specific method সবসময় call করা যায় কি?

Question 9

Java একটি class-কে কয়টি class directly extend করতে দেয়?

Question 10

Every Java class-এর ultimate parent কোন class?

Question 11

Inheritance-এর primary purpose শুধু code reuse কি?

Question 12

has-a relationship inheritance দিয়ে model করা উচিত কি?

Question 13

Deep hierarchy risky কেন?

Question 14

Upcasting safe কেন?


Knowledge Check Answers

Answer 1

একটি class অন্য class-এর accessible behavior এবং type contract inherit করে specialize করার mechanism।

Answer 2

Parent common type এবং behavior define করে। Child parent extend করে specialized type তৈরি করে।

Answer 3

একটি class-কে অন্য class-এর subclass হিসেবে declare করে।

Answer 4

Parent class-এ declared এমন accessible method, যা child object ব্যবহার করতে পারে।

Answer 5

Child সত্যিকার অর্থে parent-এর একটি specialized type।

Answer 6

Parent-এর জায়গায় child ব্যবহার করলেও expected contract এবং behavior valid থাকা।

Answer 7

হ্যাঁ।

ContentItem content =
        new VideoLesson(...);

Answer 8

না। Compile-time parent type-এর contract-এ methodটি থাকতে হবে, অথবা explicit safe cast প্রয়োজন।

Answer 9

একটি।

Answer 10

Object

Answer 11

না। Stronger purpose হলো common type এবং safe substitutability।

Answer 12

সাধারণত না। Composition ব্যবহার করা উচিত।

Answer 13

Behavior trace, initialization, coupling এবং changes বোঝা কঠিন হয়।

Answer 14

Every child object parent type-এর object হওয়ায় child-to-parent conversion valid।


Lesson Summary

এই lesson-এ আমরা শিখেছি:

  • Inheritance related types-এর hierarchy তৈরি করে
  • Parent common state, behavior এবং contract define করতে পারে
  • Child extends ব্যবহার করে parent inherit করে
  • Parent class-কে superclass বা base classও বলা হয়
  • Child class-কে subclass বা derived class বলা হয়
  • Child inherited behavior ব্যবহার করতে পারে
  • Child নিজের additional state এবং behavior add করতে পারে
  • Valid inheritance একটি meaningful is-a relationship require করে
  • VideoLesson is a ContentItem একটি valid relationship
  • Enrollment is a Course valid relationship নয়
  • Parent type reference child object hold করতে পারে
  • Compile-time type available method calls control করে
  • Runtime object actual specialized object represent করে
  • Upcasting child-to-parent safe
  • Downcasting ভুল runtime type-এর ক্ষেত্রে fail করতে পারে
  • Inheritance শুধু code reuse-এর জন্য ব্যবহার করা উচিত নয়
  • Substitutability inheritance-এর central design requirement
  • Java single class inheritance support করে
  • Every Java class ultimately Object extend করে
  • Deep hierarchy complexity এবং coupling বাড়ায়
  • has-a relationship composition দিয়ে model করা উচিত
  • Parent নিজে meaningful object না হলে abstract class appropriate হতে পারে
  • Good inheritance hierarchy shallow, meaningful এবং contract-focused হয়

Next Lesson

পরবর্তী lesson:

Parent Construction, super, and Inherited Access

আমরা শিখব:

  • Parent constructor কেন execute হয়
  • super(...)
  • Automatic super()
  • Constructor execution order
  • this(...) এবং super(...)
  • Parent private state
  • Inherited access
  • protected-এর trade-offs
  • final class এবং final method