বৈশিষ্ট্য বনাম ইন্টারফেস


344

আমি ইদানীং পিএইচপি উপর অধ্যয়ন করার চেষ্টা করেছি এবং আমি নিজেকে বৈশিষ্ট্যগুলিতে ঝুলতে দেখছি। আমি অনুভূমিক কোড পুনরায় ব্যবহারের ধারণাটি বুঝতে পারি এবং প্রয়োজনীয়ভাবে কোনও বিমূর্ত শ্রেণীর উত্তরাধিকারী হতে চাই না। আমি যা বুঝতে পারি না তা হ'ল: বৈশিষ্ট্য বনাম ইন্টারফেসের মধ্যে গুরুত্বপূর্ণ পার্থক্য কী?

আমি একটি শালীন ব্লগ পোস্ট বা একটি বা অন্যটি কখন ব্যবহার করতে হবে তা ব্যাখ্যা করার জন্য নিবন্ধ অনুসন্ধান করার চেষ্টা করেছি, তবে এখন পর্যন্ত যে উদাহরণগুলি পেয়েছি তা সাদৃশ্যপূর্ণ বলে মনে হয়।


6
ইন্টারফেসের ফাংশন বডিতে কোনও কোড নেই। তাদের আসলে কোন ফাংশন বডি নেই।
হ্যাক্রে

2
আমার অত্যন্ত উত্সাহিত উত্তর থাকা সত্ত্বেও, আমি এটি রেকর্ডটির জন্য উল্লেখ করতে চাই যে আমি সাধারণত অ্যান্টি-ট্রিট / মিক্সিনকীভাবে বৈশিষ্ট্যগুলি প্রায়শই কঠিন ওওপি অনুশীলনগুলিকে দুর্বল করে তা পড়তে এই চ্যাট প্রতিলিপিটি দেখুন ।
rdlowrey

2
আমি বিপরীতে তর্ক করব। বৈশিষ্ট্যগুলির আবির্ভাবের আগে এবং বহু বছর ধরে পিএইচপি এর সাথে কাজ করার পরে, আমি মনে করি তাদের যোগ্যতা প্রমাণ করা সহজ। কেবলমাত্র এই ব্যবহারিক উদাহরণের মাধ্যমে পড়ুন যা 'চিত্রের মডেলগুলি' Imagickঅবজেক্টের মতো হাঁটতে এবং কথা বলতে সক্ষম করে, বৈশিষ্ট্যের আগে পুরানো দিনগুলিতে প্রয়োজনীয় সমস্ত ব্লাট কম।
কুইকশিফ্টিন

বৈশিষ্ট্য এবং ইন্টারফেস একই রকম। মূল পার্থক্যটি হ'ল বৈশিষ্ট্যগুলি আপনাকে পদ্ধতিগুলি প্রয়োগ করতে দেয়, ইন্টারফেস দেয় না।
জন

উত্তর:


238

একটি ইন্টারফেস পদ্ধতি বাস্তবায়নের বর্গ একটি সেট সংজ্ঞায়িত আবশ্যক বাস্তবায়ন।

যখন কোনও বৈশিষ্ট্য হয় useতখন পদ্ধতিগুলির প্রয়োগগুলিও বরাবর আসে - যা একটিতে ঘটে না Interface

এটিই সবচেয়ে বড় পার্থক্য।

পিএইচপি আরএফসির জন্য অনুভূমিক পুনঃব্যবহার থেকে :

বৈশিষ্ট্যগুলি পিএইচপি এর মতো একক উত্তরাধিকারের ভাষাগুলিতে কোড পুনরায় ব্যবহারের ব্যবস্থা is একটি বিকাশকারী বিকাশকারীকে বিভিন্ন শ্রেণীর শ্রেণিবৃত্তিতে বসবাসকারী কয়েকটি স্বতন্ত্র শ্রেণিতে অবাধে পদ্ধতিগুলির সেটগুলি পুনরায় ব্যবহার করতে সক্ষম করে একক উত্তরাধিকারের কিছু সীমাবদ্ধতা হ্রাস করার উদ্দেশ্যে তৈরি করা হয়।


2
@ জেরাম অনুশীলনে, কিছুই নয়। বাস্তবে, আরও অনেক কিছু।
অ্যালেক গর্জে

79
বৈশিষ্ট্যগুলি বাদে একেবারে ইন্টারফেস নয়। ইন্টারফেসগুলি এমন নির্দিষ্টকরণ যা এর বিরুদ্ধে পরীক্ষা করা যায়। বৈশিষ্ট্যগুলির বিরুদ্ধে পরীক্ষা করা যায় না, সেহেতু সেগুলি কেবলমাত্র বাস্তবায়ন। এগুলি ইন্টারফেসের ঠিক বিপরীত।
আরএফসির

195
বৈশিষ্ট্যগুলি মূলত ভাষা সহায়তা কপি এবং পেস্ট হয়
শহীদ

10
এটি কোনও রূপক নয়। এটি একটি শব্দের অর্থ কসাইছে। এটি একটি বাক্সকে ভলিউমযুক্ত পৃষ্ঠ হিসাবে বর্ণনা করার মতো।
ক্লিওং করুন

6
আইরামসেক্সেল এবং শাদির মন্তব্যে প্রসারিত করার জন্য: আপনি কোনও বস্তু কোনও ইন্টারফেস প্রয়োগ করে কিনা তা পরীক্ষা করতে পারেন (উদাহরণস্বরূপ), এবং আপনি নিশ্চিত করতে পারেন যে কোনও পদ্ধতি আর্গুমেন্ট পদ্ধতিতে স্বাক্ষরটিতে একটি টাইপ ইঙ্গিতের মাধ্যমে একটি ইন্টারফেস প্রয়োগ করে। আপনি বৈশিষ্ট্যের জন্য সংশ্লিষ্ট চেকগুলি সম্পাদন করতে পারবেন না।
ব্রায়ান ডি'আস্টোস

530

পাবলিক সার্ভিস ঘোষণা:

আমি রেকর্ডটির জন্য বলতে চাই যে আমি বিশ্বাস করি যে বৈশিষ্ট্যগুলি প্রায়শই একটি কোডের গন্ধ এবং সংমিশ্রনের পক্ষে এড়ানো উচিত। এটি আমার অভিমত যে একক উত্তরাধিকারটি প্রায়শই একটি বিরোধী-প্যাটার্ন হিসাবে চিহ্নিত হয় এবং একাধিক উত্তরাধিকার কেবল এই সমস্যাটিকেই মিশ্রিত করে। উত্তরাধিকারের উপর রচনাটির পক্ষপাতী হয়ে আপনি বেশিরভাগ ক্ষেত্রে আরও ভাল পরিবেশিত হবেন (এটি একক বা একাধিক)। আপনি যদি এখনও ইন্টারফেসের বৈশিষ্ট্য এবং তাদের সম্পর্কের বিষয়ে আগ্রহী হন তবে পড়ুন ...


আসুন এটি বলে শুরু করুন:

অবজেক্ট-ওরিয়েন্টেড প্রোগ্রামিং (ওওপি) উপলব্ধি করা একটি কঠিন দৃষ্টান্ত হতে পারে। আপনি ক্লাস ব্যবহার করছেন বলে কেবল আপনার কোডটি অবজেক্ট-ওরিয়েন্টেড (ওও) নয়।

ওও কোডটি লিখতে আপনাকে বুঝতে হবে যে ওওপি সত্যই আপনার বস্তুর দক্ষতা সম্পর্কে। আপনি কি তারা পরিপ্রেক্ষিতে শ্রেণীর সম্পর্কে ভাবতে পেয়েছেন কি করতে পারেন যা তারা এর পরিবর্তে আসলে কি । এটি প্রচলিত পদ্ধতিগত প্রোগ্রামিংয়ের সম্পূর্ণ বিপরীতে যেখানে ফোকাসটি কিছু কোড তৈরি করার দিকে রয়েছে "কিছু করুন"।

যদি ওওপি কোড পরিকল্পনা এবং নকশা সম্পর্কে হয় তবে একটি ইন্টারফেস হ'ল নীলনকশা এবং কোনও অবজেক্ট সম্পূর্ণরূপে নির্মিত বাড়ি। ইতিমধ্যে, বৈশিষ্ট্যগুলি কেবল নীলনকশা (ইন্টারফেস) দ্বারা নির্ধারিত ঘর তৈরিতে সহায়তা করার একটি উপায়।

ইন্টারফেস

সুতরাং, কেন আমরা ইন্টারফেস ব্যবহার করা উচিত? বেশ সহজভাবে, ইন্টারফেসগুলি আমাদের কোডটিকে কম ভঙ্গুর করে। আপনি যদি এই বিবৃতিতে সন্দেহ করেন তবে যে কাউকে লিগ্যাসি কোড বজায় রাখতে বাধ্য করা হয়েছে যা ইন্টারফেসের বিরুদ্ধে লেখা হয়নি ask

ইন্টারফেসটি প্রোগ্রামার এবং তার কোডের মধ্যে একটি চুক্তি। ইন্টারফেসটি বলে, "যতক্ষণ না আপনি আমার বিধিগুলি খেলে আপনি আমাকে প্রয়োগ করতে পারেন তবে আপনি পছন্দ করেন এবং আমি প্রতিশ্রুতি দিই যে আমি আপনার অন্য কোডটি ভঙ্গ করব না।"

উদাহরণস্বরূপ, একটি বাস্তব-বিশ্বের পরিস্থিতি বিবেচনা করুন (কোনও গাড়ি বা উইজেট নেই):

ওয়েব অ্যাপ্লিকেশনটির জন্য সার্ভারের লোড কমানোর জন্য আপনি একটি ক্যাচিং সিস্টেমটি প্রয়োগ করতে চান

আপনি এপিসি ব্যবহার করে অনুরোধের প্রতিক্রিয়াগুলি ক্যাশে একটি ক্লাস লিখে শুরু করেছিলেন:

class ApcCacher
{
  public function fetch($key) {
    return apc_fetch($key);
  }
  public function store($key, $data) {
    return apc_store($key, $data);
  }
  public function delete($key) {
    return apc_delete($key);
  }
}

তারপরে, আপনার এইচটিটিপি প্রতিক্রিয়া অবজেক্টে, আপনি প্রকৃত প্রতিক্রিয়া উত্পন্ন করতে সমস্ত কাজ করার আগে একটি ক্যাশে হিট পরীক্ষা করে দেখুন:

class Controller
{
  protected $req;
  protected $resp;
  protected $cacher;

  public function __construct(Request $req, Response $resp, ApcCacher $cacher=NULL) {
    $this->req    = $req;
    $this->resp   = $resp;
    $this->cacher = $cacher;

    $this->buildResponse();
  }

  public function buildResponse() {
    if (NULL !== $this->cacher && $response = $this->cacher->fetch($this->req->uri()) {
      $this->resp = $response;
    } else {
      // Build the response manually
    }
  }

  public function getResponse() {
    return $this->resp;
  }
}

এই পদ্ধতির দুর্দান্ত কাজ করে। তবে কয়েক সপ্তাহ পরে আপনি সিদ্ধান্ত নিতে পারেন আপনি এপিসির পরিবর্তে ফাইল-ভিত্তিক ক্যাশে সিস্টেমটি ব্যবহার করতে চান। ApcCacherক্লাসের সক্ষমতা প্রকাশ করে এমন একটি ইন্টারফেসের চেয়ে ক্লাসের কার্যকারিতা নিয়ে কাজ করার জন্য আপনি আপনার নিয়ামককে প্রোগ্রাম করেছেন বলে এখন আপনাকে আপনার নিয়ামক কোডটি পরিবর্তন করতে হবে ApcCacher। আসুন আমরা Controllerউপরেরটির CacherInterfaceপরিবর্তে কংক্রিটের পরিবর্তে ক্লাসকে নির্ভর করে তুললাম ApcCacher:

// Your controller's constructor using the interface as a dependency
public function __construct(Request $req, Response $resp, CacherInterface $cacher=NULL)

এটির সাথে যেতে আপনি আপনার ইন্টারফেসটি এর মতো সংজ্ঞায়িত করেন:

interface CacherInterface
{
  public function fetch($key);
  public function store($key, $data);
  public function delete($key);
}

ঘুরেফিরে আপনার ApcCacherএবং আপনার নতুন FileCacherক্লাস উভয়ই প্রয়োগ করে CacherInterfaceএবং আপনি আপনার Controllerক্লাসটিকে ইন্টারফেসের দ্বারা প্রয়োজনীয় দক্ষতাগুলি ব্যবহার করার জন্য প্রোগ্রাম করেন।

এই উদাহরণটি (আশাকরি) দেখায় যে কীভাবে কোনও ইন্টারফেসে প্রোগ্রামিং করা আপনাকে পরিবর্তনগুলি আপনার অন্যান্য কোডটি ভেঙে দিবে তা চিন্তা না করে আপনার ক্লাসের অভ্যন্তরীণ বাস্তবায়ন পরিবর্তন করতে দেয়।

বৈশিষ্ট

অন্যদিকে, বৈশিষ্ট্যগুলি কেবল কোডটি পুনরায় ব্যবহারের জন্য একটি পদ্ধতি। ইন্টারফেসগুলি বৈশিষ্ট্যের পারস্পরিক একচেটিয়া বিকল্প হিসাবে ভাবা উচিত নয়। আসলে, এমন একটি বৈশিষ্ট্য তৈরি করা যা ইন্টারফেসের দ্বারা প্রয়োজনীয় দক্ষতা পূরণ করে তা হ'ল আদর্শ ব্যবহারের ক্ষেত্রে

আপনি কেবল তখনই ব্যবহার করতে পারেন যখন একাধিক ক্লাস একই কার্যকারিতা ভাগ করে নেয় (সম্ভবত একই ইন্টারফেস দ্বারা নির্ধারিত হয়)। একটি একক শ্রেণীর জন্য কার্যকারিতা সরবরাহ করার জন্য কোনও বৈশিষ্ট্য ব্যবহার করার কোনও বুদ্ধি নেই: যা কেবল ক্লাসটি কী করে তা বিস্মৃত করে এবং আরও ভাল নকশা বৈশিষ্ট্যের কার্যকারিতাটি প্রাসঙ্গিক শ্রেণিতে স্থানান্তরিত করে।

নিম্নলিখিত বৈশিষ্ট্য বাস্তবায়ন বিবেচনা করুন:

interface Person
{
    public function greet();
    public function eat($food);
}

trait EatingTrait
{
    public function eat($food)
    {
        $this->putInMouth($food);
    }

