Skill

স্কালা অবজেক্ট ওরিয়েন্টেড প্রোগ্রামিং

স্কালা প্রোগ্রামিং (Scala Programming) - Computer Programming

237

স্কালা একটি অবজেক্ট-অরিয়েন্টেড প্রোগ্রামিং (OOP) ভাষা, যা সম্পূর্ণ অবজেক্ট ভিত্তিক এবং এর মধ্যে ক্লাস, অবজেক্ট, ইনহেরিটেন্স, পলিমরফিজম, অ্যাবস্ট্রাকশন, এবং এনক্যাপসুলেশন এর মতো OOP এর সমস্ত মূল ধারণা অন্তর্ভুক্ত রয়েছে। স্কালার OOP বৈশিষ্ট্যগুলো স্কালার শক্তি এবং নমনীয়তার জন্য গুরুত্বপূর্ণ ভূমিকা পালন করে।

এখানে স্কালার অবজেক্ট-অরিয়েন্টেড প্রোগ্রামিং এর কিছু গুরুত্বপূর্ণ ধারণা এবং উদাহরণ দেওয়া হল।


১. ক্লাস (Class)

স্কালায় ক্লাস তৈরি করতে class কিওয়ার্ড ব্যবহার করা হয়। ক্লাসের মধ্যে ফিল্ড, মেথড এবং কনস্ট্রাক্টর থাকতে পারে। ক্লাসে সাধারণত একটি বা একাধিক অবজেক্ট তৈরি করা হয়।

উদাহরণ:

class Person(var name: String, var age: Int) {
  def greet(): Unit = {
    println(s"Hello, my name is $name and I am $age years old.")
  }
}

val person = new Person("Alice", 30)
person.greet()  // Output: Hello, my name is Alice and I am 30 years old.

এখানে:

  • Person একটি ক্লাস যা দুটি ভ্যারিয়েবল name এবং age ধারণ করে।
  • greet একটি মেথড যা name এবং age ব্যবহার করে একটি বার্তা প্রিন্ট করে।

২. অবজেক্ট (Object)

স্কালা একটি সিঙ্গলটন অবজেক্ট হিসাবে কাজ করে, অর্থাৎ আপনি যখন object কিওয়ার্ড ব্যবহার করেন, তখন এটি একটি একক ইনস্ট্যান্স তৈরি করে। স্কালায় object একক কপি তৈরি করে এবং একাধিকবার ব্যবহার করা যায় না।

উদাহরণ:

object MySingleton {
  def greet(): Unit = {
    println("Hello from Singleton!")
  }
}

MySingleton.greet()  // Output: Hello from Singleton!

এখানে:

  • MySingleton একটি অবজেক্ট যা greet মেথড ধারণ করে। একবার অবজেক্ট তৈরি হলে, তা পুনরায় ইনস্ট্যান্স করা যায় না।

৩. ইনহেরিটেন্স (Inheritance)

স্কালায় ইনহেরিটেন্সের মাধ্যমে একটি ক্লাস অন্য ক্লাস থেকে বৈশিষ্ট্য অর্জন করতে পারে। ক্লাসের মধ্যে extends কিওয়ার্ড ব্যবহার করে ইনহেরিটেন্স তৈরি করা হয়।

উদাহরণ:

class Animal(val name: String) {
  def speak(): Unit = {
    println(s"Animal name is $name")
  }
}

class Dog(name: String) extends Animal(name) {
  def bark(): Unit = {
    println(s"$name says Woof!")
  }
}

val dog = new Dog("Rex")
dog.speak()  // Output: Animal name is Rex
dog.bark()   // Output: Rex says Woof!

এখানে:

  • Dog ক্লাস Animal ক্লাস থেকে ইনহেরিট করেছে এবং bark নামক একটি নতুন মেথড যোগ করেছে।

৪. পলিমরফিজম (Polymorphism)

স্কালায় পলিমরফিজমের মাধ্যমে একই মেথড বিভিন্ন ধরনের অবজেক্টের জন্য বিভিন্নভাবে কাজ করতে পারে। এটি মেথড ওভাররাইডিং এবং মেথড ওভারলোডিং এর মাধ্যমে অর্জিত হয়।

উদাহরণ (মেথড ওভাররাইডিং):

class Animal {
  def speak(): Unit = {
    println("Animal speaks")
  }
}

class Dog extends Animal {
  override def speak(): Unit = {
    println("Dog barks")
  }
}

val animal = new Animal()
val dog = new Dog()

animal.speak()  // Output: Animal speaks
dog.speak()     // Output: Dog barks

এখানে:

  • Dog ক্লাস speak মেথডটি Animal ক্লাস থেকে ওভাররাইড করেছে এবং একটি নতুন বাস্তবায়ন প্রদান করেছে।

৫. এনক্যাপসুলেশন (Encapsulation)

এনক্যাপসুলেশন হল ক্লাসের অভ্যন্তরীণ ডেটা এবং মেথডগুলিকে সুরক্ষিত রাখা, যাতে বাহ্যিক কোডের সঙ্গে সরাসরি যোগাযোগ না হয়। স্কালায় এটি private এবং protected অ্যাক্সেস মডিফায়ার ব্যবহার করে অর্জিত হয়।

উদাহরণ:

class BankAccount(private var balance: Double) {
  def deposit(amount: Double): Unit = {
    if (amount > 0) balance += amount
  }
  
  def withdraw(amount: Double): Unit = {
    if (amount <= balance) balance -= amount
  }

  def getBalance(): Double = balance
}

val account = new BankAccount(1000)
account.deposit(500)
account.withdraw(200)

println(account.getBalance())  // Output: 1300

এখানে:

  • balance ভ্যারিয়েবলটি private করা হয়েছে, যার ফলে এটি সরাসরি বাহ্যিক কোড থেকে অ্যাক্সেস করা যায় না। তবে deposit এবং withdraw মেথডগুলির মাধ্যমে এটি পরিবর্তন করা যায়।

