การโอเวอร์โหลดและการลบล้าง


105

อะไรคือความแตกต่างระหว่างการโอเวอร์โหลดและการลบล้าง


2
@james: อย่างน้อยคุณลองใช้ Google หรือไม่
Mitch Wheat

ฉันเดาว่าคุณจะไม่ได้รับสิ่งนี้
Jon B

เจมส์ - อาจจะไม่ใช่และฉันรู้สึกโง่มากที่ไม่สามารถอธิบายแนวคิดง่ายๆ

1
@james ฉันเดาว่าคุณเข้าใจแนวคิดเหล่านี้โดยไม่ทราบเงื่อนไข ฉันจะเดาว่าคุณสอนตัวเอง คุณควรจะหยิบหนังสือระดับ C # ระดับเริ่มต้นไม่ใช่เพื่อเรียนรู้ แต่เพื่อเสริมสร้างสิ่งที่คุณรู้อยู่แล้ว เป็นเรื่องที่ทำให้มึนงง แต่จะช่วยได้มากในการสัมภาษณ์ทางเทคนิค
Michael Meadows

สามารถอ่านรายละเอียดเพิ่มเติมได้ที่ลิงค์นี้: intquesans.blogspot.com/2011/05/…

คำตอบ:


220

โอเวอร์โหลด

การโอเวอร์โหลดคือการที่คุณมีหลายวิธีในขอบเขตเดียวกันโดยใช้ชื่อเดียวกัน แต่มีลายเซ็นต่างกัน

//Overloading
public class test
{
    public void getStuff(int id)
    {}
    public void getStuff(string name)
    {}
}

การลบล้าง

การลบล้างเป็นหลักการที่ช่วยให้คุณเปลี่ยนการทำงานของเมธอดในคลาสย่อย

//Overriding
public class test
{
        public virtual void getStuff(int id)
        {
            //Get stuff default location
        }
}

public class test2 : test
{
        public override void getStuff(int id)
        {
            //base.getStuff(id);
            //or - Get stuff new location
        }
}

1
ฉันชอบคำตอบนี้ @cgreeno .. ขอบคุณ
Ferrakkem Bhuiyan

1
@cgreeno ฉันคิดว่าคุณควรพลาดvoidสำหรับgetStuffในtest2
มาห์

2
เพียงแค่พูดถึงว่าเมธอดคลาสพื้นฐานจะต้องถูกทำเครื่องหมายเป็นเสมือนเพื่อแทนที่คุณจะได้รับข้อผิดพลาดในการคอมไพล์
Alex Stephens

นี่อาจจะเก่าแล้ว แต่ฉันยังมีคำถามเกี่ยวกับเรื่องนี้ การใช้งานมากเกินไปทำให้สามารถใช้งานได้มากขึ้นด้วยวิธี 'one' หรือไม่? อย่างที่ฉันทำได้: getStuff(2, "Hello world!");หรือฉันทำได้getStuff("Myname", "Mysurname", "Hello World!");? ทุกคนสามารถยืนยันว่านี่เป็นวิธีที่จะทำหรือไม่
Sj03rs

ฉันคิดว่าตัวอย่างการแทนที่จริง ๆ แล้วคือการเขียนทับการแทนที่คือเมื่อคุณใช้เมธอดระดับซูเปอร์คลาสได้รับการแทนที่โดยบังเอิญหรือถ้าคุณต้องการทำโดยใช้คีย์เวิร์ดใหม่ในทั้งสองกรณีแทนที่หรือเขียนทับพฤติกรรมจะแตกต่างกันเมื่อคุณประกาศพาเรนต์ p = new เด็ก(); น. วิธีการ (); ... บางทีฉันอาจจะคิดผิดและมันก็เป็นอีกวิธีหนึ่งในการทำสิ่งเดียวกัน ใครจะระเบิดได้ดีกว่าฉัน
Cristina Carrasco

35

คำจำกัดความง่ายๆสำหรับการโอเวอร์โหลดและการลบล้าง

การโอเวอร์โหลด (Compile Time Polymorphism) :: ฟังก์ชันที่มีชื่อเดียวกันและพารามิเตอร์ต่างกัน