    private function putInMouth($food)
    {
        // Digest delicious food
    }
}

class NicePerson implements Person
{
    use EatingTrait;

    public function greet()
    {
        echo 'Good day, good sir!';
    }
}

class MeanPerson implements Person
{
    use EatingTrait;

    public function greet()
    {
        echo 'Your mother was a hamster!';
    }
}

আরও দৃ concrete় উদাহরণ: আপনি FileCacherএবং আপনার ApcCacherইন্টারফেস আলোচনার মধ্য থেকে উভয়ই একই পদ্ধতি ব্যবহার করে তা নির্ধারণ করতে ক্যাশে প্রবেশটি বাসি কিনা এবং মুছে ফেলা উচিত (স্পষ্টত এটি বাস্তব জীবনে ঘটনাটি নয়, তবে এটির সাথে যান) imagine আপনি কোনও বৈশিষ্ট্য লিখতে এবং উভয় শ্রেণিকেই সাধারণ ইন্টারফেসের প্রয়োজনীয়তার জন্য এটি ব্যবহার করার অনুমতি দিতে পারেন।

সাবধানতার একটি চূড়ান্ত শব্দ: বৈশিষ্ট্যগুলি দিয়ে ওভারবোর্ডে না যাওয়ার বিষয়ে সতর্কতা অবলম্বন করুন। অনন্য শ্রেণীর প্রয়োগগুলি পর্যাপ্ত হলে প্রায়শই বৈশিষ্ট্যগুলি দুর্বল নকশার জন্য ক্রাচ হিসাবে ব্যবহৃত হয়। আপনার সেরা কোড ডিজাইনের জন্য ইন্টারফেসের প্রয়োজনীয়তাগুলি পূরণ করার জন্য বৈশিষ্ট্যগুলি সীমাবদ্ধ করা উচিত।


69
আমি সত্যিই উপরে সরবরাহ করা দ্রুত সরল উত্তরটির সন্ধান করছিলাম, তবে আমি আপনাকে বলতে চাই যে আপনি একটি দুর্দান্ত গভীর উত্তর দিয়েছেন যা অন্যদের জন্য পার্থক্য পরিষ্কার করতে সহায়তা করবে, বাছুন।
ডাটগুয়েওয়ালা 14

35
"[সি] একটি নির্দিষ্ট শ্রেণীর ইন্টারফেসের দ্বারা প্রয়োজনীয় দক্ষতা পূরণ করে এমন বৈশিষ্ট্যগুলি পুনর্বার করা একটি আদর্শ ব্যবহারের ক্ষেত্রে"। ঠিক: +1
অ্যালেক গর্জে

5
এটি কি বলা উচিত যে পিএইচপি-তে বৈশিষ্ট্যগুলি অন্যান্য ভাষার মিশ্রণের সাথে সমান?
এএনও

5
@igorpan সব ইন্টেন্টগুলি এবং উদ্দেশ্যের জন্য আমি বলতে চাই পিএইচপি এর বৈশিষ্ট্য বাস্তবায়ন হয় একাধিক উত্তরাধিকার হিসাবে একই। এটি লক্ষণীয় যে পিএইচপি-তে কোনও বৈশিষ্ট্য যদি স্থির বৈশিষ্ট্যগুলি নির্দিষ্ট করে তবে বৈশিষ্ট্যটি ব্যবহার করে প্রতিটি শ্রেণীর স্থির সম্পত্তিটির নিজস্ব কপি থাকবে। আরও গুরুত্বপূর্ণ ... এই বৈশিষ্ট্যটি অনুসন্ধানের সময় এসইআরপিগুলিতে কীভাবে এই পোস্টটি এখন চূড়ান্তভাবে দেখছে তা আমি পৃষ্ঠার শীর্ষে একটি সার্বজনীন পরিষেবাদির ঘোষণা যুক্ত করতে যাচ্ছি। আপনার এটি পড়া উচিত।
rdlowrey

3
গভীরতার ব্যাখ্যার জন্য +1। আমি রুবি ব্যাকগ্রাউন্ড থেকে এসেছি, যেখানে মিক্সিনগুলি প্রচুর ব্যবহৃত হয়; শুধু আমার দুটি সেন্ট যুক্ত করার জন্য, আমরা যে থাম্বের ব্যবহার করি তার একটি ভাল নিয়ম পিএইচপি অনুবাদ করা যেতে পারে কারণ "এই পদ্ধতিগুলিকে পরিবর্তিত করে এমন পদ্ধতিগুলি প্রয়োগ করে না" $ এটি পুরো গুচ্ছ পাগল ডিবাগিং সেশনগুলিকে বাধা দেয় ... একটি মিশ্রণটি ক্লাসে মিশ্রিত হবে সে সম্পর্কে কোনও অনুমানও করা উচিত নয় (বা আপনার এটি খুব পরিষ্কার করে দেওয়া উচিত এবং নির্ভরযোগ্যতা কেবলমাত্র সর্বনিম্নে হ্রাস করতে হবে)। এই ক্ষেত্রে, আমি আপনার বৈশিষ্ট্যগুলি কার্যকরভাবে ইন্টারফেস প্রয়োগ করার ধারণাটি পেয়েছি।
m_x

67

traitহ'ল পিএইচপি'র একটি বাস্তবায়ন mixin, এবং কার্যকরভাবে এক্সটেনশন পদ্ধতির একটি সেট যা সংযোজনের মাধ্যমে যে কোনও শ্রেণিতে যুক্ত করা যেতে পারে trait। এরপরে পদ্ধতিগুলি শ্রেণীর প্রয়োগের অংশ হয়ে যায় তবে উত্তরাধিকার ব্যবহার না করে

থেকে পিএইচপি ম্যানুয়াল (জোর খনি):

বৈশিষ্ট্যগুলি পিএইচপি এর মতো একক উত্তরাধিকারের ভাষাগুলিতে কোড পুনরায় ব্যবহারের ব্যবস্থা are ... এটি traditionalতিহ্যগত উত্তরাধিকারের সংযোজন এবং আচরণের অনুভূমিক রচনাকে সক্ষম করে; এটি হ'ল উত্তরাধিকারের প্রয়োজন ছাড়াই শ্রেণীর সদস্যদের আবেদন।

একটি উদাহরণ:

trait myTrait {
    function foo() { return "Foo!"; }
    function bar() { return "Bar!"; }
}

উপরের বৈশিষ্ট্যটি সংজ্ঞায়িত করে, আমি এখন নিম্নলিখিতগুলি করতে পারি:

class MyClass extends SomeBaseClass {
    use myTrait; // Inclusion of the trait myTrait
}

এই মুহুর্তে, আমি যখন ক্লাসের উদাহরণ তৈরি করি তখন MyClassএর দুটি পদ্ধতি রয়েছে, যাকে বলা হয় foo()এবং bar()- যা আসে myTrait। এবং - লক্ষ্য করুন যে traitসংজ্ঞায়িত পদ্ধতিতে ইতিমধ্যে একটি মেথড বডি রয়েছে - যা কোনও Interfaceপূর্বনির্ধারিত পদ্ধতিতে পারে না।

অতিরিক্ত হিসাবে - অন্যান্য অনেক ভাষার মতো পিএইচপি একটি একক উত্তরাধিকারের মডেল ব্যবহার করে - যার অর্থ যে কোনও শ্রেণি একাধিক ইন্টারফেস থেকে প্রাপ্ত হতে পারে তবে একাধিক শ্রেণি নয় classes তবে পিএইচপি বর্গ করতে একাধিক আছে traitযা পুনর্ব্যবহারযোগ্য টুকরা অন্তর্ভুক্ত করা প্রোগ্রামার পারবেন - - ইনক্লুশান হিসাবে তারা পারে একাধিক বেস ক্লাস সহ।

কয়েকটি বিষয় লক্ষণীয়:

