soheil moonesi
soheil moonesi
خواندن ۵ دقیقه·۹ ماه پیش

C# : Virtual vs Override vs New Keyword

هدف این مطلب توضیح این سه تاست و این که چه تفاوت هایی با هم دارند.

این متن از این سایت گرفته شده و ترجمه شده.

Virtual Keyword

Virtual keyword is used for generating a virtual path for its derived classes on implementing method overriding. Virtual keyword is used within a set with override keyword. It is used as:

خوب حالا بیایم برای توضیح این متن بالا با مثال شروع کنیم.

ولی قبلش یه توضیح ای که باید بدم اینه که drived class یعنی کلاسی که از کلاس پایه درست شده و مشتق شده.

// Base Class class A { public virtual void show() { Console.WriteLine('Hello: Base Class!'); Console.ReadLine(); } }

خوب کلاس A رو فرض کنید کلاس پایه است.

Override Keyword

Override keyword is used in the derived class of the base class in order to override the base class method. Override keyword is used with virtual keyword, as:

// Base Class class A { public virtual void show() { Console.WriteLine('Hello: Base Class!'); Console.ReadLine(); } } // Derived Class class B : A { public override void show() { Console.WriteLine('Hello: Derived Class!'); Console.ReadLine(); } }

اینجا کلاس ‌B میشه کلاس مشتق شده از کلاس A . خوب همونطوری که میبینید توی کلاس اصلی و پایه اومدیم از virtual استفاده کردیم و توی کلاس مشتق شده از override استفاده کردیم. چرا؟ جلوتر میفهمیم.

آها، قبلش ولی New Keyword رو هم یه مثال براش بزنیم:

New keyword is also used in polymorphism concept, but in the case of method overloading So what does overloading means, in simple words we can say procedure of hiding your base class through your derived class.

It is implemented as:

class A { public void show() { Console.WriteLine('Hello: Base Class!'); Console.ReadLine(); } } class B : A { public new void show() { Console.WriteLine('Hello: Derived Class!'); Console.ReadLine(); } }

حالا بریم سره اصل قضیه :

using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Virgol { class A { public void show() { Console.WriteLine('Hello: Base Class!'); Console.ReadLine(); } } class B : A { public void show() { Console.WriteLine('Hello: Derived Class!'); Console.ReadLine(); } public void something(){ Console.WriteLine('Hello: Derived Class!'); Console.ReadLine(); } } class Polymorphism { public static void Main() { A a1 = new A(); a1.show(); B b1 = new B(); b1.show(); A a2 = new B(); a2.show(); } } }

خوب یه بررسی کنیم از اول این کد: اول اومدیم کلاس A رو ساختیم ، بعد اومدیم کلاس B رو از کلاس A ساختیم و مشتق گرفتیم. بعد هم اومدیم هر کدوم این ها رو یه نمونه ازشون درست کردیم و بعد از متد show برای چاپ در کنسول استفاده کردیم.

فقط یه نکته ای اینجا هستش :

A a2 = new B(); a2.show();

اینجا اومدیم یه نمونه از کلاس B درست کردیم و ریختیمش داخل a2 که از نوع کلاس A هستش. مگه میشه ؟ آره میشه. توی C# میشه مقدار کلاس مشتق شده رو داخل متغییر از نوع و تایپ کلاس پایه ریخت. ولی اتفاقی که اینجا میوفته اینه که دیگه توی این حالت به متد ها و اجزای داخل کلاس ‌B دسترسی نداریم (یعنی به متد something هم دسترسی نداریم) و فقط به کلاس A دسترسی داریم. در این حالت هیچ خطایی دریافت نمیکنیم ولی یه warning داریم :

The keyword 'new' is required on 'show' because it hides method 'void Virgol.A.show()'

اینجا virgol اسمه namespace هستش و داره میگه که برای رفع این warning باید از کلمه new استفاده کنید. برای رفع warning میایم توی کلاس B به این شکل مینویسیم:

public new void show()

در دو حالت خروجی که داریم به این ترتیبه :

Hello: Base Class!

Hello: Derived Class!

Hello: Base Class!

حالا سوالی که برای خودم پیش اومده اینه که خوب که چی؟ چرا اینجا از override و virtual استفاده نشد. خوب طبیعتا برای این که بفهمیم که این دو تا چی کار میکنن، باید قبلش ببینیم ببینیم که بدون این ها چطوری داره کار میکنه و بعدش چطوری کار میکنه.

حالا دیگه جدی میرسیم به

Virtual & Override Keywords | Method Overriding

using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Virgol { class A { public virtual void show() { Console.WriteLine('Hello: Base Class!'); Console.ReadLine(); } } class B : A { public override void show() { Console.WriteLine('Hello: Derived Class!'); Console.ReadLine(); } public void something() { Console.WriteLine('write something'); } } class Polymorphism { public static void Main() { A a1 = new A(); a1.show(); B b1 = new B(); b1.show(); A a2 = new B(); a2.show(); } } }

خوب حالا بررسی کنیم خروجی رو :

Hello: Base Class!

Hello: Derived Class!

Hello: Derived Class!

همونطوری که میبینید خروجی a2.show تغییر کرده و شده Hello: Derived Class چرا؟

برای این که ما بخوایم متدی رو override کنیم باید اون متد در کلاس پایه virtual تعریف شده باشه.

خوب ما این کار رو انجام دادیم که هر وقت که اومدیم یه نمونه از کلاس B ساختیم و خواستیم اون رو داخل متغییری از کلاس A ریختیم همچنان بتونیم از متدی که داخل کلاس B هستش استفاده کنیم.

فقط نکته ای که هست ما فقط به متدی که override شده میتونیم دسترسی پیدا کنیم و همچنان متد something وقتی که میخوایم از a2 استفاده کنیم از دسترس خارجه.

یه مثال دیگه :

Overriding + Hiding | Together

namespace Generics { class A { public virtual void show() { Console.WriteLine('Hello: Base Class!'); Console.ReadLine(); } } class B : A { public override void show() { Console.WriteLine('Hello: Derived Class!'); Console.ReadLine(); } } class C : B { public new void show() { Console.WriteLine('Am Here!'); Console.ReadLine(); } } class Polymorphism { public static void Main() { A a1 = new A(); a1.show(); B b1 = new B(); b1.show(); C c1 = new C(); c1.show(); A a2 = new B(); a2.show(); A a3 = new C(); a3.show(); B b3 = new C(); b3.show(); } } }

حالا خروجی به این شکل میشه :

Hello: Base Class! Hello: Derived Class! Am Here! Hello: Derived Class! Hello: Derived Class! Hello: Derived Class!

خوب حالا بیایم بررسی کنیم:

A a2 = new B(); a2.show(); //output: Hello: Derived Class!

اینجا چون متد show رو override کردیم طبیعتا این خروجی رو به ما میده

A a3 = new C(); a3.show(); //output: Hello: Derived Class!

توی مورد بالا اومدیم کلاس C که خودش مشتق شده کلاس B هستش و در کلاس B اومدیم متد show که در کلاس A به صورت virtual تعریف شده رو override کردیم.

B b3 = new C(); b3.show(); //output: Hello: Derived Class!

اینجا هم اومدیم کلاس C رو که مشتق گرفته شده از کلاس B هستش رو داخل متغییر با تایپ B ریختیم.


new keywordbase classderived classhello derivedclass public
C# enthusiast
شاید از این پست‌ها خوشتان بیاید