যেহেতু আপনি জিজ্ঞাসা করেছেন কেন সি # কেন এটি করেছে, তাই সি # নির্মাতাদের জিজ্ঞাসা করা ভাল। সি # এর প্রধান স্থপতি আন্ডারস হেজলসবার্গ উত্তর দিয়েছেন যে তারা কেন একটি সাক্ষাত্কারে ডিফল্টরূপে (জাভা হিসাবে) ভার্চুয়ালের সাথে না যেতে পছন্দ করেছিল , প্রাসঙ্গিক স্নিপেটগুলি নীচে রয়েছে।
মনে রাখবেন যে জাভাটির অ-ভার্চুয়াল হিসাবে কোনও পদ্ধতি চিহ্নিত করার জন্য চূড়ান্ত কীওয়ার্ড সহ ডিফল্টরূপে ভার্চুয়াল রয়েছে। এখনও দুটি ধারণাগুলি শিখতে হবে, তবে অনেক লোক চূড়ান্ত কীওয়ার্ড সম্পর্কে জানেন না বা সক্রিয়ভাবে ব্যবহার করবেন না। সি # এই সিদ্ধান্তগুলি সচেতনভাবে করার জন্য ভার্চুয়াল এবং নতুন / ওভাররাইড ব্যবহার করতে বাধ্য করে।
এর বেশ কয়েকটি কারণ রয়েছে। একটি হল পারফরম্যান্স । আমরা পর্যবেক্ষণ করতে পারি যে লোকেরা জাভাতে কোড লেখার সাথে সাথে তারা তাদের পদ্ধতিগুলি চূড়ান্ত চিহ্নিত করতে ভুলে যায়। সুতরাং, এই পদ্ধতিগুলি ভার্চুয়াল। কারণ তারা ভার্চুয়াল, তারা ভাল সঞ্চালন করে না। ভার্চুয়াল পদ্ধতি হওয়ার সাথে সাথে কেবল পারফরম্যান্সের ওভারহেড যুক্ত রয়েছে। এটি একটি ইস্যু।
আরও একটি গুরুত্বপূর্ণ বিষয় হ'ল সংস্করণ । ভার্চুয়াল পদ্ধতি সম্পর্কে চিন্তার দুটি বিদ্যালয় রয়েছে। একাডেমিক চিন্তাভাবনা বলছে, "সমস্ত কিছু ভার্চুয়াল হওয়া উচিত, কারণ আমি হয়ত কোনও দিন এটিকে ওভাররাইড করতে চাই।" বাস্তববাদী বিদ্যালয়টি, যা বাস্তব বিশ্বে চালিত বাস্তব অ্যাপ্লিকেশনগুলি তৈরির মধ্য দিয়ে আসে, বলে, "আমরা কী ভার্চুয়াল করি সে সম্পর্কে আমাদের যত্নবান হতে হবে" "
যখন আমরা প্ল্যাটফর্মে কিছু ভার্চুয়াল করি, আমরা ভবিষ্যতে এটি কীভাবে বিকশিত হয় সে সম্পর্কে ভীষণ প্রতিশ্রুতি দিচ্ছি। অ-ভার্চুয়াল পদ্ধতির জন্য, আমরা প্রতিশ্রুতি দিই যে আপনি যখন এই পদ্ধতিটি কল করবেন তখন x এবং y ঘটবে। যখন আমরা কোনও এপিআইতে ভার্চুয়াল পদ্ধতি প্রকাশ করি, আমরা কেবল প্রতিশ্রুতি দিই না যে আপনি যখন এই পদ্ধতিটি কল করবেন তখন x এবং y ঘটবে। আমরা আরও প্রতিশ্রুতি দিয়েছি যে আপনি যখন এই পদ্ধতিটি ওভাররাইড করবেন, তখন আমরা এই নির্দিষ্ট ক্রমের সাথে এই অন্যান্যগুলির বিষয়ে তাকে ডাকব এবং রাষ্ট্রটি এই এবং সেই আক্রমণকারীতে থাকবে।
প্রতিবার আপনি যখন কোনও এপিআইতে ভার্চুয়াল বলবেন, আপনি কল ব্যাক হুক তৈরি করছেন। কোনও ওএস বা এপিআই ফ্রেমওয়ার্ক ডিজাইনার হিসাবে আপনাকে সে সম্পর্কে সত্যই যত্নবান হতে হবে। আপনি কোনও এপিআই-তে কোনও যথেচ্ছ পয়েন্টে ওভাররাইডিং এবং হুকিং চান না, কারণ আপনি প্রয়োজনীয়ভাবে এই প্রতিশ্রুতিগুলি দিতে পারেন না। এবং লোকেরা ভার্চুয়াল কিছু তৈরি করার সময় তারা যে প্রতিশ্রুতি দিচ্ছে তা পুরোপুরি বুঝতে পারে না।
বিকাশকারীরা শ্রেণীর উত্তরাধিকারের নকশা সম্পর্কে কীভাবে চিন্তাভাবনা করে এবং কীভাবে তাদের সিদ্ধান্তটি নিয়েছিল সে সম্পর্কে সাক্ষাত্কারটিতে আরও আলোচনা রয়েছে।
এখন নীচের প্রশ্নের:
আমি কেন বুঝতে পারছি না যে বিশ্বে আমি আমার ডেরিভডক্লাসে বেসক্লাসের মতো একই নাম এবং একই স্বাক্ষর সহ একটি পদ্ধতি যুক্ত করতে যাচ্ছি এবং একটি নতুন আচরণের সংজ্ঞা দিচ্ছি কিন্তু রান-টাইম পলিমারফিজমে বেসক্লাস পদ্ধতিটি চালু করা হবে! (যা ওভাররাইডিং নয় তবে যৌক্তিকভাবে এটি হওয়া উচিত)।
এটি তখন ঘটবে যখন কোনও উদ্ভূত শ্রেণি ঘোষণা করতে চায় যে এটি বেস বর্গের চুক্তি মেনে চলে না, তবে একই নামের একটি পদ্ধতি রয়েছে। (যে কেউ সি # এর মধ্যে new
এবং তার override
মধ্যে পার্থক্য জানেন না , তার জন্য এই এমএসডিএন পৃষ্ঠাটি দেখুন )।
একটি খুব বাস্তব পরিস্থিতি হ'ল:
- আপনি একটি এপিআই তৈরি করেছেন, যার একটি ক্লাস রয়েছে
Vehicle
।
- আমি আপনার এপিআই ব্যবহার শুরু করেছি এবং উত্পন্ন করেছি
Vehicle
।
- আপনার
Vehicle
ক্লাসে কোনও পদ্ধতি ছিল না PerformEngineCheck()
।
- আমার
Car
ক্লাসে, আমি একটি পদ্ধতি যুক্ত করি PerformEngineCheck()
।
- আপনি আপনার API এর একটি নতুন সংস্করণ প্রকাশ করেছেন এবং একটি যুক্ত করেছেন
PerformEngineCheck()
।
- আমি আমার পদ্ধতির নাম পরিবর্তন করতে পারি না কারণ আমার ক্লায়েন্টরা আমার API এর উপর নির্ভরশীল, এবং এটি তাদের ভেঙে দেবে।
সুতরাং যখন আমি আপনার নতুন এপিআইয়ের বিরুদ্ধে পুনরায় রচনা করি তখন সি # আমাকে এই সমস্যাটি সম্পর্কে সতর্ক করে, যেমন
বেসটি PerformEngineCheck()
না থাকলে virtual
:
app2.cs(15,17): warning CS0108: 'Car.PerformEngineCheck()' hides inherited member 'Vehicle.PerformEngineCheck()'.
Use the new keyword if hiding was intended.
এবং যদি বেসটি PerformEngineCheck()
ছিল virtual
:
app2.cs(15,17): warning CS0114: 'Car.PerformEngineCheck()' hides inherited member 'Vehicle.PerformEngineCheck()'.
To make the current member override that implementation, add the override keyword. Otherwise add the new keyword.
এখন, আমার ক্লাসটি আসলে বেস ক্লাসের চুক্তিটি প্রসারিত করছে কিনা তা স্পষ্ট করেই আমাকে সিদ্ধান্ত নিতে হবে, বা এটি যদি অন্য চুক্তি হয় তবে একই নামে হয়।
- এটি তৈরির মাধ্যমে
new
, যদি বেস পদ্ধতির কার্যকারিতা উত্পন্ন পদ্ধতি থেকে আলাদা হয় তবে আমি আমার ক্লায়েন্টদের ভাঙ্গি না। রেফারেন্সযুক্ত যে কোনও কোডই কল Vehicle
দেখতে পাবে না Car.PerformEngineCheck()
, তবে যে কোডটিতে একটি রেফারেন্স Car
ছিল সেটিতে আমি যে অফারটি দিয়েছিলাম তা একই কার্যকারিতাটি দেখতে থাকবে PerformEngineCheck()
।
অনুরূপ উদাহরণটি যখন বেস ক্লাসের অন্য কোনও পদ্ধতি কল করতে পারে PerformEngineCheck()
( উদাহরণস্বরূপ আরও নতুন সংস্করণে), তখন কীভাবে কেউ এটিকে PerformEngineCheck()
উদ্ভূত শ্রেণীর কল করতে বাধা দেয় ? জাভাতে, এই সিদ্ধান্তটি বেস শ্রেণীর সাথে বিশ্রাম নেবে, তবে এটি উত্পন্ন শ্রেণীর সম্পর্কে কিছুই জানে না। সি #, যে সিদ্ধান্ত অবস্থিত থাকলে সংশ্লিষ্ট উভয় বেস শ্রেণী (মাধ্যমে উপর virtual
শব্দ), এবং উদ্ভূত বর্গ উপর (মাধ্যমে new
এবং override
কিওয়ার্ড)।
অবশ্যই, সংকলকটি যে ত্রুটিগুলি ফেলে দেয় তা প্রোগ্রামারদের অপ্রত্যাশিতভাবে ত্রুটিগুলি না করার জন্য একটি দরকারী সরঞ্জাম সরবরাহ করে (যেমন হয় ওভাররাইড বা এটি উপলব্ধি না করে নতুন কার্যকারিতা সরবরাহ করে))
অ্যান্ডারস বলেছিলেন, সত্যিকারের বিশ্ব আমাদেরকে এমন বিষয়গুলিতে জোর করে, যা আমরা যদি স্ক্র্যাচ থেকে শুরু করি, আমরা কখনই তাতে প্রবেশ করতে চাই না।
সম্পাদনা: new
ইন্টারফেসের সামঞ্জস্যতা নিশ্চিত করার জন্য কোথায় ব্যবহার করতে হবে তার একটি উদাহরণ যুক্ত করা হয়েছে।
সম্পাদনা: মন্তব্যগুলি করার সময়, আমি এরিক লিপার্টের (তখন সি # ডিজাইন কমিটির সদস্যদের মধ্যে একজন) অন্যান্য উদাহরণের দৃশ্যের (ব্রায়ান দ্বারা উল্লিখিত) একটি লেখাও পেয়েছিলাম ।
পার্ট 2: আপডেট হওয়া প্রশ্নের ভিত্তিতে
তবে সি # এর ক্ষেত্রে স্পেসশিপ যদি যানবাহন শ্রেণিকে 'ত্বরান্বিত করে নতুন ব্যবহার না করে তবে আমার কোডটির যুক্তিটি ভেঙে যাবে। এটা কি অসুবিধা নয়?
কে সিদ্ধান্ত নেয় যে SpaceShip
আসলে ওভাররাইড করছে কিনা Vehicle.accelerate()
বা এটি আলাদা কিনা? এটি SpaceShip
ডেভেলপার হতে হবে । সুতরাং যদি SpaceShip
বিকাশকারী সিদ্ধান্ত নেন যে তারা বেস ক্লাসের চুক্তি পালন করছেন না, তবে আপনার কলটি করা Vehicle.accelerate()
উচিত নয় SpaceShip.accelerate()
, বা করা উচিত? তারা যখন এটিকে চিহ্নিত করবে new
। তবে, যদি তারা সিদ্ধান্ত নেয় যে এটি সত্যই চুক্তিটি রাখে, তবে তারা প্রকৃতপক্ষে এটি চিহ্নিত করবে override
। উভয় ক্ষেত্রেই, আপনার কোড চুক্তির ভিত্তিতে সঠিক পদ্ধতিটি কল করে সঠিকভাবে আচরণ করবে । আপনার কোডটি কীভাবে সিদ্ধান্ত নিতে পারে যে SpaceShip.accelerate()
এটি আসলে ওভাররাইড করছে কিনা Vehicle.accelerate()
বা এটি নামের সংঘর্ষ কিনা ? (উপরে আমার উদাহরণ দেখুন)।
যাইহোক, অন্তর্নিহিত উত্তরাধিকার ক্ষেত্রে, এমনকি যদি SpaceShip.accelerate()
রক্ষা না চুক্তি এর Vehicle.accelerate()
, পদ্ধতি কল এখনও যেতে হবে SpaceShip.accelerate()
।