৬. অ্যাবস্ট্রাকশন (Abstraction)

স্কালায় অ্যাবস্ট্রাকশন প্রদান করা হয় abstract কিওয়ার্ডের মাধ্যমে। এটি একটি ক্লাসের মধ্যে এমন বৈশিষ্ট্য প্রকাশ করতে সহায়তা করে যা সাবক্লাস দ্বারা বাস্তবায়ন করা যাবে।

উদাহরণ:

abstract class Animal {
  def sound(): Unit  // Abstract method
}

class Dog extends Animal {
  def sound(): Unit = {
    println("Woof!")
  }
}

val dog = new Dog()
dog.sound()  // Output: Woof!

এখানে:

  • Animal একটি abstract class, যেখানে sound মেথডটি অ্যাবস্ট্রাক্ট হিসেবে ডিফাইন করা হয়েছে এবং Dog ক্লাস এই মেথডের বাস্তবায়ন প্রদান করেছে।

সারাংশ

স্কালা অবজেক্ট-অরিয়েন্টেড প্রোগ্রামিং ভাষা হিসেবে জাভার মতো বিভিন্ন OOP বৈশিষ্ট্য সমর্থন করে। এর মধ্যে ক্লাস, অবজেক্ট, ইনহেরিটেন্স, পলিমরফিজম, এনক্যাপসুলেশন এবং অ্যাবস্ট্রাকশন এর মতো OOP ধারণাগুলি ব্যবহৃত হয়। স্কালার OOP বৈশিষ্ট্যগুলি একটি প্রোগ্রামারকে ক্লিন, কার্যকরী এবং পুনঃব্যবহারযোগ্য কোড লেখার সুযোগ প্রদান করে, যা সফটওয়্যার ডেভেলপমেন্টকে আরও সহজ এবং উন্নত করে।

Content added By

স্কালার ক্লাস এবং অবজেক্ট উভয়ই গুরুত্বপূর্ণ বৈশিষ্ট্য এবং এটি একটি অবজেক্ট-অরিয়েন্টেড প্রোগ্রামিং ভাষা হওয়ার কারণে, স্কালায় সব কিছুই অবজেক্টের সাথে সম্পর্কিত। এই অধ্যায়ে, আমরা স্কালার ক্লাস এবং অবজেক্ট সম্পর্কে বিস্তারিতভাবে আলোচনা করব।


১. স্কালা ক্লাস (Scala Class)

স্কালায় ক্লাস একটি ব্লুপ্রিন্ট বা টেমপ্লেট হিসেবে কাজ করে, যার মধ্যে ডাটা (অ্যাট্রিবিউট) এবং মেথড (অ্যাকশন) সংরক্ষিত থাকে। ক্লাস ডিফাইন করার জন্য class কিওয়ার্ড ব্যবহার করা হয়।

ক্লাস ডেফিনিশন:

class ClassName {
  // class body
}

উদাহরণ: সাধারণ ক্লাস

class Person(val name: String, val age: Int) {
  def greet(): Unit = {
    println(s"Hello, my name is $name and I am $age years old.")
  }
}

val person1 = new Person("Alice", 30)
person1.greet()  // Output: Hello, my name is Alice and I am 30 years old.

এখানে:

  • Person ক্লাসের দুটি প্যারামিটার রয়েছে: name এবং age, যেগুলি val (immutable) দিয়ে ডিফাইন করা হয়েছে।
  • greet মেথডের মাধ্যমে আমরা name এবং age আউটপুট হিসেবে প্রিন্ট করছি।
  • new Person(...) দিয়ে ক্লাসের ইনস্ট্যান্স তৈরি করা হয়।

২. স্কালা অবজেক্ট (Scala Object)

স্কালার অবজেক্ট একটি একক ইনস্ট্যান্স, যা ক্লাসের মতো কাজ করে তবে শুধুমাত্র একটি অবজেক্ট থাকে। অবজেক্ট মূলত singleton ক্লাস, অর্থাৎ এর একমাত্র একটি ইনস্ট্যান্স থাকে। স্কালার অবজেক্ট সাধারণত এক্সিকিউটেবল কোডের জন্য ব্যবহৃত হয় এবং সাধারণত main মেথড থাকে যেখানে প্রোগ্রামটি শুরু হয়।

অবজেক্ট ডেফিনিশন:

object ObjectName {
  // object body
}

উদাহরণ: সাধারণ অবজেক্ট

object HelloWorld {
  def main(args: Array[String]): Unit = {
    println("Hello, Scala Object!")
  }
}

এখানে:

  • HelloWorld একটি অবজেক্ট, যার মধ্যে main মেথড রয়েছে।
  • অবজেক্টটি একবারই তৈরি হয় এবং এটি প্রোগ্রাম শুরু করার জন্য ব্যবহৃত হয়।
  • স্কালায় object কিওয়ার্ডের মাধ্যমে একটি একক ইনস্ট্যান্স তৈরি হয়, যার মাধ্যমে আপনি কোডের কার্যকরী অংশ সম্পাদন করতে পারেন।

৩. ক্লাস এবং অবজেক্টের পার্থক্য

পার্থক্যক্লাস (Class)অবজেক্ট (Object)
ইনস্ট্যান্সক্লাস থেকে একাধিক ইনস্ট্যান্স তৈরি করা যায়একমাত্র একটি ইনস্ট্যান্স থাকে
সংজ্ঞাclass কিওয়ার্ড দিয়ে ডিফাইন করা হয়object কিওয়ার্ড দিয়ে ডিফাইন করা হয়
ব্যবহারঅবজেক্ট তৈরি করার জন্য ক্লাস ব্যবহার করা হয়একমাত্র ইনস্ট্যান্সের মাধ্যমে কাজ সম্পাদন করা হয়
স্টেটক্লাসের মধ্যে স্টেট থাকতে পারেঅবজেক্টের মধ্যে একটি একক ইনস্ট্যান্স থাকে
ইনস্ট্যান্স তৈরিnew ClassName ব্যবহার করে ইনস্ট্যান্স তৈরি করা হয়সরাসরি অবজেক্টের নাম দিয়ে এক্সেস করা যায়

