শেডিং এবং সি # তে ওভাররাইডের মধ্যে পার্থক্য?


103

সি # তে কোনও পদ্ধতির ছায়া কাটা এবং ওভাররাইডের মধ্যে পার্থক্য কী ?

উত্তর:


154

উত্তম উত্তরাধিকার ...

ধরুন আপনার এই ক্লাস রয়েছে:

class A {
   public int Foo(){ return 5;}
   public virtual int Bar(){return 5;}
}
class B : A{
   public new int Foo() { return 1;}     //shadow
   public override int Bar() {return 1;} //override
}

তারপর যখন আপনি এই কল:

A clA = new A();
B clB = new B();

Console.WriteLine(clA.Foo()); // output 5
Console.WriteLine(clA.Bar()); // output 5
Console.WriteLine(clB.Foo()); // output 1
Console.WriteLine(clB.Bar()); // output 1

//now let's cast B to an A class
Console.WriteLine(((A)clB).Foo()); // output 5 <<<-- shadow
Console.WriteLine(((A)clB).Bar()); // output 1

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

এখানে কোড চালান

আশা করি আমি বোধ করছি :)


17
ওভাররাইডিং বহুমুখীতা সরবরাহ করে, ছায়া গোছানো স্তরক্রমের সেই স্তরে একটি পৃথক বাস্তবায়ন সরবরাহ করে, তবে বহুরূপী নয়।
ডেভিড রদ্রিগেজ - ড্রিবিস

@ ড্রিবিস, আপনি এই উপসংহারটি আঁকতে বহুমুখের কোন সংজ্ঞা ব্যবহার করবেন?
অ্যান্থনিডব্লু জোন্স 13

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

4
আমার কাছে মনে হচ্ছে, আপনার নমুনা কোডটিতে আপনার একটি ত্রুটি রয়েছে। কাস্টিংটি ((A) ক্লিবি) হওয়া উচিত ooফু (), তাই না?
ট্রেন্ডেল

4
না, কারণ বারটি ভার্চুয়াল, তাই এটি এখনও বি বার
স্টোরমনেট

32

শেডিং আসলে ভিবি পার্লান্স যা আমরা সি # তে লুকিয়ে থাকি।

প্রায়শই লুকিয়ে থাকে (ভিবিতে ছায়া দেওয়া) এবং ওভাররাইডিং স্টোরমনেটের উত্তর হিসাবে প্রদর্শিত হয় ।

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

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

তবে প্রায়শই যা মিস হয় তা হ'ল ভার্চুয়াল পদ্ধতিটি আড়াল করাও সম্ভব।