public class A
{
    public void print(int x, int y)
    {
        Console.WriteLine("Parent Method");
    }
}

public class B : A
{
    public void child()
    {
        Console.WriteLine("Child Method");
    }

    public void print(float x, float y)
    {
        Console.WriteLine("Overload child method");
    }
}

การแทนที่ (ความแตกต่างของเวลาทำงาน) :: ฟังก์ชันในคลาสขยายที่มีชื่อเดียวกันและพารามิเตอร์เดียวกันกับในคลาสพื้นฐาน แต่มีพฤติกรรมที่แตกต่างกัน

public class A
{
    public virtual void print()
    {
        Console.WriteLine("Parent Method");
    }
}

public class B : A
{
    public void child()
    {
        Console.WriteLine("Child Method");
    }

    public override void print()
    {
        Console.WriteLine("Overriding child method");
    }
}

บางทีคุณอาจต้องการเพิ่มว่าแนวคิดการลบล้างใช้กับความสัมพันธ์คลาสย่อยระดับพาเรนต์ - คลาส
Freakyuser

10

ฉันต้องการแบ่งปันตัวอย่างที่เข้าท่ามากสำหรับฉันเมื่อฉันเรียนรู้:

นี่เป็นเพียงตัวอย่างที่ไม่รวมเมธอดเสมือนหรือคลาสพื้นฐาน เพียงเพื่อให้คำแนะนำเกี่ยวกับแนวคิดหลัก

สมมติว่ามีเครื่องซักผ้ารถยนต์และมีฟังก์ชันที่เรียกว่า "Wash" และยอมรับรถยนต์เป็นประเภทหนึ่ง

รับข้อมูลรถและล้างรถ

public void Wash(Car anyCar){
       //wash the car
}

มาฟังก์ชั่น Overload Wash () กันเถอะ

โอเวอร์โหลด:

public void Wash(Truck anyTruck){
   //wash the Truck  
}

ฟังก์ชั่นล้างเป็นเพียงการล้างรถก่อนหน้านี้ แต่ตอนนี้ก็มีภาระมากเกินไปในการล้างรถบรรทุกเช่นกัน

  • หากวัตถุป้อนข้อมูลที่ให้มาเป็นรถยนต์ก็จะดำเนินการล้าง (Car anyCar)
  • หากวัตถุป้อนข้อมูลที่ให้มาเป็นรถบรรทุกก็จะดำเนินการ Wash (Truck anyTruck)

มาแทนที่ฟังก์ชัน Wash ()

การลบล้าง:

public override void Wash(Car anyCar){
   //check if the car has already cleaned
   if(anyCar.Clean){ 
       //wax the car
   }
   else{
       //wash the car
       //dry the car
       //wax the car
   }     
}

ฟังก์ชั่นล้างตอนนี้มีเงื่อนไขในการตรวจสอบว่ารถสะอาดอยู่แล้วหรือไม่และไม่จำเป็นต้องล้างอีก

  • ถ้ารถสะอาดก็แค่แว็กซ์

  • ถ้าไม่สะอาดให้ล้างรถก่อนจากนั้นซับให้แห้งแล้วลงแว็กซ์

.

ดังนั้นฟังก์ชันจึงถูกลบล้างโดยการเพิ่มฟังก์ชันใหม่หรือทำสิ่งที่แตกต่างออกไปโดยสิ้นเชิง


1
นี่ต้องเป็นคำตอบ โหวต +
แจ็ค

9
  • Overloading = ลายเซ็นหลายวิธีชื่อวิธีการเดียวกัน
  • Overriding = ลายเซ็นวิธีเดียวกัน (ประกาศเสมือน) นำไปใช้ในคลาสย่อย

ผู้สัมภาษณ์ที่ชาญฉลาดจะติดตาม:

อะไรคือความแตกต่างระหว่างการลบล้างและการสร้างเงา?


ไม่เคยรู้มาก่อนว่ามันถูกเรียกว่าเงา ความสัมพันธ์เดียวที่มากเกินไปและการลบล้างมีมากเกินไป
ซามูเอล