৪. ক্লাসের মধ্যে কনস্ট্রাক্টর (Constructor) ব্যবহার

স্কালায়, কনস্ট্রাক্টর ক্লাসের সাথে যুক্ত থাকে এবং এটি ক্লাসের ইনস্ট্যান্স তৈরি করার সময় ব্যবহৃত হয়। স্কালায় দুটি কনস্ট্রাক্টর থাকে:

  1. প্রধান কনস্ট্রাক্টর: ক্লাসের সাথে সরাসরি যুক্ত থাকে।
  2. সহায়ক কনস্ট্রাক্টর: অতিরিক্ত কনস্ট্রাক্টর ফাংশন।

উদাহরণ: কনস্ট্রাক্টর ব্যবহার

class Person(val name: String, val age: Int) {
  println(s"Person created: $name, $age")
}

val person1 = new Person("Alice", 30)

এখানে:

  • Person ক্লাসে দুটি প্যারামিটার name এবং age রয়েছে, যেগুলি প্রধান কনস্ট্রাক্টর হিসেবে ব্যবহৃত হচ্ছে।
  • যখন new Person("Alice", 30) কল করা হয়, তখন name এবং age প্যারামিটার দিয়ে কনস্ট্রাক্টর ইনিশিয়ালাইজ করা হয়।

৫. বিভিন্ন অবজেক্টের মধ্যে এক্সেস

স্কালায়, আপনি একটি অবজেক্টের মধ্যে ডিফাইন করা মেথড এবং ভ্যারিয়েবল অন্য অবজেক্ট থেকে এক্সেস করতে পারেন। একে সিঙ্গেলটন প্যাটার্ন বলা হয়।

উদাহরণ: অবজেক্টের মধ্যে এক্সেস

object Singleton {
  val message = "Hello from Singleton"
  def greet(): Unit = {
    println(message)
  }
}

object MainApp {
  def main(args: Array[String]): Unit = {
    Singleton.greet()  // Accessing method from Singleton object
  }
}

এখানে:

  • Singleton অবজেক্টে greet() মেথড এবং একটি ভ্যারিয়েবল message রয়েছে।
  • MainApp অবজেক্ট থেকে Singleton.greet() মেথড এক্সেস করা হচ্ছে।

৬. অবজেক্ট এবং ক্লাসের মধ্যে মিশ্রণ

স্কালায় আপনি একে অপরের সাথে ক্লাস এবং অবজেক্ট ব্যবহার করতে পারেন। কখনো কখনো, একটি ক্লাস এবং একটি অবজেক্ট একসাথে একটি কার্যকরী কাঠামো তৈরি করতে ব্যবহৃত হয়।

উদাহরণ: ক্লাস এবং অবজেক্টের মিশ্রণ

class Car(val make: String, val model: String) {
  def displayDetails(): Unit = {
    println(s"Car make: $make, model: $model")
  }
}

object CarFactory {
  def createCar(make: String, model: String): Car = {
    new Car(make, model)
  }
}

object MainApp {
  def main(args: Array[String]): Unit = {
    val car = CarFactory.createCar("Toyota", "Corolla")
    car.displayDetails()  // Output: Car make: Toyota, model: Corolla
  }
}

এখানে:

  • Car একটি ক্লাস যা গাড়ির তথ্য সংরক্ষণ করে।
  • CarFactory একটি অবজেক্ট যা Car ক্লাসের ইনস্ট্যান্স তৈরি করে।
  • MainApp অবজেক্ট থেকে ফ্যাক্টরি মেথড CarFactory.createCar কল করে গাড়ির বিস্তারিত দেখানো হচ্ছে।

সারাংশ

  • ক্লাস (Class): স্কালায় ক্লাস হল একটি টেমপ্লেট বা ব্লুপ্রিন্ট, যা অবজেক্ট তৈরি করতে ব্যবহৃত হয়। ক্লাসের মাধ্যমে আপনি একটি অবজেক্টের বিভিন্ন বৈশিষ্ট্য এবং আচরণ ডিফাইন করতে পারেন।
  • অবজেক্ট (Object): স্কালায় অবজেক্ট একটি একক ইনস্ট্যান্স থাকে এবং এটি সাধারণত ফাংশনাল প্রোগ্রামিংয়ে ব্যবহৃত হয়। এটি একটি singleton অবজেক্ট, যার একাধিক ইনস্ট্যান্স থাকে না।

স্কালায় ক্লাস এবং অবজেক্ট ব্যবহারের মাধ্যমে আপনি শক্তিশালী এবং স্কেলেবল প্রোগ্রাম তৈরি করতে পারেন।

Content added By

স্কালায় কনস্ট্রাক্টর এবং ওভারলোডিং দুটি অত্যন্ত গুরুত্বপূর্ণ ধারণা, যা প্রোগ্রামিংয়ের ক্ষেত্রে ক্লাসের ভেতরে বিভিন্ন ধরনের ইনস্ট্যান্স তৈরি এবং মেথডের একাধিক সংস্করণ তৈরি করতে সহায়তা করে। এখানে স্কালার কনস্ট্রাক্টর এবং ওভারলোডিং সম্পর্কে বিস্তারিত আলোচনা করা হলো।


১. কনস্ট্রাক্টর (Constructor)