                      -----------------------------------------------
                      |   Interface   |  Base Class   |    Trait    |
                      ===============================================
> 1 per class         |      Yes      |       No      |     Yes     |
---------------------------------------------------------------------
Define Method Body    |      No       |       Yes     |     Yes     |
---------------------------------------------------------------------
Polymorphism          |      Yes      |       Yes     |     No      |
---------------------------------------------------------------------

পলিমরফিজ্ম:

তার আগে উদাহরণে, যেখানে MyClass প্রসারিত SomeBaseClass , MyClass হয় একটি দৃষ্টান্ত SomeBaseClass। অন্য কথায়, একটি অ্যারের SomeBaseClass[] basesউদাহরণ থাকতে পারে MyClass। একইভাবে, যদি MyClassপ্রসারিত হয় তবে IBaseInterfaceএকটি অ্যারের IBaseInterface[] basesউদাহরণ থাকতে পারে MyClass। এর সাথে এ জাতীয় কোনও বহুকর্মী কন্সট্রাক্ট উপলভ্য নেই trait- কারণ একটি traitমূলত কেবল কোড যা প্রতিটি ক্লাসে প্রোগ্রামারের সুবিধার জন্য অনুলিপি করা হয়।

অগ্রগণ্যতা:

ম্যানুয়ালে বর্ণিত:

বেস ক্লাসের উত্তরাধিকার সূত্রে প্রাপ্ত কোনও সদস্য ট্রাইট দ্বারা সন্নিবেশিত সদস্য দ্বারা ওভাররাইড করা হয়। অগ্রাধিকার ক্রমটি হ'ল বর্তমান শ্রেণীর সদস্যরা বৈশিষ্ট্য পদ্ধতিগুলি ওভাররাইড করে, যা প্রত্যাবর্তিতভাবে উত্তরাধিকার সূত্রে প্রাপ্ত পদ্ধতিগুলিকে ওভাররাইড করে।

সুতরাং - নিম্নলিখিত পরিস্থিতিতে বিবেচনা করুন:

class BaseClass {
    function SomeMethod() { /* Do stuff here */ }
}

interface IBase {
    function SomeMethod();
}

trait myTrait {
    function SomeMethod() { /* Do different stuff here */ }
}

class MyClass extends BaseClass implements IBase {
    use myTrait;

    function SomeMethod() { /* Do a third thing */ }
}

উপরের মাইক্লাসের উদাহরণ তৈরি করার সময়, নিম্নলিখিতটি ঘটে:

  1. Interface IBaseনামক একটি parameterless ফাংশন প্রয়োজন SomeMethod()উপলব্ধ করা হয়।
  2. বেস ক্লাসটি BaseClassএই পদ্ধতির একটি বাস্তবায়ন সরবরাহ করে - প্রয়োজনীয়তাকে সন্তুষ্ট করে।
  3. trait myTraitএকটি parameterless ফাংশন বলা উপলব্ধ SomeMethod()পাশাপাশি, যা অগ্রগণ্য উপর BaseClass-version
  4. class MyClassতার নিজস্ব সংস্করণ উপলব্ধ SomeMethod()- যা অগ্রগণ্য উপর trait-version।

উপসংহার

  1. একটি Interfaceকোনও মেথড বডিটির একটি ডিফল্ট বাস্তবায়ন সরবরাহ করতে পারে না, যখন একটি traitক্যান।
  2. একটি Interfaceহ'ল বহুসামগ্রী , উত্তরাধিকারসূত্রে নির্মিত কন্সট্রাক্ট - যখন একটি traitহয় না।
  3. একাধিক Interfaceগুলি একই শ্রেণিতে ব্যবহার করা যেতে পারে, এবং একাধিক traitগুলি ব্যবহার করতে পারে ।

4
"একটি বৈশিষ্ট্য একটি বিমূর্ত শ্রেণীর সি # ধারণার অনুরূপ" না, একটি বিমূর্ত শ্রেণি একটি বিমূর্ত শ্রেণি; এই ধারণাটি পিএইচপি এবং সি # উভয়তেই বিদ্যমান। আমি পরিবর্তে সি # তে এক্সটেনশন পদ্ধতিতে তৈরি স্ট্যাটিক ক্লাসের সাথে পিএইচপি-তে একটি বৈশিষ্ট্যের তুলনা করব, টাইপ-ভিত্তিক বিধিনিষেধটি অপসারণ করা হয়েছে কারণ কেবলমাত্র এক প্রকারের প্রসারিত একটি এক্সটেনশন পদ্ধতির বিপরীতে কোনও বৈশিষ্ট্য ব্যবহার করা যেতে পারে any
বোল্টক্লক

1
খুব ভাল ভাষ্য - এবং আমি আপনার সাথে একমত। পুনরায় পড়ার ক্ষেত্রে, এটি একটি ভাল উপমা। আমি বিশ্বাস করি যে এটি আরও ভাল হিসাবে এখনও এটি হিসাবে বিবেচনা করা উচিত mixin- এবং আমি আমার উত্তরটি খোলার পুনর্বিবেচনা করেছি, আমি এটি প্রতিফলিত করার জন্য আপডেট করেছি। মন্তব্য করার জন্য ধন্যবাদ, @ বোল্টক্লক!
ট্রয় অ্যালফোর্ড

1
সি # এক্সটেনশন পদ্ধতির কোনও সম্পর্ক আছে বলে আমি মনে করি না। একক শ্রেণীর ধরণের (অবশ্যই শ্রেণীর শ্রেণিবিন্যাসকে সম্মান করে) প্রসারিত পদ্ধতিগুলি যুক্ত করা হয় তাদের উদ্দেশ্য হ'ল একাধিক শ্রেণীর উপর "কোড ভাগ করে নেওয়া" এবং কোনও বিশৃঙ্খলা তৈরি না করে অতিরিক্ত কার্যকারিতা সহ কোনও প্রকারকে বাড়ানো। এটি তুলনাযোগ্য নয়! যদি কোনও জিনিস পুনরায় ব্যবহারের প্রয়োজন হয়, তবে এর সাধারণত অর্থ হয় এর নিজস্ব স্থান থাকতে হবে, পৃথক শ্রেণীর মতো যা সাধারণ কার্যকারিতা প্রয়োজন এমন শ্রেণীর সাথে সম্পর্কিত। বাস্তবায়ন নকশার উপর নির্ভর করে পরিবর্তিত হতে পারে, তবে মোটামুটি এটি। বৈশিষ্ট্যগুলি দুর্বল কোড করার আরও একটি উপায় another
সোফিজা

একটি শ্রেণীর একাধিক ইন্টারফেস থাকতে পারে? আমি আপনার গ্রাফটি ভুল পেয়েছি কিনা তা নিশ্চিত নই, তবে দশম শ্রেণি Y, Z কার্যকর করে।
ইয়ান চাবোট

26

আমার মনে traitsহয় এমন ক্লাস তৈরিতে দরকারী যা এমন পদ্ধতি রয়েছে যা বিভিন্ন শ্রেণীর বিভিন্ন পদ্ধতি হিসাবে ব্যবহার করা যেতে পারে।

উদাহরণ স্বরূপ:

trait ToolKit
{
    public $errors = array();