4

ดังที่ Michael กล่าวว่า:

  • Overloading = ลายเซ็นหลายวิธีชื่อวิธีการเดียวกัน
  • Overriding = ลายเซ็นวิธีเดียวกัน (ประกาศเสมือน) นำไปใช้ในคลาสย่อย

และ

  • Shadowing = หากถือว่าเป็น DerivedClass จะใช้วิธีการที่ได้รับถ้าเป็น BaseClass จะใช้วิธีการพื้นฐาน

3

การมีเมธอด / ตัวสร้างมากกว่าหนึ่งวิธีที่มีชื่อเดียวกัน แต่พารามิเตอร์ต่างกันเรียกว่าโอเวอร์โหลด นี่คือเหตุการณ์เวลาที่รวบรวม

Class Addition 
{
   int add(int a, int b) 
   {
     return a+b;
   }
   int add(int a, int b, int c)
   {
     return a+b+c;
   }

   public static main (String[] args) 
   {
     Addition addNum = new Addition();
     System.out.println(addNum.add(1,2));
     System.out.println(addNum.add(1,2,3));
   }
}

O / p:

3
6

การลบล้างเป็นเหตุการณ์รันไทม์ซึ่งหมายถึงตามโค้ดของคุณที่ผลลัพธ์จะเปลี่ยนแปลงในขณะรันไทม์

class Car
{
    public int topSpeed() 
    {
        return 200;
    }
}
class Ferrari extends Car
{
    public int topSpeed()
    {
        return 400;
    }
    public static void main(String args[])
    {
        Car car = new Ferrari();
        int num= car.topSpeed();
        System.out.println("Top speed for this car is: "+num);
    }
}

สังเกตว่ามีวิธีการทั่วไปในทั้งสองคลาส topSpeed ​​() ตั้งแต่เราสร้างเฟอร์รารีเราจึงได้ผลลัพธ์ที่แตกต่างออกไป

O / p:

Top speed for this car is: 400

2

ใน C # ไม่มี Java เหมือนการแทนที่ที่ซ่อนอยู่โดยไม่มีการแทนที่คำหลักในวิธีการแทนที่! ดูการใช้งาน C # เหล่านี้:

ตัวแปร 1 ที่ไม่มีการแทนที่ : ผลลัพธ์คือ 200

    class Car {
        public int topSpeed() {
            return 200;
        }
    }

    class Ferrari : Car {
        public int topSpeed(){
                return 400;
        }
    }

    static void Main(string[] args){
        Car car = new Ferrari();
        int num= car.topSpeed();
        Console.WriteLine("Top speed for this car is: "+num);
        Console.ReadLine();
    }

ตัวแปร 2 ที่มีคีย์เวิร์ดแทนที่ : ผลลัพธ์คือ 400

    class Car {
        public virtual int topSpeed() {
            return 200;
        }
    }

    class Ferrari : Car {
        public override int topSpeed(){
                return 400;
        }
    }

    static void Main(string[] args){
        Car car = new Ferrari();
        int num= car.topSpeed();
        Console.WriteLine("Top speed for this car is: "+num);
        Console.ReadLine();
    }

คำหลักเสมือนบนคลาสของรถยนต์ตรงข้ามกับขั้นสุดท้ายบน Java หมายความว่าไม่ใช่ขั้นสุดท้ายคุณสามารถแทนที่หรือใช้งานได้หาก Car เป็นนามธรรม


1

shadowing = รักษาสองคำจำกัดความที่คลาสที่ได้รับและเพื่อที่จะแสดงนิยามคลาสพื้นฐานมันเงา (ซ่อน) นิยามคลาสที่ได้รับและในทางกลับกัน


1

อีกจุดที่จะเพิ่ม

การโอเวอร์โหลดมากกว่าหนึ่งวิธีที่มีชื่อเดียวกัน ประเภทผลตอบแทนเดียวกันหรือต่างกัน ไม่มีพารามิเตอร์ที่แตกต่างกันหรือพารามิเตอร์ประเภทต่างๆ ในคลาสเดียวกันหรือคลาสที่ได้รับมา