class A
{
    public virtual void DoStuff() { // original implementation }
}

class B : A
{
    public new void DoStuff() {  //new implementation }
}

B b = new B();
A a = b;

b.DoStuff(); //calls new implementation
a.DoStuff(); //calls original implementation.

উপরের উদাহরণে নোট করুন ডস্টফ কংক্রিট হয়ে যায় এবং ওভাররাইড করা যায় না। তবে উভয় virtualএবং newকীওয়ার্ড একসাথে ব্যবহার করাও সম্ভব ।

class A
{
    public virtual void DoStuff() { // original implementation }
}

class B : A
{
    public new virtual void DoStuff() {  //new implementation }
}

class C : B
{
    public override void DoStuff() { //replacement implementation }
}

C c = new C();
B b = c;
A a = b;

c.DoStuff(); //calls replacement implementation
b.DoStuff(); //calls replacement implementation
a.DoStuff(); //calls original implementation.

নোট করুন যে সমস্ত পদ্ধতি ভার্চুয়াল হওয়ার সাথে জড়িত থাকা সত্ত্বেও, সিটিতে ওভাররাইড A এর উপর ভার্চুয়াল পদ্ধতিকে প্রভাবিত করে না কারণ newবিতে ব্যবহারের ফলে A বাস্তবায়ন আড়াল হয়।

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

আপনি যদি অ্যাক্সেসিবিলিটি মডিফায়ারগুলি পরিবর্তন করেন তবে বিশেষত আপনি সমস্ত ধরণের সমস্যায় পড়তে পারেন। উদাহরণ স্বরূপ:-

public class Foo
{
    internal Foo() { }
    protected virtual string Thing() { return "foo"; }
}

public class Bar : Foo
{
 internal new string Thing() { return "bar"; }
}

এর বাহ্যিক উত্তরাধিকারীর কাছে Bar, Fooথিংয়ের প্রয়োগ () বাস্তবায়ন অ্যাক্সেসযোগ্য এবং অতিক্রমযোগ্য remains .NET টাইপ বিধি অনুসারে সমস্ত আইনী এবং ব্যাখ্যাযোগ্য নিরবচ্ছিন্নভাবে বেশ অনিচ্ছাকৃত।

কীভাবে নিখরচায় ব্যবহার করা যেতে পারে এমন কৌশলগুলির পরামর্শ হিসাবে জিনিসগুলি কীভাবে কাজ করে না তা বোঝার জন্য আমি এই উত্তরটি পোস্ট করেছি।


4
জেনে ভালো লাগলো. তবে এটির ব্যবহার বিপজ্জনক হতে পারে :)
স্টোরমনেট

4
সঠিকভাবে ব্যবহার না করা হলে সমস্ত সরঞ্জাম বিপজ্জনক হতে পারে।
অ্যান্থনিডব্লু জোন্স 13

4
কিন্তু, এটি ব্যবহারযোগ্যতা সত্যই সন্দেহজনক বলে মনে হচ্ছে! এটি ব্যবহার করে কোনও 'গুরুতর' ওপেন সোর্স অ্যাপ রয়েছে?
জক্স

4
ব্যবহারযোগ্যতা? আপনি কি দরকারীতা বলতে চান? সামনের কিছু অংশ আপনার প্রয়োজন না হওয়া অবধি অব্যর্থ মনে হতে পারে।
অ্যান্টনিডব্লু জোন্স 16

মনে হচ্ছে শেডিং কেবলমাত্র ভার্চুয়াল এবং নতুন নাটকগুলিতে ছবিতে আসে। @ স্টর্মেনেটগুলি কেবল ওভাররাইড জিনিসটি ব্যাখ্যা করছে কারণ শ্রেণিটি ভার্চুয়াল না হলে তার নিজস্ব পদ্ধতিটি কল করা স্বাভাবিক আচরণ।
সুমিত কাপাদিয়া

6

আমি মনে করি মূল পার্থক্যটি হ'ল ছায়ার সাথে আপনি মূলত নামটি পুনরায় ব্যবহার করছেন, এবং কেবল সুপারক্লাস ব্যবহারকে উপেক্ষা করছেন। ওভাররাইড সহ, আপনি প্রয়োগ পরিবর্তন করছেন, তবে অ্যাক্সেসযোগ্যতা এবং স্বাক্ষর নয় (যেমন প্যারামিটারের ধরন এবং প্রত্যাবর্তন)। Http://www.geekinterview.com / প্রশ্ন_ডেটেল / ১৯৩৩১ দেখুন ।


5

ছায়া গো একটি VB.NET ধারণা। সি # তে, ছায়া গো লুকানো হিসাবে পরিচিত। এটি উত্পন্ন শ্রেণিবদ্ধ পদ্ধতি লুকায়। এটি 'নতুন' কীওয়ার্ড ব্যবহার করে সম্পন্ন হয়েছে।

ওভাররাইড কীওয়ার্ডটি প্রাপ্ত বর্গে একটি বেস ক্লাস পদ্ধতির (যা 'ভার্চুয়াল' চিহ্নিত করা হয়) সম্পূর্ণ নতুন বাস্তবায়ন সরবরাহ করতে ব্যবহৃত হয়।


তুমি বলতে চাচ্ছ এটি পরিবর্তিত বেস শ্রেণীর পদ্ধতিটি পরিবর্তিত বর্ধিত শ্রেণি পদ্ধতিটি গোপন করে। ?
শাইজুত

0

মূলত যদি আপনার নীচের মতো কিছু থাকে,

Class A
{
}

Class B:A
{
}

A a = new B();

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

কিছু পরিস্থিতিতে আপনাকে রেফারেন্স ক্লাসের কোনও পদ্ধতিটি কল করতে হবে যা নির্দিষ্ট মুহুর্তে অবজেক্টের ধরণে কোনও পদ্ধতি কল করার পরিবর্তে instance উপরের ক্ষেত্রে এটিতে থাকা রেফারেন্সটি 'বি', তবে প্রকারটি 'এ'। সুতরাং আপনি যদি চান যে পদ্ধতি কলটি 'বি' তে ঘটেছিল, তবে আপনি এটি অর্জন করতে ভার্চুয়াল এবং ওভাররাইড ব্যবহার করেন।

আশাকরি এটা সাহায্য করবে...

ড্যানিয়েল সন্দীপ।


0

যদি এমন কোনও কেস থাকে যেখানে আপনি কোনও শ্রেণীর বিষয়বস্তু পরিবর্তন করতে পারবেন না A, তবে বলা যাক , তবে আপনি কিছু পদ্ধতি ব্যবহার করতে চাইছেন পাশাপাশি একটি পদ্ধতি যা নাম সাধারণ, আপনি newকীওয়ার্ড দ্বারা নিজের পদ্ধতি প্রয়োগ করতে পারবেন ।

ক্রুक्स পয়েন্টটি এটি ব্যবহার করতে হবে যে রেফারেন্স এবং অবজেক্ট উভয়ই একই ধরণের হওয়া উচিত।

class A
{
    public void Test()
    {
        Console.WriteLine("base");
    }
}

class B : A
{
    public new void Test()
    {
        Console.WriteLine("sub");
    }

    public static void Main(string[] args)
    {
        A a = new A();
        B aa = new B();
        a.Test();
        aa.Test();
    }
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.