    public function error($msg)
    {
        $this->errors[] = $msg;
        return false;
    }
}

আপনি এই বৈশিষ্ট্যটি ব্যবহার করে এমন কোনও ক্লাসে এই "ত্রুটি" পদ্ধতিটি ব্যবহার করতে এবং ব্যবহার করতে পারেন ।

class Something
{
    use Toolkit;

    public function do_something($zipcode)
    {
        if (preg_match('/^[0-9]{5}$/', $zipcode) !== 1)
            return $this->error('Invalid zipcode.');

        // do something here
    }
}

interfacesআপনার সাথে থাকাকালীন কেবল পদ্ধতি স্বাক্ষর ঘোষণা করতে পারে তবে এর কার্যকারিতা কোড নয়। এছাড়াও, একটি ইন্টারফেস ব্যবহার করতে আপনাকে ব্যবহার করে একটি শ্রেণিবিন্যাস অনুসরণ করতে হবে implements। বৈশিষ্ট্যের ক্ষেত্রে এটি হয় না।

একেবারে আলাদা!


আমি মনে করি এটি একটি বৈশিষ্ট্যের খারাপ উদাহরণ। to_integerকোনও IntegerCastইন্টারফেসে সম্ভবত যুক্ত হতে পারে কারণ কোনও পূর্ণসংখ্যার (বুদ্ধিমানের) কাস্ট ক্লাসের মৌলিকভাবে অনুরূপ উপায় নেই।
ম্যাথু

5
"To_integer" ভুলে যান - এটি কেবল একটি চিত্রণ। একটি উদাহরণ. একটি "হ্যালো, ওয়ার্ল্ড"। একটি "উদাহরণ.কম"।
জে ব্রুনি

2
এই সরঞ্জামকিট বৈশিষ্ট্যটি কী উপকারে জোগায় যে স্ট্যান্ডেলোন ইউটিলিটি ক্লাসটি পারে না? আপনার পরিবর্তে use Toolkitআপনি থাকতে পারতেন $this->toolkit = new Toolkit();বা আমি নিজেও বৈশিষ্ট্যের কিছু সুবিধা অনুভব করছি?
অ্যান্টনি

Somethingif(!$something->do_something('foo')) var_dump($something->errors);
@ অ্যান্টনি

20

উপরের উত্তর দেওয়া খুব কঠিন হতে পারে, এটি এটি বোঝার সহজতম উপায়:

বৈশিষ্ট

trait SayWorld {
    public function sayHello() {
        echo 'World!';
    }
}

সুতরাং যদি আপনি sayHelloপুরো ফাংশনটি পুনরায় তৈরি না করেই অন্য শ্রেণিতে ফাংশন করতে চান তবে আপনি বৈশিষ্ট্যগুলি ব্যবহার করতে পারেন,

class MyClass{
  use SayWorld;

}

$o = new MyClass();
$o->sayHello();

ঠিক কুল!

কেবল বৈশিষ্ট্যগুলিই আপনি বৈশিষ্ট্য (ফাংশন, ভেরিয়েবল, কনস্ট্যান্ড ..) ব্যবহার করতে পারেন। এছাড়াও আপনি একাধিক বৈশিষ্ট্য ব্যবহার করতে পারেন:use SayWorld,AnotherTraits;

ইন্টারফেস

  interface SayWorld {
     public function sayHello();
  }

  class MyClass implements SayWorld { 
     public function sayHello() {
        echo 'World!';
     }
}

সুতরাং এটি ইন্টারফেসের বৈশিষ্ট্যগুলির থেকে আলাদা কীভাবে: আপনাকে প্রয়োগিত শ্রেণিতে ইন্টারফেসের সবকিছু পুনরায় তৈরি করতে হবে। ইন্টারফেসের বাস্তবায়ন নেই। এবং ইন্টারফেসে কেবল ফাংশন এবং কনস্ট থাকতে পারে, এতে ভেরিয়েবল থাকতে পারে না।

আশা করি এটা কাজে লাগবে!


5

বৈশিষ্ট্যগুলি বর্ণনা করতে প্রায়শই ব্যবহৃত রূপকটি হ'ল বৈশিষ্ট্যগুলি হল বাস্তবায়নের সাথে ইন্টারফেস।

বেশিরভাগ পরিস্থিতিতে এটি সম্পর্কে চিন্তাভাবনার একটি ভাল উপায় তবে উভয়ের মধ্যে বেশ কয়েকটি সূক্ষ্ম পার্থক্য রয়েছে।

শুরু করার জন্য, instanceofঅপারেটর বৈশিষ্ট্যগুলির সাথে কাজ করবে না (অর্থাত্ কোনও বৈশিষ্ট্যটি সত্যিকারের বস্তু নয়) সুতরাং কোনও শ্রেণীর একটি নির্দিষ্ট বৈশিষ্ট্য রয়েছে কিনা তা দেখতে আপনি আমাদের দেখতে পারবেন না (বা অন্যথায় দুটি সম্পর্কহীন শ্রেণি একটি বৈশিষ্ট ভাগ করেছে কিনা তা দেখতে) )। অনুভূমিক কোডটি পুনরায় ব্যবহারের জন্য এটিই এটির অর্থ এটি।