int Add (int num1, int num2) int เพิ่ม (int num1, int num2, int num3) double Add (int num1, int num2) double Add (double num1, double num2)

สามารถเป็นไปได้ในคลาสเดียวกันหรือคลาสที่ได้รับ โดยทั่วไปชอบในคลาสเดียวกัน เช่น Console.WriteLine () มี 19 วิธีที่โอเวอร์โหลด

สามารถโอเวอร์โหลดคลาสตัวสร้างวิธีการ

สามารถพิจารณาได้ว่าเป็นความหลากหลายของ Compile Time (static / Early Binding)

================================================== ================================================== =

การลบล้างไม่สามารถทำได้ในคลาสเดียวกัน สามารถแทนที่คลาสเมธอดคุณสมบัติตัวทำดัชนีเหตุการณ์

มีข้อ จำกัด บางประการเช่นเมธอดฐานที่ถูกแทนที่ต้องเป็นเสมือนนามธรรมหรือลบล้าง คุณไม่สามารถใช้ตัวดัดแปลงใหม่แบบคงที่หรือเสมือนเพื่อแก้ไขวิธีการแทนที่

สามารถพิจารณาว่าเป็นความหลากหลายของเวลาทำงาน (Dynamic / Late Binding)

ช่วยในการกำหนดเวอร์ชันhttp://msdn.microsoft.com/en-us/library/6fawty39.aspx

================================================== ================================================== =

ลิงก์ที่มีประโยชน์

http://msdn.microsoft.com/en-us/library/ms173152.aspx Compile time polymorphism เทียบกับ run time polymorphism


ดีมีรายละเอียดที่จำเป็น
user3885927

1

การโอเวอร์โหลดเป็นส่วนหนึ่งของความหลากหลายแบบคงที่และใช้เพื่อใช้วิธีการที่แตกต่างกันที่มีชื่อเดียวกัน แต่มีลายเซ็นต่างกัน การลบล้างใช้เพื่อทำให้วิธีการที่ไม่สมบูรณ์สมบูรณ์ ในความคิดของฉันไม่มีการเปรียบเทียบระหว่างสองแนวคิดนี้สิ่งเดียวที่คล้ายกันคือทั้งสองมาพร้อมกับคำศัพท์เดียวกันที่จบลง


กัปตันที่นี่: การโอเวอร์โหลดเมธอดจะช่วยให้คุณมีลายเซ็นหลายวิธีที่มีชื่อเดียวกัน การลบล้างซ่อนสมาชิกที่สืบทอดมาจากคลาสหรืออินเทอร์เฟซ บินหนี
SparK

1
@SparK Overriding ไม่ได้ซ่อนสมาชิก คุณสามารถทั้งแทนที่หรือซ่อนเป็นสมาชิกได้รับมรดก ทั้งสองเป็นตัวเลือกพิเศษซึ่งกันและกัน
Servy

@ บริการเลือกคำผิดฉันหมายถึง "สารทดแทน"
SparK

0

Method overloading และ Method overriding เป็น 2 แนวคิดที่แตกต่างกันอย่างสิ้นเชิง การโอเวอร์โหลดเมธอดมีชื่อเมธอดเดียวกัน แต่มีลายเซ็นต่างกัน การแทนที่เมธอดกำลังเปลี่ยนการใช้งานดีฟอลต์ของเมธอดคลาสฐานในคลาสที่ได้รับ ด้านล่างนี้คุณจะพบวิดีโอแนะนำที่ยอดเยี่ยม 2 เรื่องที่อธิบายแนวคิดเหล่านี้

วิธีการลบล้าง Vs การซ่อน

วิธีการมากเกินไป


0

การโอเวอร์โหลดเป็นแนวคิดที่คุณมีลายเซ็นหรือวิธีการเดียวกันที่มีชื่อเดียวกัน แต่พารามิเตอร์ต่างกันและการลบล้างเรามีเมธอดชื่อเดียวกันที่มีพารามิเตอร์ต่างกันนอกจากนี้การสืบทอดยังเรียกว่าการลบล้าง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.