পিএইচপি ইনহেরিটেন্স
অবজেক্ট অরিয়েন্টেড পিএইচপির আরো একটি বড় সুবিধা হলো কোড ইনহেরিটেন্স(inheritance)। অর্থাৎ একটি ক্লাস তার উত্তরাধিকার বা চাইল্ড ক্লাস এর সাথে কোড ডুপ্লিকেশনের ক্ষমতা রাখে।
উদাহরণস্বরূপঃ সন্তান যেমন পিতা-মাতার সম্পত্তির মালিক হয়। আরো সহজ করে বললেঃ সন্তান যেমন পিতা-মাতার সম্পত্তি ব্যবহার করতে পারে ঠিক তেমনি একটি চাইল্ড ক্লাস তার প্যারেন্ট ক্লাসের সকল প্রোপার্টি এবং মেথড সমুহকে অ্যাক্সেস করতে পারে। এক্ষেত্রে আমরা প্যারেন্ট ক্লাসে কোড গুলো একবার লিখে চাইল্ড ক্লাস থেকে যতবার ইচ্ছা ব্যবহার করতে পারি। এটি প্রোগ্রামের মডুলারিটি(modularity) অনেক বাড়িয়ে দেয়।
চাইল্ড ক্লাস তৈরি
আমরা কোনো কোড প্যারেন্ট ক্লাসে একবার লিখে ইনহেরিটেন্স(inheritance) ব্যবহার করে ঐ কোডকে প্যারেন্ট এবং চাইল্ড উভই ক্লাস থেকেই ব্যবহার করতে পারবো।
একটি প্যারেন্ট ক্লাসের চাইল্ড ক্লাস তৈরি করার জন্য extends
কীওয়ার্ড ব্যবহার করা হয়।
চাইল্ড ক্লাস তৈরির সিনট্যাক্স
নিম্নে চাইল্ড ক্লাস তৈরির সিনট্যাক্স দেখানো হলোঃ<?php
class Parent{
// Parent ক্লাসের কোড গুলো এখানে থাকবে।
}
class Child extends Parent{
// Parent ক্লাসের কোড গুলো এখান থেকে ব্যবহার করা যাবে।
}
?>
একটি চাইল্ড ক্লাস তার প্যারেন্ট ক্লাসের সকল non-private মেথড এবং প্রোপার্টিসমূহ অ্যাক্সেস করতে পারে।
<?php
class Greeting{
private $name;
public function __construct($name){
$this->name = $name;
}
public function getHello(){
echo "Hello ". $this->name . ".";
}
}
// প্যারেন্ট ক্লাসের চাইল্ড ক্লাস তৈরি
class Hello extends Greeting{
// Greeting ক্লাসের কোড গুলো এখান থেকে ব্যবহার করা যাবে
}
$hello = new Hello("Tamjid");
$hello->getHello();
?>
Hello Tamjid.
উদাহরণের ব্যাখ্যা
বিঃদ্রঃ Greeting ক্লাসের private ব্যাতিত সকল মেথড এবং প্রোপার্টিসমূহ Hello ক্লাসের মাধ্যমে ব্যবহার করা যাবে। __construct() এবং getHello() মেথড এর স্কোপ পাবলিক হওয়ায় প্যারেন্ট ক্লাসে থাকা সত্ত্বেও প্যারেন্ট এবং চাইল্ড উভয় ক্লাস থেকেই অ্যাক্সেস করা যাবে।
চাইল্ড ক্লাসের নিজস্ব প্রোপার্টি এবং মেথড
একটি চাইল্ড ক্লাস যে শুধুমাত্র প্যারেন্ট ক্লাসের প্রোপার্টি এবং মেথড ব্যবহার করে তা নয়। বরং একটি চাইল্ড ক্লাসেরও কিছু নিজস্ব প্রোপার্টি এবং মেথড থাকতে পারে। একটি চাইল্ড ক্লাস প্যারেন্ট ক্লাসের সকল প্রোপার্টি এবং মেথড ব্যবহার করতে পারলেও প্যারেন্ট ক্লাস কখনোই চাইল্ড ক্লাসের প্রোপার্টি এবং মেথড ব্যবহার করতে পারে না।
নিম্নের উদাহরণে আমরা চাইল্ড ক্লাসের মধ্যে একটি প্রোপার্টি এবং একটি মেথড ডিফাইন করবোঃ
<?php
class Greeting{
private $name;
public function __construct($name){
$this->name = $name;
}
public function getHello(){
echo "Hello ". $this->name . ". ";
}
}
class Hello extends Greeting{
private $message = "How's your day!";
public function welcomeMsg(){
echo $this->getHello() . $this->message;
}
}
$hello = new Hello("Tamjid");
$hello->welcomeMsg();
?>
Hello Tamjid. How's your day!
protected অ্যাক্সেস মডিফায়ার
আমরা যেকোনো প্রোপার্টি অথবা মেথডকে protected ঘোষনা করতে পারি। এই পদ্ধতি অবলম্বন করে আমরা প্যারেন্ট ক্লাসের প্রোপার্টি এবং মেথডসমূহকে প্যারেন্ট এবং চাইল্ড উভয় ক্লাস থেকেই অ্যাক্সেস করতে পারি।
পূর্ববর্তী অধ্যায়ে আমরা দেখেছিলাম, public কীওয়ার্ড ব্যবহার করে কিভাবে প্রোপার্টি এবং মেথড সমুহকে ক্লাসের ভিতরে এবং বাইরে থেকে অ্যাক্সেস করা যায় এবং private কীওয়ার্ড ব্যবহার করে কিভাবে ক্লাসের অভন্তরেই প্রোপার্টি এবং মেথডসমুহকে অ্যাক্সেস করতে হয়।
এই টিউটোরিয়ালে আমরা তৃতীয় একটি মডিফায়ার অর্থাৎ protected মডিফায়ার সম্পর্কে জানবো। যা প্যারেন্ট এবং চাইল্ড উভয় ক্লাসের মধ্যে অ্যাক্সেস যোগ্য। কিন্তু ক্লাসের বাইরে থেকে এটিকে অ্যাক্সেস করা সম্ভব নয়।
উপরের উদাহরণে আমরা $name প্রোপার্টিকে private ডিক্লেয়ার করেছিলাম। চলুন দেখাযাক, এই প্রোপার্টিকে চাইল্ড ক্লাস থেকে অ্যাক্সেস করলে কি ঘটেঃ
<?php
class Greeting{
private $name;
public function __construct($name){
$this->name = $name;
}
}
class Hello extends Greeting{
public function getHello(){
echo "Hello ". $this->name . ". ";
}
}
$hello = new Hello("Tamjid");
$hello->getHello();
?>
Notice: Undefined property: Hello::$name
আমরা একটি error এর সম্মুখীন হলাম। কারণ $name একটি private প্রোপার্টি। তাই আমরা এটিকে চাইল্ড ক্লাস থেকে অ্যাক্সেস করতে পারবো না।
এই সমস্যাটি সমাধান করতে আমরা protected কীওয়ার্ড ব্যবহার করবো।
<?php
class Greeting{
protected $name;
public function __construct($name){
$this->name = $name;
}
}
class Hello extends Greeting{
public function getHello(){
echo "Hello ". $this->name . ".";
}
}
$hello = new Hello("Tamjid");
$hello->getHello();
?>
Hello Tamjid.
এইবার এটি ঠিকমত কাজ করেছে। কারণ, প্যারেন্ট ক্লাসের protected প্রোপার্টি চাইল্ড ক্লাস থেকেও অ্যাক্সেস করা যায়।
চাইল্ড ক্লাস থেকে প্যারেন্ট ক্লাসের প্রোপার্টি এবং মেথড ওভার-রাইড
যে পদ্ধতিতে চাইল্ড ক্লাসের নিজস্ব প্রোপার্টি বা মেথডসমূহ ঘোষণা(declare) করা হয় ঠিক একই পদ্ধতিতে চাইল্ড ক্লাস থেকে প্যারেন্ট ক্লাসের প্রোপার্টি বা মেথডসমুহকে ওভার-রাইড করা হয়। প্যারেন্ট ক্লাসে ডিফাইনকৃত মেথড বা প্রোপার্টিকে চাইল্ড ক্লাসে ভিন্ন মান দ্বারা পূনরায় ডিফাইন করলেই এগুলো ওভার-রাইড(Override) হয়ে যাবে।
নিম্নের উদাহরণে আমরা প্যারেন্ট ক্লাসের getHello() মেথডকে চাইল্ড ক্লাসে ওভার-রাইড করবোঃ
<?php
class Greeting{
protected $name;
public function __construct($name){
$this->name = $name;
}
public function getHello(){
echo "Hello ". $this->name . ".";
}
}
class Hello extends Greeting{
public function getHello(){
echo "Welcome ". $this->name . ".";
}
}
$hello = new Hello("Tamjid");
$hello->getHello();
?>
Welcome Tamjid.
ফলাফল পরিবর্তন হয়ে গেছে। সুতরাং প্যারেন্ট ক্লাসের getHello() মেথডটি চাইল্ড ক্লাসে পরিবর্তন হয়ে গেছে।
চাইল্ড ক্লাসে প্যারেন্ট ক্লাসের প্রোপার্টি এবং মেথড ওভার-রাইড প্রতিরোধ
আমরা প্যারেন্ট ক্লাসের private ব্যাতিত সকল মেথড এবং প্রোপার্টিকে চাইল্ড ক্লাস থেকে অ্যাক্সেস এবং ওভার-রাইড(Override) বা পরিবর্তন করতে পারি। কিন্তু কিছু কিছু ক্ষেত্রে আপনি নিশ্চয় চাইবেন যেন প্যারেন্ট ক্লাসে তৈরি মেথড বা প্রোপার্টিসমূহকে এর চাইল্ড ক্লাস থেকে ওভার-রাইড করতে না পারে।
এটা সমাধানের জন্য আপনার প্যারেন্ট ক্লাসে ডিফাইনকৃত public বা protected মেথড এবং প্রোপার্টিসমুহের পূর্বে final কীওয়ার্ড যুক্ত করে দিন। যে সকল প্রোপার্টি বা মেথডের পূর্বে final কীওয়ার্ড থাকবে সেগুলোকে চাইল্ড ক্লাস থেকে আর ওভার-রাইড করা যাবে না।
নিম্নের উদাহরণে আমরা প্যারেন্ট ক্লাসের getHello() মেথডের পূর্বে final কীওয়ার্ড ব্যবহার করবোঃ
<?php
class Greeting{
protected $name;
public function __construct($name){
$this->name = $name;
}
final public function getHello(){
echo "Hello ". $this->name . ".";
}
}
class Hello extends Greeting{
public function getHello(){
echo "Welcome ". $this->name . ".";
}
}
$hello = new Hello("Tamjid");
$hello->getHello();
?>
Fatal error: Cannot override final method Greeting::getHello()
প্যারেন্ট ক্লাসের getHello() মেথডের পূর্বে final কীওয়ার্ড ব্যবহার করায় এটি চাইল্ড ক্লাস থেকে ওভার-রাইড করা সম্ভব হয়নি এবং একটি error এর সম্মুখীন হতে হয়েছে।