পিএইচপি OOP ইন্টাফেসের জন্য টাইপ হিন্টিং
ইন্টারফেস প্রোগ্রামিং কে অধিক সহজ এবং পরিবর্তনযোগ্য করে তোলে। একই ধরনের একাধিক ক্লাসে টাইপ হিন্টিং নিয়ে কাজ করার সময় ইন্টারফেস টাইপ হিন্টিং ব্যবহার করা উচিত।
অবজেক্টের জন্য টাইপ হিন্টিং যথেষ্ট নাও হতে পারে?
এখন আমরা Toyota নামে একটি ক্লাস তৈরি করবো যাতে Toyota ট্রাকের লাইসেন্স নাম্বার এবং মডেল নাম্বার থাকবে। এছাড়া এই ক্লাসের একটি গুরুত্বপূর্ণ মেথডও থাকবে যা তৈলের টাংকি তৈলের পরিমান নির্ণয় করবে।
সুতরাং আমরা calcTankVolume
নামের ফাংশনটি ব্যবহার করবো। এই মেথডটি টাংকির প্রস্থ(base)
এবং উচ্চতার উপর নির্ভর করে টাংকি তৈলের পরিমান নির্ণয় করবে। এছাড়া কন্সট্রাকটর মেথডে উচ্চতা, প্রস্থ এবং লাইসেন্স প্লেট নাম্বার নির্ধারন করে দিবঃ
<?php
class Toyota {
protected $model;
protected $rib;
protected $height;
// কন্সকন্সট্রাকটর মেথডে উচ্চতা, বেস এবং লাইসেন্স প্লেট নাম্বারের মান নির্ধারন
public function __construct($model, $rib, $height) {
$this->model = $model;
$this->rib = $rib;
$this->height = $height;
}
// চর্তুভূজ আকৃতির টাংকির মান নির্ণয়
public function calcTankVolume() {
return $this->rib * $this->rib * $this->height;
}
}
?>
এখন আমরা ক্লাসের বাইরে এমন একটি ফাংশন তৈরি করবো যা সম্পূর্ণ টাংকির তৈলের দাম নির্ণয় করবে। আমার চাই এই ফাংশনে ব্যবহৃত আর্গুমেন্টগুলো Toyota
ক্লাসের অর্ন্তরভুক্ত হোক। আর এটা করার জন্যই আমরা টাইপ হিটিং ব্যবহার করবোঃ
// টাইপ হিন্টিং এটা নিশ্চিত করে যে, ফাংশনটি শুধুমাত্র Toyota ক্লাসের আর্গুমেন্ট গ্রহন করবে।
function calcTankPrice(Toyota $toyota, $pricePerLiter) {
return "$" . $toyota->calcTankVolume() * 0.0035990 * $pricePerLiter;
}
এখন আপনি খুব সহজেই সম্পূর্ণ টাংকির তৈলের দাম নির্ণয় করতে পারেন। উদাহরণস্বরূপঃ ট্রাকের প্লেট নাম্বার 512379, বেসের দৈর্ঘ্য 10", উচ্চতা 15" এবং তৈলের দাম প্রতি লিটার $5। এখন আমরা তৈলের টাংকির দাম নির্ণয় করবোঃ
$toyota1 = new Toyota('512379', 10, 15);
echo calcTankPrice($toyota1, 5);
উপরের সবগুলো কোড একসাথে করে রান করানোর পরে নিম্নের ফলাফল পাওয়া যাবে।
$26.9925
ইন্টাফেস টাইপ হিন্টিং
আমরা একই ধরনের একাধিক ক্লাসে টাইপ হিন্টিং নিয়ে কাজ করার সময় ইন্টারফেস টাইপ হিন্টিং ব্যবহার করবো।
আমরা একটু আগে Toyota
নামে একটি ক্লাস তৈরি করেছি যা Toyota ট্রাকের সম্পূর্ণ টাংকির তৈলের দাম নির্ণয় করে। কিন্তু এখন আমরা Mahindra ট্রাকের সম্পূর্ণ টাংকির তৈলের দাম নির্ণয় করবো। কারণ Toyota ট্রাকের টাংকির আকৃতি এবং Mahindra ট্রাকের টাংকির আকৃতি এক নয়। Mahindra ট্রাকের টাংকির আকৃতি গোলাকার বিধায় এর জন্য নিম্নের ক্লাসটি ব্যবহার করবোঃ
<?php
class Mahindra {
protected $model;
protected $radius;
protected $height;
// কন্সট্রাকটর মেথডে উচ্চতা, ব্যাসার্ধ্য এবং লাইসেন্স প্লেট নাম্বারের মান নির্ধারন
public function __construct($model, $radius, $height) {
$this->model = $model;
$this->radius = $radius;
$this->height = $height;
}
// গোলাকার আকৃতির টাংকির মান নির্ণয়
public function calcTankVolume() {
return $this->radius * $this->radius * pi() * $this->height;
}
}
?>
যেহেতু আমাদের Mahindra
ক্লাসটি লেখা সম্পন্ন হয়েছে, এখন আমরা Mahindra ট্র্যাকের সম্পূর্ণ টাংকির তৈলের দাম নির্ণয় করার চেষ্টা করবোঃ
$mahindra1 = new Mahindra('965742', 9, 20);
echo calcTankPrice($mahindra1, 5);
এইক্ষেত্রে আমরা যেই ধরনের ফলাফল আশা করেছিলাম তা পাবো নাঃ
Catchable fatal error: Argument 1 passed to calcTankPrice()
must be an instance of Toyota, instance of Mahindra given
এই ত্রুটি পাওয়ার কারণ হচ্ছে আমরা সঠিক অবজেক্ট পাস করায় নি। আমাদের calcTankPrice()
ফাংশনটি শুধুমাত্র Toyota ক্লাসের অন্তরভূক্ত অবজেক্ট গুলো গ্রহন করবে। কিন্তু আমরা Mahindra ক্লাসের অবজেক্ট পাস(pass) করানোর ফলে এই ত্রুটির সম্মুখীন হয়েছি।
এই সমস্যা সমাধান করার জন্য আমরা টাইপ হিন্টিং ব্যবহার করবো না। বরং আমরা এর চেয়ে আরও ভালো সমাধান হিসাবে ইন্টাফেসের জন্য টাইপ হিন্টিং ব্যবহার করবো। আর এটা করার জন্য আমরা abstract class এবং real interface একত্রে ব্যবহার করবো।
এখন আমরা Truck নামে একটি abstract class তৈরি করবো যা থেকে Toyota এবং Mahimdra উভয় ক্লাসকে ইনহেরিট(inherit) করবোঃ
abstract class Truck {
protected $model;
protected $height;
abstract public function calcTankVolume();
}
এখন আমরা Toyota এবং Mahimdra উভয় ক্লাসকে পুনরায় লিখবো যেন এরা উভইয়েই Truck ক্লাস থেকে ইনহেরিট(inherit) হয়ঃ
class Toyota extends Truck {
protected $rib;
public function __construct($model, $rib, $height) {
$this->model = $model;
$this->rib = $rib;
$this->height = $height;
}
// চর্তুভূজ আকৃতির টাংকির মান নির্ণয়
public function calcTankVolume() {
return $this->rib * $this->rib * $this->height;
}
}
class Mahindra extends Truck {
protected $radius;
public function __construct($model, $radius, $height) {
$this->model = $model;
$this->radius = $radius;
$this->height = $height;
}
// গোলাকৃতি টাংকির মান নির্ণয়
public function calcTankVolume() {
return $this->radius * $this->radius * pi() * $this->height;
}
}
যেহেতু উভয় ক্লাসই একই ইন্টারফেস থেকে ইনহেরিট(inherit) হয়েছে, তাই আমরা calcTankPrice()
ফাংশনে Truck ইন্টারফেসটি টাইপ হিন্টিং হিসাবে ব্যবহার করবো। সুতরাং এই ইন্টারফেসটির অন্তর্গত অবজেক্টসমুহ এই ফাংশন দ্বারা অ্যাক্সেস করা সম্ভবঃ
// টাইপ হিন্টিং এটি নিশ্চিত করে যে, এই ফাংশনটি শুধুমাত্র অবজেক্ট গ্রহন করবে
//এবং অবজেক্টগুলোকে Truck ইন্টারফেসের অন্তরভুক্ত হতে হবে
function calcTankPrice(Truck $truck, $pricePerLiter) {
return "$" . $truck->calcTankVolume() * 0.0035990 * $pricePerLiter;
}
এখন আমরা calcTankPrice()
ফাংশনটি ব্যবহার করে Toyota এবং Mahimdra উভয় অবজেক্টের ফলাফল দেখবোঃ
$toyota1 = new Toyota('512379', 10, 15);
echo calcTankPrice($toyota1, 5);
echo "<br>";
$mahindra1 = new Mahindra('965742', 9, 20);
echo calcTankPrice($mahindra1, 5);
$26.9925
$91.583394878184