উদাহরণস্বরূপ, ধরুন আমি একটি ICar
ইন্টারফেস চাই এবং সমস্ত বাস্তবায়নের ক্ষেত্রে ক্ষেত্র থাকবে Year
। এর অর্থ কি প্রতিটি বাস্তবায়ন পৃথকভাবে ঘোষণা করতে হবে Year
? ইন্টারফেসে কেবল এটি সংজ্ঞায়িত করা ভাল লাগবে না?
উদাহরণস্বরূপ, ধরুন আমি একটি ICar
ইন্টারফেস চাই এবং সমস্ত বাস্তবায়নের ক্ষেত্রে ক্ষেত্র থাকবে Year
। এর অর্থ কি প্রতিটি বাস্তবায়ন পৃথকভাবে ঘোষণা করতে হবে Year
? ইন্টারফেসে কেবল এটি সংজ্ঞায়িত করা ভাল লাগবে না?
উত্তর:
যদিও অন্যান্য উত্তরগুলির অনেকগুলি শব্দার্থক স্তরে সঠিক, তবে আমি বাস্তবায়নের বিশদ স্তর থেকে এই ধরণের প্রশ্নগুলির কাছে আসাও আকর্ষণীয় মনে করি।
একটি ইন্টারফেসটি স্লটগুলির সংগ্রহ হিসাবে ভাবা যেতে পারে , যার মধ্যে পদ্ধতি রয়েছে । যখন কোনও শ্রেণি একটি ইন্টারফেস প্রয়োগ করে, ক্লাসটি রানটাইমটি বলতে হবে কীভাবে সমস্ত প্রয়োজনীয় স্লট পূরণ করতে হয়। যখন তুমি বললে
interface IFoo { void M(); }
class Foo : IFoo { public void M() { ... } }
ক্লাসটি বলে "যখন আপনি আমার উদাহরণ তৈরি করেন, তখন আইএফও.এম এর স্লটে Foo.M- এর একটি রেফারেন্স স্টাফ করুন
তারপরে আপনি যখন কোনও কল করবেন:
IFoo ifoo = new Foo();
ifoo.M();
সংকলক কোডটি উত্পন্ন করে যা বলে যে "আইফু.এম এর স্লটে কী পদ্ধতিটি রয়েছে তা অবজেক্টটিকে জিজ্ঞাসা করুন এবং সেই পদ্ধতিটি কল করুন।
যদি ইন্টারফেসটি এমন স্লটগুলির সংগ্রহ যা পদ্ধতিগুলি ধারণ করে, তবে সেই স্লটে কিছুতে কোনও সম্পত্তি প্রাপ্তি এবং সেট পদ্ধতি, কোনও সূচকের প্রাপ্ত ও সেট পদ্ধতি এবং কোনও ইভেন্টের অ্যাড এবং অপসারণের পদ্ধতিগুলিও থাকতে পারে। তবে একটি ক্ষেত্র একটি পদ্ধতি নয় । কোনও ক্ষেত্রের সাথে এমন কোনও "স্লট" যুক্ত নেই যা আপনি ক্ষেত্রের অবস্থানের সাথে একটি রেফারেন্স সহ "পূরণ করতে পারেন"। এবং সেইজন্য, ইন্টারফেসগুলি পদ্ধতি, বৈশিষ্ট্য, সূচক এবং ইভেন্টগুলি সংজ্ঞায়িত করতে পারে তবে ক্ষেত্রগুলি নয়।
An interface cannot contain constants, fields, operators
থেকে। msdn.microsoft.com/en-us/library/ms173156.aspx )
int One()
তবে বাস্তবায়ন public int One(){return 1;}
ক্ষেত্র নয়।
সি # তে ইন্টারফেসগুলি এমন একটি সংজ্ঞা সংজ্ঞায়িত করার উদ্দেশ্যে যা কোনও শ্রেণি মেনে চলবে - কোনও নির্দিষ্ট বাস্তবায়ন নয়।
সেই আত্মায় সি # ইন্টারফেস বৈশিষ্ট্যগুলি সংজ্ঞায়িত করার অনুমতি দেয় - যার জন্য কলারকে অবশ্যই একটি বাস্তবায়ন সরবরাহ করতে হবে:
interface ICar
{
int Year { get; set; }
}
প্রয়োগকারী ক্লাসগুলি বাস্তবায়নের বিষয়টি সহজ করার জন্য অটো-বৈশিষ্ট্যগুলি ব্যবহার করতে পারে, যদি কোনও সম্পত্তির সাথে যুক্ত থাকে না:
class Automobile : ICar
{
public int Year { get; set; } // automatically implemented
}
Year
?
public int Year => 123;
। যাইহোক, এক্ষেত্রে এটির একটি সেটারের কোনও ধারণা নেই, সুতরাং ইন্টারফেসটি সংজ্ঞায়িত করতে হবেint Year { get; }
এরিক লিপার্ট এটিকে পেরেক দিয়েছিলেন, তিনি যা বলেছিলেন তা বলার জন্য আমি আলাদা উপায় ব্যবহার করব। একটি ইন্টারফেসের সমস্ত সদস্য ভার্চুয়াল এবং সেগুলি ইন্টারফেসের উত্তরাধিকার সূত্রে প্রাপ্ত একটি শ্রেণীর দ্বারা ওভাররাইড করা প্রয়োজন। আপনি ইন্টারফেস ঘোষণায় স্পষ্টভাবে ভার্চুয়াল কীওয়ার্ড লিখবেন না, বা শ্রেণিতে ওভাররাইড কীওয়ার্ড ব্যবহার করবেন না, সেগুলি অন্তর্ভুক্ত রয়েছে।
ভার্চুয়াল কীওয়ার্ড পদ্ধতি এবং একটি তথাকথিত ভি-টেবিল, পদ্ধতি পয়েন্টারগুলির একটি অ্যারে সহ .NET এ প্রয়োগ করা হয়। ওভাররাইড কীওয়ার্ডটি বেস শ্রেণীর দ্বারা উত্পাদিত ওভাররাইট করে ভিন্ন পদ্ধতি পয়েন্টার সহ ভি-টেবিল স্লটটি পূরণ করে। সম্পত্তি, ইভেন্ট এবং সূচকগুলি হুডের অধীনে পদ্ধতি হিসাবে প্রয়োগ করা হয়। তবে ক্ষেত্রগুলি হয় না। ইন্টারফেসের ফলে ক্ষেত্রগুলি থাকতে পারে না।
কেন শুধু একটি Year
সম্পত্তি নেই, যা পুরোপুরি ঠিক আছে?
ইন্টারফেসে ক্ষেত্রগুলি থাকে না কারণ ক্ষেত্রগুলি ডেটা উপস্থাপনের একটি নির্দিষ্ট প্রয়োগের প্রতিনিধিত্ব করে এবং এগুলি প্রকাশের ফলে এনক্যাপসুলেশন ভেঙে যায়। সুতরাং কোনও ক্ষেত্রের সাথে একটি ইন্টারফেস থাকা কার্যকরভাবে একটি ইন্টারফেসের পরিবর্তে একটি প্রয়োগকরণে কোডিং হবে, যা একটি ইন্টারফেসের জন্য একটি কৌতূহলী প্যারাডক্স!
উদাহরণস্বরূপ, আপনার Year
স্পেসিফিকেশনের অংশটির প্রয়োজন হতে পারে যে চলমান বছর +1 বা 1900 এর আগে যে কোনওটি পরে ICar
নিয়োগের অনুমতি দেওয়ার জন্য এটি প্রয়োগকারীদের পক্ষে অবৈধ। এটি Year
বলার উপায় নেই যে আপনি যদি Year
ক্ষেত্রগুলি উন্মুক্ত করে থাকেন - তবে ব্যবহারের থেকে আরও ভাল বৈশিষ্ট্য পরিবর্তে এখানে কাজ করতে।
সংক্ষিপ্ত উত্তর হ্যাঁ, প্রতিটি প্রয়োগকারী ধরণের নিজস্ব ব্যাকিং ভেরিয়েবল তৈরি করতে হবে। এটি কারণ একটি ইন্টারফেস একটি চুক্তির সাথে সাদৃশ্যপূর্ণ। এটি যা করতে পারে তা হ'ল নির্দিষ্ট জনসাধারণের অ্যাক্সেসযোগ্য কোডগুলির টুকরো নির্দিষ্ট করে যা একটি প্রয়োগকারী প্রকারকে অবশ্যই উপলব্ধ করতে হবে; এতে কোনও কোড নিজেই থাকতে পারে না।
আপনার প্রস্তাবিত ব্যবহার করে এই দৃশ্যের বিষয়টি বিবেচনা করুন:
public interface InterfaceOne
{
int myBackingVariable;
int MyProperty { get { return myBackingVariable; } }
}
public interface InterfaceTwo
{
int myBackingVariable;
int MyProperty { get { return myBackingVariable; } }
}
public class MyClass : InterfaceOne, InterfaceTwo { }
আমাদের এখানে বেশ কয়েকটি সমস্যা রয়েছে:
myBackingVariable
করবে MyClass
?গৃহীত সবচেয়ে সাধারণ পদ্ধতির ইন্টারফেস এবং একটি বাস্তব জমি যা এটি প্রয়োগ করে একটি বিমূর্ত শ্রেণীর ঘোষণা দেয়। এটি আপনাকে বিমূর্ত শ্রেণীর উত্তরাধিকার সূত্রে ন্যায্যতা দেয় এবং নিখরচায় বাস্তবায়ন লাভ করে, বা স্পষ্টভাবে ইন্টারফেসটি প্রয়োগ করে এবং অন্য শ্রেণির উত্তরাধিকার সূত্রে অনুমোদিত হয়। এটি এমন কিছু কাজ করে:
public interface IMyInterface
{
int MyProperty { get; set; }
}
public abstract class MyInterfaceBase : IMyInterface
{
int myProperty;
public int MyProperty
{
get { return myProperty; }
set { myProperty = value; }
}
}
অন্যরা 'কেন' দিয়েছে, তাই আমি কেবল যুক্ত করব যে আপনার ইন্টারফেসটি একটি নিয়ন্ত্রণকে সংজ্ঞায়িত করতে পারে; আপনি যদি এটি কোনও সম্পত্তিতে আবদ্ধ করেন:
public interface IView {
Control Year { get; }
}
public Form : IView {
public Control Year { get { return uxYear; } } //numeric text box or whatever
}
ইন্টারফেসে কোনও প্রয়োগ নেই।
ইতিমধ্যে অনেক কিছু বলা হয়েছে, তবে এটি সহজ করার জন্য, এখানে আমার নেওয়া। ইন্টারফেসগুলি ভোক্তা বা শ্রেণি দ্বারা প্রয়োগযোগ্য পদ্ধতি চুক্তি এবং মান সংরক্ষণের ক্ষেত্র না রাখার উদ্দেশ্যে are
আপনি তর্ক করতে পারেন যে তাহলে সম্পত্তি কেন অনুমোদিত? সুতরাং সহজ উত্তরটি হ'ল - বৈশিষ্ট্যগুলি অভ্যন্তরীণভাবে কেবল পদ্ধতি হিসাবে সংজ্ঞায়িত হয়।
এর জন্য আপনার কাছে একটি গাড়ী বেস ক্লাস থাকতে পারে যা বছরের ক্ষেত্রটি বাস্তবায়িত করে এবং অন্যান্য সমস্ত বাস্তবায়ন সেখান থেকে উত্তরাধিকারসূত্রে আসতে পারে।
একটি ইন্টারফেস জনসাধারণের উদাহরণ বৈশিষ্ট্য এবং পদ্ধতিগুলি সংজ্ঞায়িত করে। ক্ষেত্রগুলি সাধারণত ব্যক্তিগত হয়, বা সর্বাধিক সুরক্ষিত, অভ্যন্তরীণ বা সুরক্ষিত অভ্যন্তরীণ (শব্দটি "ক্ষেত্র" সাধারণত পাবলিক কোনও কিছুর জন্য ব্যবহৃত হয় না)।
অন্যান্য জবাব দ্বারা উল্লিখিত হিসাবে আপনি একটি বেস শ্রেণীর সংজ্ঞা দিতে পারেন এবং একটি সুরক্ষিত সম্পত্তি নির্ধারণ করতে পারেন যা সমস্ত উত্তরাধিকারীর দ্বারা অ্যাক্সেসযোগ্য হবে।
একটি অদ্ভুততা একটি ইন্টারফেস আসলে অভ্যন্তরীণ হিসাবে সংজ্ঞায়িত করা যেতে পারে তবে এটি ইন্টারফেসের কার্যকারিতা সীমাবদ্ধ করে, এবং সাধারণত এটি অভ্যন্তরীণ কার্যকারিতা সংজ্ঞায়িত করতে ব্যবহৃত হয় যা অন্যান্য বাহ্যিক কোড ব্যবহার করে না।