স্কালায় কনস্ট্রাক্টর একটি বিশেষ মেথড যা ক্লাসের নতুন ইনস্ট্যান্স তৈরি করতে ব্যবহৃত হয়। এটি ক্লাসের একটি অংশ হিসেবে স্বয়ংক্রিয়ভাবে কল হয় যখন নতুন অবজেক্ট তৈরি করা হয়। স্কালায় দুটি ধরনের কনস্ট্রাক্টর থাকে:

  1. প্রধান কনস্ট্রাক্টর: যেটি ক্লাসের সাথেই ডিফাইন করা হয় এবং ক্লাসের মূল কনস্ট্রাক্টর হিসেবে কাজ করে।
  2. সহায়ক কনস্ট্রাক্টর: যেটি ক্লাসের ভিতরে অতিরিক্ত কনস্ট্রাক্টর হিসেবে ব্যবহৃত হয়।

১.১ প্রধান কনস্ট্রাক্টর (Primary Constructor)

স্কালায়, প্রধান কনস্ট্রাক্টর সাধারণত ক্লাসের ডেফিনিশনের মধ্যে ডিফাইন করা হয়। এটি একাধিক আর্গুমেন্ট নিতে পারে এবং এই আর্গুমেন্টগুলির মাধ্যমে অবজেক্ট তৈরি করা হয়।

উদাহরণ:

class Person(val name: String, val age: Int) {
  // Here, the primary constructor is the part of the class definition.
  def greet(): Unit = {
    println(s"Hello, my name is $name and I am $age years old.")
  }
}

// Creating an object using the primary constructor
val person = new Person("Alice", 30)
person.greet()  // Output: Hello, my name is Alice and I am 30 years old.

এখানে name এবং age কনস্ট্রাক্টরের মাধ্যমে ইনপুট নেওয়া হচ্ছে এবং greet() মেথডটি এই ভ্যালুগুলিকে ব্যবহার করছে।

১.২ সহায়ক কনস্ট্রাক্টর (Auxiliary Constructor)

স্কালায় সহায়ক কনস্ট্রাক্টর ফাংশনটি মূল কনস্ট্রাক্টরের বাইরে অতিরিক্ত ইনস্ট্যান্স তৈরি করার জন্য ব্যবহৃত হয়। এটি this কিওয়ার্ড দিয়ে ডিফাইন করা হয়।

উদাহরণ:

class Person(val name: String, val age: Int) {
  // Primary constructor
  def this(name: String) = {
    this(name, 18)  // Calls the primary constructor with a default age of 18
  }

  def greet(): Unit = {
    println(s"Hello, my name is $name and I am $age years old.")
  }
}

// Creating an object using the auxiliary constructor
val person1 = new Person("Bob", 25)
person1.greet()  // Output: Hello, my name is Bob and I am 25 years old.

val person2 = new Person("Charlie")  // Default age will be 18
person2.greet()  // Output: Hello, my name is Charlie and I am 18 years old.

এখানে, সহায়ক কনস্ট্রাক্টর name আর্গুমেন্ট গ্রহণ করে এবং age জন্য একটি ডিফল্ট মান (১৮) অ্যাসাইন করে।


২. ওভারলোডিং (Overloading)

ওভারলোডিং হল একাধিক মেথড বা কনস্ট্রাক্টরের একই নাম দিয়ে ভিন্ন ভিন্ন প্যারামিটার সিগনেচার (সংখ্যা বা টাইপ) ব্যবহার করা। এটি স্কালায় সাধারণভাবে মেথড ওভারলোডিং এবং কনস্ট্রাক্টর ওভারলোডিং হিসাবে দেখা যায়।

২.১ মেথড ওভারলোডিং (Method Overloading)

মেথড ওভারলোডিং হল এক বা একাধিক মেথডের একটি নামের মধ্যে ভিন্ন ভিন্ন প্যারামিটার সিগনেচার ব্যবহার করা। একই নামের মেথডের বিভিন্ন সংস্করণ একই ক্লাসের মধ্যে থাকতে পারে, তবে তাদের আর্গুমেন্টসের সংখ্যা বা টাইপ আলাদা হতে হবে।

উদাহরণ:

class Calculator {
  def add(a: Int, b: Int): Int = {
    a + b
  }

  def add(a: Double, b: Double): Double = {
    a + b
  }
}

val calc = new Calculator
println(calc.add(5, 10))      // Output: 15 (Int addition)
println(calc.add(5.5, 10.2))  // Output: 15.7 (Double addition)

এখানে, add মেথডটি দুটি আলাদা টাইপের প্যারামিটার গ্রহণ করছে: একবার Int এবং অন্যবার Double। তাই এটি মেথড ওভারলোডিং।

২.২ কনস্ট্রাক্টর ওভারলোডিং (Constructor Overloading)

স্কালায় কনস্ট্রাক্টর ওভারলোডিং হল একাধিক কনস্ট্রাক্টর দিয়ে এক বা একাধিক ক্লাসের ইনস্ট্যান্স তৈরি করা, যেখানে কনস্ট্রাক্টরগুলির প্যারামিটার সিগনেচার আলাদা থাকতে পারে।

উদাহরণ:

class Rectangle(val length: Double, val width: Double) {
  // Primary constructor
  def this(length: Double) = {
    this(length, length)  // Creating a square if only one side is provided
  }

  def area(): Double = length * width
}

val rectangle1 = new Rectangle(5, 10)
println(rectangle1.area())  // Output: 50

val square = new Rectangle(4)
println(square.area())  // Output: 16 (Square case, both sides equal)

এখানে, দ্বিতীয় কনস্ট্রাক্টর কেবল একটি মাত্র আর্গুমেন্ট গ্রহণ করে এবং যদি শুধুমাত্র একটি আর্গুমেন্ট প্রদান করা হয় তবে কনস্ট্রাক্টরটি একটি স্কোয়ার তৈরি করবে যেখানে দৈর্ঘ্য এবং প্রস্থ সমান।