পিএইচপি-তে এখন এমন ক্রিয়াকলাপ রয়েছে যা আপনাকে ক্লাসের জন্য ব্যবহার করা সমস্ত বৈশিষ্ট্যের একটি তালিকা পেতে দেয়, তবে বৈশিষ্ট্য-উত্তরাধিকারের অর্থ কোনও শ্রেণীর নির্দিষ্ট বৈশিষ্ট্য রয়েছে কিনা তা নির্ভরযোগ্যভাবে পরীক্ষা করতে আপনাকে পুনরাবৃত্ত চেকগুলি করতে হবে (উদাহরণ রয়েছে) পিএইচপি ডকো পৃষ্ঠাগুলিতে কোড)। তবে হ্যাঁ, এটি অবশ্যই সহজ এবং পরিষ্কার উদাহরণ হিসাবে নেই, এবং আইএমএইচও এটি এমন একটি বৈশিষ্ট্য যা পিএইচপি আরও ভাল করে তুলবে।

এছাড়াও, বিমূর্ত ক্লাসগুলি এখনও ক্লাস, তাই তারা একাধিক-উত্তরাধিকার সম্পর্কিত কোড পুনরায় ব্যবহারের সমস্যার সমাধান করে না। মনে রাখবেন আপনি কেবল একটি শ্রেণি (বাস্তব বা বিমূর্ত) প্রসারিত করতে পারেন তবে একাধিক ইন্টারফেস প্রয়োগ করতে পারেন।

আমি খুঁজে পেয়েছি বৈশিষ্ট্য এবং ইন্টারফেস সিউডো একাধিক উত্তরাধিকার তৈরি করতে হাতে হাতে ব্যবহার করা সত্যই ভাল। উদাহরণ:

class SlidingDoor extends Door implements IKeyed  
{  
    use KeyedTrait;  
    [...] // Generally not a lot else goes here since it's all in the trait  
}

এটি করার অর্থ আপনি নির্দিষ্ট ডোর অবজেক্টটি কেয়েড কিনা তা নির্ধারণের জন্য উদাহরণ ব্যবহার করতে পারবেন, আপনি জানেন যে আপনি পদ্ধতিগুলির একটি ধারাবাহিক সেট ইত্যাদি পাবেন এবং কীডট্রেট ব্যবহার করে সমস্ত কোডের মধ্যে সমস্ত কোড এক জায়গায় রয়েছে।


এই উত্তরের শেষ অংশটি অবশ্যই @rdlowrey তার পোস্টে "ট্রেইটস" এর অধীনে শেষ তিনটি অনুচ্ছেদে আরও বিশদে কী বলছেন; আমি কেবল অনুভব করেছি যে একটি সাধারণ কঙ্কালের কোড স্নিপেট এটি চিত্রিত করতে সহায়তা করবে।
জন ক্লসকে

আমি মনে করি যে বৈশিষ্ট্যগুলি ব্যবহারের সর্বোত্তম উপায় হ'ল ইন্টারফেসগুলি যেখানে আপনি পারেন তা ব্যবহার করে। এবং যদি এমন কোনও ঘটনা ঘটে থাকে যখন একাধিক সাবক্লাসগুলি সেই ইন্টারফেসের জন্য একই ধরণের কোড প্রয়োগ করে এবং আপনি সেই কোডটি তাদের (বিমূর্ত) সুপারক্লাসে স্থানান্তর করতে পারবেন না -> বৈশিষ্ট্য সহ এটি প্রয়োগ করতে পারেন
প্লেয়ার

4

বৈশিষ্ট্যগুলি কেবল কোড পুনরায় ব্যবহারের জন্য

ইন্টারফেস কেবলমাত্র ফাংশনগুলির স্বাক্ষর সরবরাহ করে যা ক্লাসে সংজ্ঞায়িত করা হয় যেখানে এটি প্রোগ্রামারের বিবেচনার ভিত্তিতে ব্যবহার করা যেতে পারে । এইভাবে আমাদের ক্লাসের একটি গ্রুপের জন্য একটি প্রোটোটাইপ দেওয়া

রেফারেন্সের জন্য- http://www.php.net/manual/en/language.oop5.traits.php


3

আপনি মূলত কোডের একটি স্বয়ংক্রিয় "অনুলিপি-পেস্ট" হিসাবে একটি বৈশিষ্ট্য বিবেচনা করতে পারেন।

বৈশিষ্ট্য ব্যবহার করা বিপজ্জনক কারণ মৃত্যুদন্ড কার্যকর হওয়ার আগে এটি কী করে তা জানার কোনও উপায় নেই।

তবে উত্তরাধিকার হিসাবে সীমাবদ্ধতার অভাবের কারণে বৈশিষ্ট্যগুলি আরও নমনীয়।

বৈশিষ্ট্যগুলি এমন কোনও পদ্ধতিতে ইনজেক্ট করতে কার্যকর হতে পারে যা কোনও শ্রেণিতে কিছু পরীক্ষা করে, উদাহরণস্বরূপ, অন্য পদ্ধতি বা বৈশিষ্ট্যের অস্তিত্ব। এ সম্পর্কে একটি দুর্দান্ত নিবন্ধ (তবে ফরাসি ভাষায়, দুঃখিত)

এটি পেতে পারে এমন ফরাসি-পঠনকারীদের জন্য, জিএনইউ / লিনাক্স ম্যাগাজিন এইচএস 54 এর এই বিষয়ে একটি নিবন্ধ রয়েছে।


ডিফল্ট বাস্তবায়নের সাথে ইন্টারফেস থেকে কীভাবে বৈশিষ্ট্যগুলি আলাদা তার এখনও পাবেন না
denis631

@ denis631 আপনি কোড স্নিপেট হিসাবে বৈশিষ্ট্য, এবং স্বাক্ষর চুক্তি হিসাবে ইন্টারফেস দেখতে পারেন। যদি এটি সহায়তা করতে পারে তবে আপনি এটিকে কোনও শ্রেণির একটি অনানুষ্ঠানিক বিট হিসাবে দেখতে পারেন যা কিছু থাকতে পারে। যদি এটি সাহায্য করে তবে আমাকে জানান।
বেনজ

আমি দেখতে পাচ্ছি যে পিএইচপি বৈশিষ্ট্যগুলি ম্যাক্রোগুলি হিসাবে দেখা যেতে পারে যা সংকলন সময়ে প্রসারিত / কেবল just কীটির সাথে কোড স্নিপেটকে বাদ দিয়ে। মরিচা বৈশিষ্ট্যগুলি পৃথকভাবে প্রদর্শিত হয় (বা আমি কী ভুল)। তবে যেহেতু এগুলির উভয়েরই শব্দের বৈশিষ্ট্য রয়েছে আমি তাদের ধরে নেওয়ার জন্য একই ধারণার অর্থ গ্রহণ করব meaning মরিচা বৈশিষ্ট্য লিঙ্ক: doc.rust-lang.org/rust-by-example/trait.html
অস্বীকার 631

