কীভাবে বৈশিষ্ট্য ফাংশনকে ওভাররাইড করতে হবে এবং ওভাররাইড ফাংশন থেকে এটিকে কল করবেন?


369

দৃশ্যপট:

trait A {
    function calc($v) {
        return $v+1;
    }
}

class MyClass {
    use A;

    function calc($v) {
        $v++;
        return A::calc($v);
    }
}

print (new MyClass())->calc(2); // should print 4

এই কোডটি কাজ করে না, এবং উত্তরাধিকার সূত্রে যেমন কোনও বৈশিষ্ট্য ফাংশন কল করার কোনও উপায় আমি পাই না। আমি কলিং চেষ্টা self::calc($v), static::calc($v), parent::calc($v),A::calc($v) এবং নিম্নলিখিত:

trait A {
    function calc($v) {
        return $v+1;
    }
}

class MyClass {
    use A {
        calc as traitcalc;
    }

    function calc($v) {
        $v++;
        return traitcalc($v);
    }
}

কিছুই কাজ করে না।

এটি কার্যকর করার কোনও উপায় আছে বা আমার অবশ্যই এটির চেয়ে আরও জটিল জটিল বৈশিষ্ট্য ফাংশনটি সম্পূর্ণরূপে ওভাররাইড করতে হবে :)

উত্তর:


640

আপনার শেষটি প্রায় সেখানে ছিল:

trait A {
    function calc($v) {
        return $v+1;
    }
}

class MyClass {
    use A {
        calc as protected traitcalc;
    }

    function calc($v) {
        $v++;
        return $this->traitcalc($v);
    }
}

বৈশিষ্ট্য কোনও শ্রেণি নয়। আপনি এর সদস্যদের সরাসরি অ্যাক্সেস করতে পারবেন না। এটি মূলত কেবল স্বয়ংক্রিয় কপি এবং পেস্ট করা ...


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

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

1
সমস্যাটি হ'ল বৈশিষ্ট্যের অন্যান্য সমস্ত পদ্ধতি আর অন্তর্ভুক্ত নয়।
মালহাল

2
আপনার বৈশিষ্ট্য ফাংশন স্ট্যাটিক হতো আপনি কলিং ফাংশন অ্যাক্সেস করতে পারে: শুধু রেফারেন্সের জন্যA::calc(1)
velop

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

14

যদি শ্রেণিটি সরাসরি পদ্ধতিটি প্রয়োগ করে তবে এটি বৈশিষ্ট্য সংস্করণ ব্যবহার করবে না। সম্ভবত আপনি যা ভাবছেন তা হ'ল:

trait A {
    function calc($v) {
        return $v+1;
    }
}

class MyClass {
    function calc($v) {
        return $v+2;
    }
}

class MyChildClass extends MyClass{
}

class MyTraitChildClass extends MyClass{
    use A;
}

print (new MyChildClass())->calc(2); // will print 4

print (new MyTraitChildClass())->calc(2); // will print 3

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

আপনি যদি চান তবে বৈশিষ্টটি পিতামাত্ত শ্রেণিতে পদ্ধতি ব্যবহার করতে পারে (ধরে নিলে পদ্ধতিটি উপস্থিত থাকবে তা ধরে নিই) উদাহরণস্বরূপ

trait A {
    function calc($v) {
        return parent::calc($v*3);
    }
}
// .... other code from above
print (new MyTraitChildClass())->calc(2); // will print 8 (2*3 + 2)

আপনি ওভাররাইড করার উপায়গুলি সরবরাহ করতে পারেন, তবে তবুও নিম্নলিখিত বৈশিষ্ট্য পদ্ধতিটি অ্যাক্সেস করুন:

trait A {
    function trait_calc($v) {
        return $v*3;
    }
}

class MyClass {
    function calc($v) {
        return $v+2;
    }
}


class MyTraitChildClass extends MyClass{
    use A {
      A::trait_calc as calc;
    }
}


class MySecondTraitChildClass extends MyClass{
    use A {
      A::trait_calc as calc;
    }

    public function calc($v) {
      return $this->trait_calc($v)+.5;
    }
}


print (new MyTraitChildClass())->calc(2); // will print 6
echo "\n";
print (new MySecondTraitChildClass())->calc(2); // will print 6.5

আপনি এটি http://sandbox.onlinephpfunifications.com/code/e53f6e8f9834aea5e038aec4766ac7e1c19cc2b5 এ কাজ করতে দেখতে পারেন


8

আগ্রহী হলে বিকল্প বিকল্প - সাধারণ ওওও উপায় ব্যবহার করার জন্য একটি অতিরিক্ত মধ্যবর্তী শ্রেণি সহ। এটি প্যারেন্ট :: পদ্ধতিতে ব্যবহারের সাথে সহজ করে তোলে

trait A {
    function calc($v) {
        return $v+1;
    }
}

// an intermediate class that just uses the trait
class IntClass {
    use A;
}

// an extended class from IntClass
class MyClass extends IntClass {
    function calc($v) {
        $v++;
        return parent::calc($v);
    }
}

6
এই পদ্ধতিটি ব্যবহার করে আপনার যে কোনও সুবিধা শেভ করবে trait। একাধিক ক্লাসে একাধিক বৈশিষ্ট্যের সংমিশ্রণের মতো (যেমন বৈশিষ্ট্য A, B একটি শ্রেণিতে বৈশিষ্ট্য, B, C, D অন্য শ্রেণিতে বৈশিষ্ট্য A, C অন্য শ্রেণিতে বৈশিষ্ট্যযুক্ত)
Ionuț Staicu

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

এটি পুরোপুরি আমার পক্ষে কাজ করবে না। ScreenablePerson::save()উপস্থিত রয়েছে, বৈশিষ্ট্য Candidateব্যবহার Validatingকরে এবং প্রসারিত করে এবং ScreenablePersonতিনটি শ্রেণীরই রয়েছে save()
থিওডোর আর স্মিথ

1

অন্য বৈশিষ্ট্য ব্যবহার:

trait ATrait {
    function calc($v) {
        return $v+1;
    }
}

class A {
    use ATrait;
}

trait BTrait {
    function calc($v) {
        $v++;
        return parent::calc($v);
    }
}

class B extends A {
    use BTrait;
}

print (new B())->calc(2); // should print 4
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.