সারাংশ

  • কনস্ট্রাক্টর: ক্লাসের ইনস্ট্যান্স তৈরি করার জন্য ব্যবহৃত হয়। স্কালায় প্রধান কনস্ট্রাক্টর (primary constructor) এবং সহায়ক কনস্ট্রাক্টর (auxiliary constructor) দুটো ধরনের কনস্ট্রাক্টর রয়েছে।
  • ওভারলোডিং: স্কালায় মেথড বা কনস্ট্রাক্টরের নাম একই রাখা যায়, তবে তাদের প্যারামিটার সংখ্যা বা টাইপ ভিন্ন থাকতে হবে। এটি মেথড ও কনস্ট্রাক্টর উভয় ক্ষেত্রেই ব্যবহার করা যায়।

কনস্ট্রাক্টর ও ওভারলোডিং স্কালা প্রোগ্রামিংয়ের শক্তিশালী ফিচার, যা কোডের পুনঃব্যবহারযোগ্যতা এবং কার্যকারিতা বাড়ায়।

Content added By

স্কালা প্রোগ্রামিং ভাষায় ইনহেরিটেন্স (Inheritance) এবং পলিমরফিজম (Polymorphism) হল অবজেক্ট-অরিয়েন্টেড প্রোগ্রামিংয়ের দুটি গুরুত্বপূর্ণ ধারণা। এই দুটি বৈশিষ্ট্য কোডের পুনঃব্যবহারযোগ্যতা এবং নমনীয়তা (flexibility) বৃদ্ধি করে।


১. ইনহেরিটেন্স (Inheritance)

ইনহেরিটেন্স হল একটি প্রক্রিয়া যার মাধ্যমে একটি ক্লাস অন্য একটি ক্লাস থেকে বৈশিষ্ট্য (ফিল্ড, মেথড) এবং আচরণ (behaviors) উত্তরাধিকার (inherit) করে। এটি কোড পুনঃব্যবহার এবং সহজেই নতুন বৈশিষ্ট্য সংযোজনের জন্য ব্যবহৃত হয়।

স্কালায়, ক্লাস ইনহেরিট করতে extends কিওয়ার্ড ব্যবহার করা হয়। এটি একটি ক্লাসকে অন্য ক্লাস থেকে উত্তরাধিকার (inherit) করার অনুমতি দেয়।

১.১ ইনহেরিটেন্স উদাহরণ

// Superclass (Parent class)
class Animal {
  def speak(): Unit = {
    println("The animal makes a sound")
  }
}

// Subclass (Child class) inherits from Animal
class Dog extends Animal {
  def speak(): Unit = {
    println("The dog barks")
  }
}

// Main object to test inheritance
object InheritanceExample {
  def main(args: Array[String]): Unit = {
    val dog = new Dog()
    dog.speak()  // Output: The dog barks

    val animal = new Animal()
    animal.speak()  // Output: The animal makes a sound
  }
}

এখানে:

  • Dog ক্লাস Animal ক্লাস থেকে ইনহেরিট করেছে, কিন্তু এটি speak() মেথডটি ওভাররাইড (override) করেছে যাতে ডগের জন্য নির্দিষ্ট আচরণ (বাক) তৈরি করা যায়।
  • Dog ক্লাস Animal ক্লাসের বৈশিষ্ট্যগুলো উত্তরাধিকার হিসেবে পেয়ে থাকে, তবে Dog ক্লাস তার নিজস্ব আচরণ প্রদান করতে পারে।

২. পলিমরফিজম (Polymorphism)

পলিমরফিজম হল একটি ধারণা যার মাধ্যমে একে একাধিক উপায়ে ব্যবহার করা যায়। এটি এক বা একাধিক মেথড বা অপারেশনকে বিভিন্ন ধরনের অবজেক্টের জন্য বিভিন্ন উপায়ে ব্যবহার করতে দেয়।

পলিমরফিজম দুটি ধরনের হতে পারে:

  1. মেথড পলিমরফিজম (Method Polymorphism): একই নামের মেথডের বিভিন্ন বাস্তবায়ন (implementation) থাকতে পারে।
  2. অপারেটর পলিমরফিজম (Operator Polymorphism): একই অপারেটরের জন্য বিভিন্ন আর্গুমেন্টের সাথে কাজ করার ক্ষমতা।

২.১ মেথড পলিমরফিজম (Method Polymorphism)

মেথড পলিমরফিজম হল একই মেথড নামের একাধিক ভার্সন থাকা, যা বিভিন্ন আর্গুমেন্ট গ্রহণ করে বা প্যারামিটার অনুসারে বিভিন্ন আচরণ প্রদর্শন করে।

// Superclass (Parent class)
class Animal {
  def speak(): Unit = {
    println("The animal makes a sound")
  }
}

// Subclass (Child class) inherits from Animal
class Dog extends Animal {
  override def speak(): Unit = {
    println("The dog barks")
  }
}

// Another subclass (Child class)
class Cat extends Animal {
  override def speak(): Unit = {
    println("The cat meows")
  }
}

// Main object to test polymorphism
object PolymorphismExample {
  def main(args: Array[String]): Unit = {
    val dog: Animal = new Dog()  // Dog object as Animal type
    val cat: Animal = new Cat()  // Cat object as Animal type

    dog.speak()  // Output: The dog barks
    cat.speak()  // Output: The cat meows
  }
}

এখানে:

  • Dog এবং Cat ক্লাস দুটি speak() মেথডটি ওভাররাইড (override) করেছে।
  • Dog এবং Cat অবজেক্টগুলি Animal টাইপের হয়ে থাকা সত্ত্বেও, তারা তাদের নিজস্ব আচরণ প্রদর্শন করে।

২.২ অপারেটর পলিমরফিজম (Operator Polymorphism)

স্কালায় অপারেটর পলিমরফিজমের মাধ্যমে একই অপারেটরের বিভিন্ন প্রকার ব্যবহার করা যায়। এটি সাধারণত কাস্টম অপারেটর ডিফাইন করার জন্য ব্যবহৃত হয়।

class Complex(val real: Double, val imaginary: Double) {
  def +(that: Complex): Complex = {
    new Complex(this.real + that.real, this.imaginary + that.imaginary)
  }