2

আপনি যদি ইংরাজী জানেন এবং এর traitঅর্থ জানেন তবে নামটি যা বলে তা হ'ল। এটি টাইপ করে বিদ্যমান ক্লাসগুলির সাথে সংযুক্ত পদ্ধতি এবং বৈশিষ্ট্যের একটি শ্রেণিবর্গের প্যাক use

মূলত, আপনি এটি একটি একক ভেরিয়েবলের সাথে তুলনা করতে পারেন। ক্লোজার ফাংশনগুলি সুযোগগুলির useবাইরে থেকে এই ভেরিয়েবলগুলি করতে পারে এবং সেভাবে তাদের ভিতরে মূল্য থাকে। এগুলি শক্তিশালী এবং সবকিছুতে ব্যবহার করা যেতে পারে। বৈশিষ্টগুলি ব্যবহার করা হয় একইভাবে ঘটে।


2

অন্যান্য উত্তরগুলি ইন্টারফেস এবং বৈশিষ্ট্যের মধ্যে পার্থক্য ব্যাখ্যা করার দুর্দান্ত কাজ করে। আমি একটি দরকারী বাস্তব বিশ্বের উদাহরণের উপর ফোকাস করব, বিশেষত একটিতে যা দেখায় যে বৈশিষ্ট্যগুলি উদাহরণ ভেরিয়েবলগুলি ব্যবহার করতে পারে - আপনাকে ন্যূনতম বয়লারপ্লেট কোড সহ কোনও শ্রেণিতে আচরণ যুক্ত করতে দেয়।

আবার, অন্যদের দ্বারা উল্লিখিত মত, বৈশিষ্টগুলি ইন্টারফেসের সাথে ভালভাবে জুড়ি দেয়, ইন্টারফেসটিকে আচরণের চুক্তিটি নির্দিষ্ট করতে দেয় এবং বৈশিষ্ট্যটি বাস্তবায়নে পরিপূর্ণ হয়।

কোনও ক্লাসে ইভেন্ট প্রকাশ / সাবস্ক্রাইব ক্ষমতা যুক্ত করা কিছু কোড বেসগুলিতে একটি সাধারণ দৃশ্য হতে পারে। এখানে 3 টি সাধারণ সমাধান রয়েছে:

  1. ইভেন্টের পাব / সাব কোড সহ একটি বেস শ্রেণীর সংজ্ঞা দিন এবং তারপরে দক্ষতা অর্জনের জন্য যে ক্লাসগুলি ইভেন্টগুলির অফার করতে চায় সেগুলি এটি প্রসারিত করতে পারে।
  2. ইভেন্টের পাব / সাব কোড সহ একটি শ্রেণীর সংজ্ঞা দিন এবং তারপরে অন্যান্য শ্রেণিগুলি যা ইভেন্টগুলি দিতে চায় সেগুলি রচনাটির মাধ্যমে এটি ব্যবহার করতে পারে, রচনা অবজেক্টটি আবদ্ধ করার জন্য তাদের নিজস্ব পদ্ধতিগুলি সংজ্ঞায়িত করে, পদ্ধতিটির কলকে প্রক্সিং করে।
  3. ইভেন্ট পাব / সাব কোড সহ একটি বৈশিষ্ট্য সংজ্ঞায়িত করুন, এবং তারপরে অন্যান্য শ্রেণিগুলি যা ইভেন্টগুলি দিতে চায় useতা বৈশিষ্ট্য অর্জনের জন্য, বৈশিষ্টটি, এটি আমদানি করতে পারে।

প্রতিটি কাজ কতটা ভাল করে?

# 1 ভাল কাজ করে না। এটি হ'ল, যতক্ষণ না আপনি বুঝতে পারবেন যে আপনি বেস ক্লাসটি বাড়িয়ে দিতে পারবেন না কারণ আপনি ইতিমধ্যে অন্য কিছু প্রসারিত করছেন। আমি এর উদাহরণ দেখাব না কারণ এটি উত্তরাধিকারসূত্রে ব্যবহার করার জন্য এটি কতটা সীমাবদ্ধ তা স্পষ্ট হওয়া উচিত।

# 2 এবং # 3 উভয়ই ভাল কাজ করে। আমি একটি উদাহরণ দেখাব যা কিছু পার্থক্য তুলে ধরে।

প্রথমত, কিছু কোড যা উভয় উদাহরণের মধ্যে একই হবে:

একটি ইন্টারফেস

interface Observable {
    function addEventListener($eventName, callable $listener);
    function removeEventListener($eventName, callable $listener);
    function removeAllEventListeners($eventName);
}

এবং ব্যবহার দেখানোর জন্য কিছু কোড:

$auction = new Auction();

// Add a listener, so we know when we get a bid.
$auction->addEventListener('bid', function($bidderName, $bidAmount){
    echo "Got a bid of $bidAmount from $bidderName\n";
});

// Mock some bids.
foreach (['Moe', 'Curly', 'Larry'] as $name) {
    $auction->addBid($name, rand());
}

ঠিক আছে, এখন দেখা যাক Auctionবৈশিষ্টগুলি ব্যবহার করার সময় শ্রেণীর প্রয়োগ কীভাবে পৃথক হবে lets

প্রথমত, এখানে # 2 (রচনা ব্যবহার করে) দেখতে কেমন হবে:

class EventEmitter {
    private $eventListenersByName = [];

    function addEventListener($eventName, callable $listener) {
        $this->eventListenersByName[$eventName][] = $listener;
    }

    function removeEventListener($eventName, callable $listener) {
        $this->eventListenersByName[$eventName] = array_filter($this->eventListenersByName[$eventName], function($existingListener) use ($listener) {
            return $existingListener === $listener;
        });
    }

    function removeAllEventListeners($eventName) {
        $this->eventListenersByName[$eventName] = [];
    }

    function triggerEvent($eventName, array $eventArgs) {
        foreach ($this->eventListenersByName[$eventName] as $listener) {
            call_user_func_array($listener, $eventArgs);
        }
    }
}

class Auction implements Observable {
    private $eventEmitter;

    public function __construct() {
        $this->eventEmitter = new EventEmitter();
    }

    function addBid($bidderName, $bidAmount) {
        $this->eventEmitter->triggerEvent('bid', [$bidderName, $bidAmount]);
    }

    function addEventListener($eventName, callable $listener) {
        $this->eventEmitter->addEventListener($eventName, $listener);
    }

    function removeEventListener($eventName, callable $listener) {
        $this->eventEmitter->removeEventListener($eventName, $listener);
    }

    function removeAllEventListeners($eventName) {
        $this->eventEmitter->removeAllEventListeners($eventName);
    }
}

এখানে # 3 (বৈশিষ্ট্যগুলি) দেখতে কেমন হবে:

trait EventEmitterTrait {
    private $eventListenersByName = [];

