আসুন একটি সেকেন্ডের জন্য উপেক্ষা করুন যে প্রশ্নে পদ্ধতিটি হল __construct
এবং এটি কল করুন frobnicate
। এখন ধরুন আপনার কাছে একটি অবজেক্ট api
বাস্তবায়নকারী IHttpApi
এবং একটি অবজেক্ট config
বাস্তবায়নকারী রয়েছে IHttpConfig
। স্পষ্টতই, এই কোডটি ইন্টারফেসের সাথে ফিট করে:
$api->frobnicate($config)
তবে ধরা যাক আমরা উদাহরণস্বরূপ উপুড় api
হয়ে যাই IApi
, উদাহরণস্বরূপ এটিকে পাস করা function frobnicateTwice(IApi $api)
। এখন যে ফাংশনে, frobnicate
বলা হয়, এবং যেহেতু এটি শুধুমাত্র সঙ্গে পুলিশ IApi
, এটা যেমন যেমন একটি কল সঞ্চালন করা সম্ভব $api->frobnicate(new SpecificConfig(...))
যেখানে SpecificConfig
কার্যকরী IConfig
কিন্তু IHttpConfig
। বিন্দুতে কেউ প্রকারের সাথে অস্বাস্থ্যকর কিছু করেনি, তবে এমনটি IHttpApi::frobnicate
পেয়েছে SpecificConfig
যেখানে এটি প্রত্যাশিত IHttpConfig
।
এটি ভাল না। আমরা উজান বন্ধ করতে চাই না, আমরা সাব টাইপিং করতে চাই এবং আমরা স্পষ্টতই চাই একটি ইন্টারফেস প্রয়োগকারী একাধিক ক্লাস চাই। সুতরাং একমাত্র বুদ্ধিমান বিকল্প হ'ল পরামিতিগুলির জন্য আরও সুনির্দিষ্ট ধরণের প্রয়োজনীয় একটি সাব টাইপ পদ্ধতি নিষিদ্ধ করা। (আপনি আরও সাধারণ ধরণের ফিরে আসতে চাইলে একই রকম সমস্যা দেখা দেয় ))
সাধারণত, আপনি বহুকর্ম, বৈচিত্রকে ঘিরে একটি ক্লাসিক ফাঁদে গেছেন । কোনও ধরণের সমস্ত ঘটনা T
উপ- টাইপ দ্বারা প্রতিস্থাপন করা যায় না U
। বিপরীতভাবে, কোনও ধরণের সমস্ত ঘটনাকে T
একটি সুপারটাইপ দ্বারা প্রতিস্থাপন করা যায় নাS
। সাবধানতার সাথে বিবেচনা (বা আরও ভাল, ধরণের তত্ত্বের কঠোর প্রয়োগ) প্রয়োজনীয়।
ফিরে আসছেন __construct
: যেহেতু আফাইক আপনি ঠিক একটি ইন্টারফেস ইনস্ট্যান্ট করতে পারবেন না, কেবলমাত্র একটি কংক্রিট প্রয়োগকারী, এটি একটি অর্থহীন বিধিনিষেধের মতো মনে হতে পারে (এটি কোনও ইন্টারফেসের মাধ্যমে ডাকা হবে না)। তবে __construct
সেক্ষেত্রে ইন্টারফেসের সাথে কেন শুরু করা উচিত? নির্বিশেষে, __construct
এখানে বিশেষ-ক্ষেত্রে এটি খুব কম কাজে লাগবে ।