  def display(): Unit = {
    println(s"${real} + ${imaginary}i")
  }
}

object OperatorPolymorphismExample {
  def main(args: Array[String]): Unit = {
    val complex1 = new Complex(3.0, 4.0)
    val complex2 = new Complex(1.0, 2.0)

    val result = complex1 + complex2  // Using the overloaded + operator
    result.display()  // Output: 4.0 + 6.0i
  }
}

এখানে:

  • + অপারেটরকে কাস্টমাইজ করা হয়েছে যাতে এটি দুটি Complex অবজেক্টকে যোগ করতে পারে।

৩. এবস্ট্রাকশন (Abstraction) এবং ইনহেরিটেন্স

এবস্ট্রাকশন এবং ইনহেরিটেন্স একে অপরের সাথে সম্পর্কিত। স্কালায় abstract class এবং trait এর মাধ্যমে আপনি অবজেক্ট-অরিয়েন্টেড প্রোগ্রামিংয়ের এবস্ট্রাকশন ব্যবহার করতে পারেন।

৩.১ এবস্ট্রাক্ট ক্লাস (Abstract Class)

abstract class Animal {
  def sound(): Unit  // Abstract method without implementation
}

class Dog extends Animal {
  def sound(): Unit = {
    println("Bark")
  }
}

object AbstractClassExample {
  def main(args: Array[String]): Unit = {
    val dog = new Dog()
    dog.sound()  // Output: Bark
  }
}

এখানে:

  • Animal ক্লাস একটি abstract ক্লাস, যেখানে sound() মেথডটি অ্যাবস্ট্রাক্ট (অমীমাংসিত) হিসেবে ডিফাইন করা হয়েছে।
  • Dog ক্লাসে sound() মেথডের বাস্তবায়ন (implementation) দেওয়া হয়েছে।

সারাংশ

  • ইনহেরিটেন্স হল একটি ক্লাসের বৈশিষ্ট্য এবং আচরণ অন্য ক্লাস দ্বারা উত্তরাধিকার (inherit) করার প্রক্রিয়া।
  • পলিমরফিজম হল একই নামের মেথডের বিভিন্ন বাস্তবায়ন (overloading বা overriding) বা অপারেটরের বিভিন্ন ব্যবহারের ক্ষমতা।

এগুলি স্কালায় কোডের পুনঃব্যবহারযোগ্যতা, নমনীয়তা এবং কার্যকারিতা বাড়াতে সহায়ক।

Content added By

ট্রেইট (Trait) এবং মিক্সইন (Mixin) স্কালার দুটি গুরুত্বপূর্ণ বৈশিষ্ট্য, যা অবজেক্ট-অরিয়েন্টেড প্রোগ্রামিং (OOP) এবং ফাংশনাল প্রোগ্রামিং (FP) এর মধ্যে একটি শক্তিশালী সমন্বয় তৈরি করতে ব্যবহৃত হয়। স্কালায় ট্রেইট এবং মিক্সইন ব্যবহারের মাধ্যমে কোডের পুনঃব্যবহারযোগ্যতা এবং নমনীয়তা বাড়ানো যায়।


১. ট্রেইট (Traits)

ট্রেইট হল এমন একটি ধরনের ক্লাস যা একাধিক ক্লাসের মধ্যে পুনঃব্যবহারযোগ্য কোড শেয়ার করার জন্য ব্যবহৃত হয়। ট্রেইটের মধ্যে আপনি ফাংশন এবং ভ্যারিয়েবল ডিফাইন করতে পারেন, এবং ট্রেইটগুলোকে মিশ্রিত (mix) করতে পারেন বিভিন্ন ক্লাসের মধ্যে।

ট্রেইটগুলো মূলত এক ধরনের ইন্টারফেস-এর মতো কাজ করে, কিন্তু এগুলো ক্লাসের মতো কিছু ফাংশনালিটি এবং বাস্তবায়নও সরবরাহ করতে পারে।

ট্রেইট তৈরি করা

trait Animal {
  def sound: String  // Abstract method
  def move(): Unit = {  // Concrete method
    println("Moving around...")
  }
}

class Dog extends Animal {
  def sound: String = "Woof"
}

class Cat extends Animal {
  def sound: String = "Meow"
}

object Main extends App {
  val dog = new Dog
  val cat = new Cat
  println(dog.sound)  // Output: Woof
  dog.move()          // Output: Moving around...
  println(cat.sound)  // Output: Meow
  cat.move()          // Output: Moving around...
}

এখানে:

  • trait Animal: এটি একটি ট্রেইট যার মধ্যে একটি abstract method sound এবং একটি concrete method move আছে।
  • Dog এবং Cat ক্লাস: এই দুটি ক্লাস Animal ট্রেইট থেকে inherit করে এবং sound মেথডটি বাস্তবায়ন করে।

ট্রেইট এর সুবিধা:

  • ক্লাসের মধ্যে কোড পুনঃব্যবহার: ট্রেইট কোডের পুনঃব্যবহারযোগ্য অংশ হিসেবে কাজ করে, যাতে আপনি একাধিক ক্লাসে কমন ফাংশনালিটি শেয়ার করতে পারেন।
  • ফাংশনাল এবং অবজেক্ট-অরিয়েন্টেড প্রোগ্রামিংয়ের সমন্বয়: স্কালায় ট্রেইট ফাংশনাল এবং অবজেক্ট-অরিয়েন্টেড প্রোগ্রামিংয়ের শক্তিশালী সমন্বয় ঘটায়।

২. মিক্সইন (Mixins)

মিক্সইন হলো একটি স্কালা ফিচার, যার মাধ্যমে একটি ক্লাস বা অবজেক্ট একাধিক ট্রেইটের মধ্যে ফাংশনালিটি শেয়ার করতে পারে। মিক্সইন এইভাবে কোডের পুনঃব্যবহারযোগ্যতা বৃদ্ধি করে, কারণ একাধিক ট্রেইট একসাথে মিশ্রিত করা যায় এবং বিভিন্ন ক্লাসে প্রয়োগ করা যায়।