    function addEventListener($eventName, callable $listener) {
        $this->eventListenersByName[$eventName][] = $listener;
    }

    function removeEventListener($eventName, callable $listener) {
        $this->eventListenersByName[$eventName] = array_filter($this->eventListenersByName[$eventName], function($existingListener) use ($listener) {
            return $existingListener === $listener;
        });
    }

    function removeAllEventListeners($eventName) {
        $this->eventListenersByName[$eventName] = [];
    }

    protected function triggerEvent($eventName, array $eventArgs) {
        foreach ($this->eventListenersByName[$eventName] as $listener) {
            call_user_func_array($listener, $eventArgs);
        }
    }
}

class Auction implements Observable {
    use EventEmitterTrait;

    function addBid($bidderName, $bidAmount) {
        $this->triggerEvent('bid', [$bidderName, $bidAmount]);
    }
}

নোট করুন যে শ্রেণীর ভিতরে থাকা কোডটি EventEmitterTraitহুবহু একইভাবে EventEmitterক্লাসের অভ্যন্তরে যেমন বৈশিষ্ট্যটি triggerEvent()পদ্ধতিটিকে সুরক্ষিত হিসাবে ঘোষণা করে ঠিক তেমনই is সুতরাং, আপনার কেবলমাত্র পার্থক্যটি দেখতে হবে Auctionশ্রেণীর বাস্তবায়ন

এবং পার্থক্য বড়। রচনা ব্যবহার করার সময়, আমরা একটি দুর্দান্ত সমাধান পাই, আমাদের পছন্দমতো EventEmitterক্লাস দ্বারা আমাদের পুনরায় ব্যবহার করার অনুমতি দেয় । তবে, প্রধান ত্রুটিটি হ'ল আমাদের কাছে প্রচুর বয়লারপ্লেট কোড রয়েছে যা আমাদের লিখতে ও বজায় রাখতে হবে কারণ Observableইন্টারফেসে সংজ্ঞায়িত প্রতিটি পদ্ধতির জন্য আমাদের এটি প্রয়োগ করা এবং বোরিং বয়লারপ্লিট কোড লিখতে হবে যা কেবলমাত্র যুক্তিটিকে সংশ্লিষ্ট পদ্ধতিতে প্রেরণ করে write আমাদের EventEmitterবস্তু রচনা । এই উদাহরণে বৈশিষ্ট্যটি ব্যবহার করা আমাদের এড়াতে দেয় , বয়লারপ্লেট কোড হ্রাস করতে এবং রক্ষণাবেক্ষণযোগ্যতা উন্নত করতে সহায়তা করে

যাইহোক, এমন সময় থাকতে পারে যেখানে আপনি চান না যে আপনার Auctionক্লাসটি পুরো Observableইন্টারফেসটি প্রয়োগ করবে - সম্ভবত আপনি কেবল 1 বা 2 টি পদ্ধতি উদ্ঘাটন করতে চান, বা এমনকি এমনকি কোনওটিই নয় যাতে আপনি নিজের পদ্ধতির স্বাক্ষরগুলি সংজ্ঞায়িত করতে পারেন। এই জাতীয় ক্ষেত্রে, আপনি এখনও রচনা পদ্ধতি পছন্দ করতে পারেন।

তবে, বেশিরভাগ দৃশ্যে বৈশিষ্ট্যটি খুব আকর্ষণীয়, বিশেষত যদি ইন্টারফেসের প্রচুর পদ্ধতি থাকে, যার ফলে আপনি প্রচুর বয়লারপ্লেট লেখেন।

* আপনি আসলে উভয়টিই করতে পারেন - EventEmitterআপনি যদি কখনও কাঠামোগতভাবে ব্যবহার করতে চান তবে ক্লাসটি সংজ্ঞায়িত করুন এবং EventEmitterTraitবৈশিষ্ট্যের EventEmitterঅভ্যন্তরে শ্রেণি প্রয়োগটি ব্যবহার করে বৈশিষ্ট্যটিও সংজ্ঞায়িত করুন :)


1

বৈশিষ্ট্যটি এক শ্রেণীর মতো যা আমরা একাধিক উত্তরাধিকারের উদ্দেশ্যে এবং কোড পুনরায় ব্যবহারযোগ্যতার জন্য ব্যবহার করতে পারি as

আমরা ক্লাসের ভিতরে বৈশিষ্ট্য ব্যবহার করতে পারি এবং একইসাথে 'ব্যবহার কীওয়ার্ড' দিয়ে একাধিক বৈশিষ্ট্যও ব্যবহার করতে পারি।

ইন্টারফেসটি কোডের পুনরায় ব্যবহারযোগ্যতার জন্য একটি বৈশিষ্ট হিসাবে ব্যবহার করা হচ্ছে

ইন্টারফেসটি একাধিক ইন্টারফেস প্রসারিত করে যাতে আমরা একাধিক উত্তরাধিকারের সমস্যাগুলি সমাধান করতে পারি তবে যখন আমরা ইন্টারফেসটি বাস্তবায়ন করি তখন আমাদের ক্লাসের ভিতরে সমস্ত পদ্ধতি তৈরি করা উচিত। আরও তথ্যের জন্য নীচের লিঙ্কে ক্লিক করুন:

http://php.net/manual/en/language.oop5.traits.php http://php.net/manual/en/language.oop5.interfaces.php


1

একটি ইন্টারফেস একটি চুক্তি যা বলে যে "এই বস্তুটি এই জিনিসটি করতে সক্ষম হয়", অন্যদিকে একটি বৈশিষ্ট্য বস্তুকে জিনিসটি করার ক্ষমতা দেয়।

ক্লাসের মধ্যে কোডটি "অনুলিপি এবং পেস্ট" করার একটি বৈশিষ্ট হ'ল মূলত।

এই নিবন্ধটি পড়ার চেষ্টা করুন, পিএইচপি বৈশিষ্ট্যগুলি কী কী?


0

মূল পার্থক্যটি হ'ল, ইন্টারফেসগুলির সাথে, আপনাকে অবশ্যই প্রতিটি শ্রেণীর মধ্যে প্রতিটি পদ্ধতির প্রকৃত বাস্তবায়ন সংজ্ঞায়িত করতে হবে যা বলেছেন ইন্টারফেস প্রয়োগ করে, তাই আপনার অনেকগুলি ক্লাস একই ইন্টারফেস প্রয়োগ করতে পারে তবে ভিন্ন আচরণের সাথে, যখন বৈশিষ্টগুলি কেবলমাত্র কোডের কিছু অংশ ইনজেকশনে থাকে একটি শ্রেণী; আর একটি গুরুত্বপূর্ণ পার্থক্য হ'ল বৈশিষ্ট্য পদ্ধতিগুলি কেবল শ্রেণি-পদ্ধতি বা স্ট্যাটিক-পদ্ধতি হতে পারে, ইন্টারফেস পদ্ধতির বিপরীতে যা (এবং সাধারণত) উদাহরণ পদ্ধতিও হতে পারে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.