স্কালায় মিক্সইন করার জন্য with কিওয়ার্ড ব্যবহার করা হয়।

মিক্সইন উদাহরণ

trait Animal {
  def sound: String
}

trait Movable {
  def move(): Unit = println("Moving around...")
}

class Dog extends Animal with Movable {
  def sound: String = "Woof"
}

class Cat extends Animal with Movable {
  def sound: String = "Meow"
}

object Main extends App {
  val dog = new Dog
  println(dog.sound)  // Output: Woof
  dog.move()          // Output: Moving around...

  val cat = new Cat
  println(cat.sound)  // Output: Meow
  cat.move()          // Output: Moving around...
}

এখানে:

  • Movable ট্রেইটটি Dog এবং Cat ক্লাসের সাথে মিক্সইন করা হয়েছে, যাতে এই দুটি ক্লাস move মেথডটি ব্যবহার করতে পারে।
  • with কিওয়ার্ড ব্যবহার করে Dog এবং Cat ক্লাসে ট্রেইটগুলো মিক্স করা হয়েছে।

মিক্সইন এর সুবিধা:

  • বহু ট্রেইট মিশ্রণ: আপনি একাধিক ট্রেইট একসাথে মিক্স করতে পারেন, যা কোডের পুনঃব্যবহারযোগ্যতা এবং নমনীয়তা বাড়ায়।
  • প্রতিটি ক্লাসে আলাদা ফাংশনালিটি: মিক্সইন ব্যবহারের মাধ্যমে ক্লাসগুলোতে আলাদা আলাদা ফাংশনালিটি মিশ্রিত করা যায়, যা কোডের গঠন আরও ভালো করে।

৩. ট্রেইট এবং মিক্সইনের পার্থক্য

বৈশিষ্ট্যট্রেইট (Trait)মিক্সইন (Mixin)
সংজ্ঞায়নএকাধিক ক্লাসের মধ্যে কোড শেয়ার করার জন্য ট্রেইট ব্যবহার করা হয়।মিক্সইন, একাধিক ট্রেইট একসাথে একটি ক্লাসে শেয়ার করা হয়।
ফাংশনালিটিট্রেইট নিজেই কিছু ফাংশনালিটি বা abstract মেথড প্রদান করে।মিক্সইন হলো একাধিক ট্রেইটের ফাংশনালিটির মিশ্রণ।
ব্যবহারট্রেইট ক্লাস বা অবজেক্টে ব্যবহৃত হয় এবং সেই ক্লাসে কোড পুনঃব্যবহারযোগ্য করতে সাহায্য করে।মিক্সইন একাধিক ট্রেইটকে একত্রে ব্যবহার করার জন্য ব্যবহৃত হয়।

৪. একাধিক ট্রেইট মিশ্রণ (Multiple Trait Mixing)

স্কালায় আপনি একাধিক ট্রেইট একসাথে মিশ্রিত করতে পারেন। যদি বিভিন্ন ট্রেইটের মধ্যে কিছু সাধারণ ফাংশন বা প্রোপার্টি থাকে, তবে এগুলি মিশ্রিত করে আরও শক্তিশালী ফাংশনালিটি তৈরি করা যায়।

উদাহরণ:

trait Animal {
  def sound: String
}

trait Movable {
  def move(): Unit = println("Moving around...")
}

trait Swimmable {
  def swim(): Unit = println("Swimming...")
}

class Dog extends Animal with Movable {
  def sound: String = "Woof"
}

class Fish extends Animal with Swimmable {
  def sound: String = "Blub"
}

object Main extends App {
  val dog = new Dog
  dog.move()  // Output: Moving around...

  val fish = new Fish
  fish.swim()  // Output: Swimming...
}

এখানে:

  • Dog ক্লাসে Movable ট্রেইট মিক্সইন করা হয়েছে।
  • Fish ক্লাসে Swimmable ট্রেইট মিক্সইন করা হয়েছে।

সারাংশ

  • ট্রেইট (Trait) হল একটি অবজেক্ট-অরিয়েন্টেড কনসেপ্ট যা কোডের পুনঃব্যবহারযোগ্যতা বাড়ানোর জন্য ব্যবহৃত হয় এবং একাধিক ক্লাসে শেয়ার করা যায়।
  • মিক্সইন (Mixin) হল ট্রেইটগুলির সমন্বয়, যেখানে একাধিক ট্রেইট একসাথে কোনো ক্লাসে যুক্ত করা হয়।
  • স্কালায় ট্রেইট এবং মিক্সইন ব্যবহারের মাধ্যমে কোডের পুনঃব্যবহারযোগ্যতা, নমনীয়তা, এবং কার্যকারিতা বৃদ্ধি পায়।

এ দুটি বৈশিষ্ট্য স্কালার কোডকে আরও পরিষ্কার, শক্তিশালী এবং পুনঃব্যবহারযোগ্য করে তোলে।

Content added By

অ্যাবস্ট্রাক্ট ক্লাস এবং ফাইনাল কিওয়ার্ড স্কালা প্রোগ্রামিং ভাষার গুরুত্বপূর্ণ বৈশিষ্ট্য। এগুলি ক্লাসের বিশেষ বৈশিষ্ট্য এবং ইনহেরিটেন্স (Inheritance) সম্পর্কিত বিভিন্ন কনসেপ্টের সঙ্গে সম্পর্কিত। এখানে স্কালার অ্যাবস্ট্রাক্ট ক্লাস এবং ফাইনাল কিওয়ার্ডের ব্যবহার এবং উদাহরণ আলোচনা করা হলো।


১. অ্যাবস্ট্রাক্ট ক্লাস (Abstract Class)

অ্যাবস্ট্রাক্ট ক্লাস এমন একটি ক্লাস যা সম্পূর্ণভাবে বাস্তবায়িত (implemented) না হয়ে কিছু অংশ অনির্দিষ্ট (abstract) রেখে দেয়, এবং এই ক্লাসটি সরাসরি ইনস্ট্যান্স (instance) তৈরি করা যায় না। অ্যাবস্ট্রাক্ট ক্লাসকে অন্য ক্লাস দ্বারা সম্প্রসারিত (extend) করা হয় এবং সেখানে এর অনির্দিষ্ট মেথডগুলির বাস্তবায়ন প্রদান করা হয়।

অ্যাবস্ট্রাক্ট ক্লাস ডিফাইন করা:

// অ্যাবস্ট্রাক্ট ক্লাস
abstract class Animal {
  // একটি abstract মেথড (এটি কোন কোড রিটার্ন করে না)
  def sound(): String

  // একটি সাধারণ মেথড
  def sleep(): String = {
    "Sleeping..."
  }
}

// অ্যাবস্ট্রাক্ট ক্লাস ইনহেরিট করে বাস্তব ক্লাস
class Dog extends Animal {
  // abstract মেথডের বাস্তবায়ন
  def sound(): String = {
    "Bark"
  }
}

object AbstractClassExample {
  def main(args: Array[String]): Unit = {
    val dog = new Dog()
    println(dog.sound())  // Output: Bark
    println(dog.sleep())  // Output: Sleeping...
  }
}

এখানে:

  • abstract class: Animal একটি অ্যাবস্ট্রাক্ট ক্লাস, যার মধ্যে একটি abstract মেথড sound() রয়েছে।
  • abstract method: sound() মেথডের কোনও বাস্তবায়ন নেই, এটি কেবল ক্লাসের উপরে ডিফাইন করা হয়েছে।
  • real class: Dog ক্লাস Animal ক্লাসের উপরে ইনহেরিট করে এবং sound() মেথডের বাস্তবায়ন প্রদান করেছে।

২. ফাইনাল কিওয়ার্ড (Final Keyword)

ফাইনাল কিওয়ার্ড ব্যবহৃত হয় ক্লাস, মেথড বা ভ্যারিয়েবলগুলিতে, যার মাধ্যমে সেই ক্লাস, মেথড বা ভ্যারিয়েবলটি পরিবর্তন বা ইনহেরিট করা যাবে না।

২.১ ফাইনাল ক্লাস

যখন একটি ক্লাসে final কিওয়ার্ড ব্যবহার করা হয়, তখন সে ক্লাসটি অন্য কোন ক্লাস দ্বারা ইনহেরিট (extend) করা যাবে না। অর্থাৎ, সেই ক্লাসটি ফাইনাল হয়ে যায়।

final class Car {
  def start(): Unit = {
    println("Car started!")
  }
}

// এই কোডটি কম্পাইল হবে না, কারণ Car ক্লাসটি ফাইনাল
// class ElectricCar extends Car { }  // Error: Cannot extend final class

এখানে:

  • Car ক্লাসে final কিওয়ার্ড দেওয়া হয়েছে, ফলে এটি আর কোনো ক্লাস দ্বারা ইনহেরিট করা যাবে না।

২.২ ফাইনাল মেথড

যদি একটি মেথডে final কিওয়ার্ড ব্যবহার করা হয়, তাহলে সেই মেথডটি ওভাররাইড (override) করা যাবে না।

class Vehicle {
  final def move(): Unit = {
    println("Vehicle is moving")
  }
}

class Car extends Vehicle {
  // এই কোডটি কম্পাইল হবে না, কারণ move() মেথডটি ফাইনাল
  // override def move(): Unit = {
  //   println("Car is moving")
  // }
}

এখানে:

  • move() মেথডে final কিওয়ার্ড ব্যবহৃত হয়েছে, যার কারণে এটি override করা যাবে না।

২.৩ ফাইনাল ভ্যারিয়েবল

ফাইনাল ভ্যারিয়েবল এমন একটি ভ্যারিয়েবল, যার মান একবার অ্যাসাইন করার পর তা আর পরিবর্তন করা যায় না।

object FinalVariableExample {
  final val maxSpeed = 120

  def main(args: Array[String]): Unit = {
    // maxSpeed = 130  // Error: reassignment to val
    println(s"Max Speed: $maxSpeed")
  }
}

এখানে:

  • maxSpeed একটি ফাইনাল ভ্যারিয়েবল, যার মান একবার নির্ধারণ করার পর তা আর পরিবর্তন করা যাবে না।

সারাংশ

  • অ্যাবস্ট্রাক্ট ক্লাস: এটি এমন একটি ক্লাস যা সম্পূর্ণভাবে বাস্তবায়িত না হয়ে কিছু অংশ অনির্দিষ্ট রেখে দেয় এবং এটি সরাসরি ইনস্ট্যান্স তৈরি করতে পারে না। এটি ইনহেরিট করে অন্যান্য ক্লাসে তার অনির্দিষ্ট অংশগুলোর বাস্তবায়ন করা হয়।
  • ফাইনাল কিওয়ার্ড:
    • ফাইনাল ক্লাস: এটি এমন একটি ক্লাস যা অন্য কোন ক্লাস দ্বারা ইনহেরিট করা যাবে না।
    • ফাইনাল মেথড: এটি এমন একটি মেথড যা ওভাররাইড করা যাবে না।
    • ফাইনাল ভ্যারিয়েবল: এটি এমন একটি ভ্যারিয়েবল যার মান একবার অ্যাসাইন করার পর তা আর পরিবর্তন করা যায় না।

এগুলি স্কালার ইনহেরিটেন্স, ক্লাস, এবং অবজেক্ট মডেলিংয়ে গুরুত্বপূর্ণ ভূমিকা পালন করে এবং কোডকে আরো সুরক্ষিত ও কার্যকরী করে তোলে।

Content added By
Promotion

Are you sure to start over?

Loading...