อะไรคือความแตกต่างระหว่างฟังก์ชั่นนามธรรมและฟังก์ชั่นเสมือนจริง? แนะนำให้ใช้ virtual หรือ abstract ในกรณีใด วิธีใดเป็นวิธีที่ดีที่สุด
อะไรคือความแตกต่างระหว่างฟังก์ชั่นนามธรรมและฟังก์ชั่นเสมือนจริง? แนะนำให้ใช้ virtual หรือ abstract ในกรณีใด วิธีใดเป็นวิธีที่ดีที่สุด
คำตอบ:
ฟังก์ชันนามธรรมไม่สามารถใช้งานได้ คุณกำลังพูดว่าคลาสเด็ก ๆ จะต้องให้วิธีการของตัวเองในเวอร์ชันของตัวเอง แต่มันก็ธรรมดาเกินไปที่จะลองใช้ในคลาสผู้ปกครอง
ฟังก์ชั่นเสมือนจริงโดยทั่วไปแล้วดูว่านี่คือฟังก์ชันที่อาจหรืออาจไม่ดีพอสำหรับคลาสเด็ก ดังนั้นถ้ามันดีพอใช้วิธีนี้ถ้าไม่ก็แทนที่ฉันและให้ฟังก์ชั่นของคุณเอง
ฟังก์ชั่นนามธรรมไม่มีการใช้งานและมันสามารถประกาศได้ในระดับนามธรรม สิ่งนี้บังคับให้คลาสที่ได้รับมาเพื่อให้การใช้
ฟังก์ชั่นเสมือนจริงให้การใช้งานเริ่มต้นและสามารถมีอยู่ในคลาสนามธรรมหรือคลาสที่ไม่ใช่นามธรรม
ตัวอย่างเช่น:
public abstract class myBase
{
//If you derive from this class you must implement this method. notice we have no method body here either
public abstract void YouMustImplement();
//If you derive from this class you can change the behavior but are not required to
public virtual void YouCanOverride()
{
}
}
public class MyBase
{
//This will not compile because you cannot have an abstract method in a non-abstract class
public abstract void YouMustImplement();
}
MyBase
ชั้นเรียนของคุณไม่จำเป็นต้องใช้คลาสนามธรรมหรือไม่? ฉันไม่ได้ทำสิ่งนี้บ่อย ๆ ดังนั้นฉันจึงอาจผิดพลาดได้ ฉันไม่เห็นสิ่งนั้นในตัวอย่างของคุณ
abstract
คลาสเท่านั้นที่สามารถมีabstract
สมาชิกได้abstract
คลาสที่สืบทอดจากabstract
คลาสต้อง override
เป็นabstract
สมาชิกabstract
virtual
abstract
สมาชิกไม่สามารถให้การดำเนินการใด ๆ ( abstract
เรียกว่าpure virtual
ในบางภาษา)virtual
หรือไม่virtual
ก็ได้ abstract
สมาชิก (เช่นคุณสมบัตินามธรรมวิธีนามธรรม) เป็นเช่นเดียวกับวิธีการที่เสมือนเช่นคุณสามารถแทนที่มันยกเว้นว่ามันไม่ได้ดำเนินการกับตัวเองเริ่มต้นใช้งาน
คุณต้องแทนที่ฟังก์ชันนามธรรมเสมอ
ดังนั้น:
ฟังก์ชั่นบทคัดย่อ:
ฟังก์ชั่นเสมือนจริง:
เมธอด Abstract: เมื่อคลาสมีเมธอด abstract คลาสนั้นต้องถูกประกาศเป็น abstract วิธีนามธรรมไม่มีการนำไปใช้ดังนั้นคลาสที่สืบทอดมาจากคลาสนามธรรมนั้นต้องจัดเตรียมการนำไปใช้สำหรับวิธีนามธรรมนี้
วิธีเสมือน: คลาสสามารถมีวิธีเสมือน วิธีเสมือนมีการใช้งาน เมื่อคุณรับช่วงจากคลาสที่มีวิธีเสมือนคุณสามารถแทนที่วิธีเสมือนและจัดหาตรรกะเพิ่มเติมหรือแทนที่ตรรกะด้วยการใช้งานของคุณเอง
เวลาที่จะใช้อะไร: ในบางกรณีคุณรู้ว่าบางประเภทควรมีวิธีการเฉพาะ แต่คุณไม่ทราบว่าการใช้วิธีนี้ควรมีอะไรบ้าง
ในกรณีเช่นนี้คุณสามารถสร้างส่วนต่อประสานที่มีวิธีการที่มีลายเซ็นนี้ อย่างไรก็ตามหากคุณมีกรณีดังกล่าว แต่คุณรู้ว่าตัวดำเนินการของอินเทอร์เฟซนั้นจะมีวิธีการทั่วไปอีกวิธีหนึ่ง (ซึ่งคุณสามารถให้การใช้งานได้แล้ว) คุณสามารถสร้างคลาสนามธรรมได้ คลาสนามธรรมนี้มีเมธอด abstract (ซึ่งต้อง overriden) และเมธอดอื่นซึ่งมีตรรกะ 'common'
ควรใช้วิธีเสมือนหากคุณมีคลาสที่สามารถใช้โดยตรง แต่คุณต้องการให้ผู้สืบทอดสามารถเปลี่ยนพฤติกรรมบางอย่างได้แม้ว่าจะไม่ได้รับคำสั่งก็ตาม
คำอธิบาย: ด้วยการเปรียบเทียบ หวังว่ามันจะช่วยคุณได้
บริบท
ฉันทำงานที่ชั้น 21 ของอาคาร และฉันก็หวาดระแวงเรื่องไฟ ไฟที่เผาไหม้เครื่องกวาดท้องฟ้าเป็นครั้งคราวและต่อไปเรื่อย ๆ แต่โชคดีที่เรามีคู่มือการใช้งานที่นี่ในสิ่งที่ต้องทำในกรณีเกิดไฟไหม้:
FireEscape ()
นี่เป็นวิธีการเสมือนจริงที่เรียกว่าFireEscape ()
วิธีการเสมือน
แผนนี้ค่อนข้างดีสำหรับสถานการณ์ 99% มันเป็นแผนพื้นฐานที่ใช้งานได้ แต่มีโอกาส 1% ที่ประตูหนีไฟถูกปิดกั้นหรือได้รับความเสียหายซึ่งในกรณีที่คุณถูกเมาอย่างสมบูรณ์และคุณจะกลายเป็นขนมปังปิ้งเว้นแต่ว่าคุณจะทำอะไรรุนแรง ด้วยวิธีการเสมือนคุณสามารถทำได้: คุณสามารถแทนที่แผน FireEscape () พื้นฐานด้วยแผนเวอร์ชันของคุณเอง:
ในคำอื่น ๆวิธีเสมือนให้เป็นแผนขั้นพื้นฐานซึ่งสามารถแทนที่หากคุณต้องการ คลาสย่อยสามารถแทนที่เมธอดเสมือนคลาสพาเรนต์ของคลาสพาเรนต์ถ้าโปรแกรมเมอร์เห็นว่าเหมาะสม
วิธีการบทคัดย่อ
ไม่ใช่ทุกองค์กรที่เจาะได้ดี บางองค์กรไม่ทำการฝึกซ้อมดับเพลิง พวกเขาไม่มีนโยบายหนีโดยรวม มนุษย์ทุกคนมีไว้เพื่อตนเอง ฝ่ายบริหารสนใจในนโยบายที่มีอยู่เท่านั้น
กล่าวอีกนัยหนึ่งแต่ละคนถูกบังคับให้พัฒนาวิธี FireEscape () ของตัวเอง ผู้ชายคนหนึ่งจะเดินออกจากบันไดหนีไฟ ผู้ชายอีกคนจะโดดร่ม ผู้ชายอีกคนจะใช้เทคโนโลยีจรวดขับเคลื่อนเพื่อหนีออกจากอาคาร ผู้ชายอีกคนจะโรยตัวออกมา ฝ่ายบริหารไม่สนใจว่าคุณจะหลบหนีไปได้อย่างไรตราบใดที่คุณมีแผน FireEscape () ขั้นพื้นฐาน - หากพวกเขาไม่สามารถรับประกันได้ OHS จะลงมาในองค์กรเช่นก้อนอิฐจำนวนหนึ่ง นี่คือสิ่งที่มีความหมายโดยวิธีนามธรรม
ความแตกต่างระหว่างทั้งสองอีกครั้งคืออะไร?
วิธีนามธรรม: คลาสย่อยถูกบังคับให้ใช้วิธี FireEscape ของตนเอง ด้วยวิธีการเสมือนคุณมีแผนขั้นพื้นฐานรอให้คุณ แต่สามารถเลือกที่จะใช้งานของคุณเองถ้ามันไม่ดีพอ
ตอนนี้มันไม่ยากเลยเหรอ?
วิธีนามธรรมเป็นวิธีที่จะต้องดำเนินการเพื่อให้เป็นรูปธรรมในชั้นเรียน ประกาศอยู่ในระดับนามธรรม (และชั้นเรียนใด ๆ ที่มีวิธีนามธรรมจะต้องเป็นระดับนามธรรม) และจะต้องดำเนินการในระดับที่เป็นรูปธรรม
เมธอดเสมือนเป็นวิธีที่สามารถแทนที่ในคลาสที่ได้รับโดยใช้การแทนที่การแทนที่พฤติกรรมในซูเปอร์คลาส หากคุณไม่ได้แทนที่คุณจะได้รับพฤติกรรมดั้งเดิม ถ้าคุณทำคุณจะได้รับพฤติกรรมใหม่เสมอ ตรงข้ามกับไม่ใช่วิธีการเสมือนที่ไม่สามารถเขียนทับได้ แต่สามารถซ่อนวิธีดั้งเดิมได้ สิ่งนี้ทำได้โดยใช้new
ตัวดัดแปลง
ดูตัวอย่างต่อไปนี้:
public class BaseClass
{
public void SayHello()
{
Console.WriteLine("Hello");
}
public virtual void SayGoodbye()
{
Console.WriteLine("Goodbye");
}
public void HelloGoodbye()
{
this.SayHello();
this.SayGoodbye();
}
}
public class DerivedClass : BaseClass
{
public new void SayHello()
{
Console.WriteLine("Hi There");
}
public override void SayGoodbye()
{
Console.WriteLine("See you later");
}
}
เมื่อฉันยกตัวอย่างDerivedClass
และโทรSayHello
หรือSayGoodbye
ฉันจะได้รับ "สวัสดีที่นั่น" และ "พบกันใหม่" ถ้าฉันโทรHelloGoodbye
ฉันจะได้รับ "สวัสดี" และ "พบกันใหม่" นี่เป็นเพราะSayGoodbye
เป็นเสมือนและสามารถถูกแทนที่ด้วยคลาสที่ได้รับ SayHello
ถูกซ่อนไว้เท่านั้นดังนั้นเมื่อฉันเรียกมันว่าจากคลาสพื้นฐานของฉันฉันจะได้รับวิธีการดั้งเดิมของฉัน
วิธีการบทคัดย่อเป็นเสมือนโดยปริยาย พวกเขากำหนดพฤติกรรมที่ต้องมีอยู่เช่นเดียวกับอินเทอร์เฟซ
วิธีการนามธรรมเป็นเสมือนจริงเสมอ พวกเขาไม่สามารถใช้งานได้
นั่นคือความแตกต่างที่สำคัญ
โดยทั่วไปคุณจะใช้วิธีเสมือนหากคุณมีการใช้งาน 'เริ่มต้น' และต้องการอนุญาตให้ลูกหลานเปลี่ยนพฤติกรรม
ด้วยวิธีการแบบนามธรรมคุณบังคับให้ลูกหลานให้การดำเนินการ
ฉันทำสิ่งนี้ง่ายขึ้นโดยทำการปรับปรุงในคลาสต่อไปนี้ (จากคำตอบอื่น ๆ ):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace TestOO
{
class Program
{
static void Main(string[] args)
{
BaseClass _base = new BaseClass();
Console.WriteLine("Calling virtual method directly");
_base.SayHello();
Console.WriteLine("Calling single method directly");
_base.SayGoodbye();
DerivedClass _derived = new DerivedClass();
Console.WriteLine("Calling new method from derived class");
_derived.SayHello();
Console.WriteLine("Calling overrided method from derived class");
_derived.SayGoodbye();
DerivedClass2 _derived2 = new DerivedClass2();
Console.WriteLine("Calling new method from derived2 class");
_derived2.SayHello();
Console.WriteLine("Calling overrided method from derived2 class");
_derived2.SayGoodbye();
Console.ReadLine();
}
}
public class BaseClass
{
public void SayHello()
{
Console.WriteLine("Hello\n");
}
public virtual void SayGoodbye()
{
Console.WriteLine("Goodbye\n");
}
public void HelloGoodbye()
{
this.SayHello();
this.SayGoodbye();
}
}
public abstract class AbstractClass
{
public void SayHello()
{
Console.WriteLine("Hello\n");
}
//public virtual void SayGoodbye()
//{
// Console.WriteLine("Goodbye\n");
//}
public abstract void SayGoodbye();
}
public class DerivedClass : BaseClass
{
public new void SayHello()
{
Console.WriteLine("Hi There");
}
public override void SayGoodbye()
{
Console.WriteLine("See you later");
}
}
public class DerivedClass2 : AbstractClass
{
public new void SayHello()
{
Console.WriteLine("Hi There");
}
// We should use the override keyword with abstract types
//public new void SayGoodbye()
//{
// Console.WriteLine("See you later2");
//}
public override void SayGoodbye()
{
Console.WriteLine("See you later");
}
}
}
การผูกเป็นกระบวนการของการแมปชื่อกับหน่วยของรหัส
การรวมภายหลังหมายความว่าเราใช้ชื่อ แต่เลื่อนการแมป กล่าวอีกนัยหนึ่งเราสร้าง / พูดถึงชื่อแรกและให้บางกระบวนการที่ตามมาจัดการกับการแมปรหัสกับชื่อนั้น
พิจารณาตอนนี้:
ดังนั้นคำตอบสั้น ๆ คือ: virtual
เป็นคำสั่งการรวมสายสำหรับเครื่อง (รันไทม์) ในขณะabstract
ที่คำสั่งการรวมภายหลังสำหรับมนุษย์ (โปรแกรมเมอร์)
ในคำอื่น ๆvirtual
หมายถึง:
“ Dear runtime , ผูกโค้ดที่เหมาะสมกับชื่อนี้โดยทำสิ่งที่คุณทำได้ดีที่สุด: ค้นหา ”
ในขณะที่abstract
หมายถึง:
“ เรียนผู้เขียนโปรแกรมโปรดผูกรหัสที่เหมาะสมกับชื่อนี้ด้วยการทำสิ่งที่ดีที่สุด: ประดิษฐ์ ”
เพื่อประโยชน์ของความสมบูรณ์การบรรทุกเกินพิกัดหมายถึง:
“ เรียนผู้แปลโปรดผูกรหัสที่เหมาะสมกับชื่อนี้โดยทำสิ่งที่คุณทำได้ดีที่สุด: เรียงลำดับ ”
โดยทั่วไปคุณใช้วิธีเสมือนเมื่อคุณต้องการให้ผู้สืบทอดขยายฟังก์ชันการทำงานหากพวกเขาต้องการ
คุณใช้วิธีนามธรรมเมื่อคุณต้องการให้ผู้สืบทอดใช้ฟังก์ชันการทำงาน (และในกรณีนี้พวกเขาไม่มีทางเลือก)
วิธีเสมือนจริง :
เสมือนหมายความว่าเราสามารถแทนที่มันได้
ฟังก์ชั่นเสมือนจริงมีการใช้งาน เมื่อเรารับช่วงชั้นเราสามารถแทนที่ฟังก์ชั่นเสมือนและให้ตรรกะของเราเอง
วิธีการบทคัดย่อ
บทคัดย่อหมายถึงเราต้องลบล้างมัน
ฟังก์ชั่นนามธรรมไม่มีการใช้งานและจะต้องอยู่ในระดับนามธรรม
สามารถประกาศได้เท่านั้น สิ่งนี้บังคับให้คลาสที่ได้รับมาเพื่อให้การใช้งานมัน
สมาชิกนามธรรมเป็นเสมือนโดยปริยาย นามธรรมสามารถเรียกว่าเสมือนจริงในบางภาษา
public abstract class BaseClass
{
protected abstract void xAbstractMethod();
public virtual void xVirtualMethod()
{
var x = 3 + 4;
}
}
ฉันเคยเห็นในบางสถานที่วิธีนามธรรมถูกกำหนดไว้ด้านล่าง **
"วิธีบทคัดย่อต้องใช้ในคลาสย่อย"
** ฉันรู้สึกว่ามันเป็นเหมือน
มันไม่จำเป็นว่าวิธีนามธรรมจะต้องมีการดำเนินการในระดับเด็กถ้าระดับของเด็กยังเป็นนามธรรม ..
1) วิธีนามธรรมไม่สามารถเป็นวิธีส่วนตัวได้ 2) วิธีการนามธรรมไม่สามารถนำมาใช้ในระดับนามธรรมเดียวกัน
ฉันจะบอกว่า .. หากเรากำลังใช้คลาสนามธรรมคุณจะต้องแทนที่วิธีนามธรรมจากคลาสนามธรรมพื้นฐาน เพราะ .. การนำวิธีนามธรรมมาใช้นั้นมีการแทนที่คำสำคัญ. คล้ายกับวิธีเสมือน
ไม่จำเป็นสำหรับเมธอดเสมือนที่จะนำไปใช้ในคลาสที่สืบทอด
----------CODE--------------
public abstract class BaseClass
{
public int MyProperty { get; set; }
protected abstract void MyAbstractMethod();
public virtual void MyVirtualMethod()
{
var x = 3 + 4;
}
}
public abstract class myClassA : BaseClass
{
public int MyProperty { get; set; }
//not necessary to implement an abstract method if the child class is also abstract.
protected override void MyAbstractMethod()
{
throw new NotImplementedException();
}
}
public class myClassB : BaseClass
{
public int MyProperty { get; set; }
//You must have to implement the abstract method since this class is not an abstract class.
protected override void MyAbstractMethod()
{
throw new NotImplementedException();
}
}
ตัวอย่างข้างต้นส่วนใหญ่ใช้รหัส - และถือว่าดีมาก ฉันไม่ต้องการเพิ่มสิ่งที่พวกเขาพูด แต่ต่อไปนี้เป็นคำอธิบายง่ายๆที่ใช้การเปรียบเทียบแทนที่จะเป็นรหัส / ศัพท์เทคนิค
คำอธิบายอย่างง่าย - คำอธิบายโดยใช้การเปรียบเทียบ
วิธีการบทคัดย่อ
คิดว่า George W Bush เขาพูดกับทหารของเขาว่า: "ไปต่อสู้ในอิรัก" และนั่นคือมัน สิ่งที่เขาระบุไว้คือการต่อสู้จะต้องทำ เขาไม่ได้ระบุวิธีการที่ตรงนั้นจะเกิดขึ้น แต่ฉันหมายความว่าคุณไม่สามารถออกไปและ "ต่อสู้": นั่นหมายความว่าอะไรกันแน่? ฉันจะต่อสู้กับ B-52 หรือผู้ชนะของฉันได้อย่างไร รายละเอียดเฉพาะเหล่านั้นจะถูกปล่อยให้คนอื่น นี่เป็นวิธีนามธรรม
วิธีการเสมือน
David Petraeus สูงขึ้นในกองทัพ เขาได้นิยามความหมายของการต่อสู้:
ปัญหาคือว่ามันเป็นวิธีการทั่วไปมาก มันเป็นวิธีที่ดีที่ใช้งานได้ แต่บางครั้งก็ไม่เจาะจงพอ สิ่งที่ดีสำหรับ Petraeus คือคำสั่งของเขามีขอบเขตและขอบเขตที่กว้างขวาง - เขาอนุญาตให้ผู้อื่นเปลี่ยนคำจำกัดความของ "การต่อสู้" ตามข้อกำหนดเฉพาะของพวกเขา
Bloggs งานส่วนตัวอ่านคำสั่งของ Petraeus และได้รับอนุญาตให้ใช้งานเวอร์ชันการต่อสู้ของเขาเองตามข้อกำหนดเฉพาะของเขา:
Nouri al Maliki ยังได้รับคำสั่งซื้อจาก Petraeus เช่นเดียวกัน เขาต้องต่อสู้ด้วย แต่เขาเป็นนักการเมืองไม่ใช่ทหารราบ เห็นได้ชัดว่าเขาไม่สามารถยิงศัตรูของเขาได้ในหัว เนื่องจาก Petraeus ให้วิธีการเสมือนแก่เขาแล้ว Maliki จึงสามารถใช้วิธีการต่อสู้ในเวอร์ชันของเขาเองตามสถานการณ์เฉพาะของเขา:
กล่าวอีกนัยหนึ่งวิธีเสมือนให้คำแนะนำสำเร็จรูป - แต่นี่เป็นคำแนะนำทั่วไปซึ่งสามารถทำให้เฉพาะเจาะจงมากขึ้นโดยคนที่ลงมาสู่การสืบทอดของกองทัพบกตามสถานการณ์เฉพาะของพวกเขา
ความแตกต่างระหว่างคนทั้งสอง
George Bush ไม่ได้พิสูจน์รายละเอียดการใช้งานใด ๆ สิ่งนี้จะต้องให้คนอื่น นี่เป็นวิธีนามธรรม
Petraeus ในมืออื่น ๆไม่ให้รายละเอียดการดำเนินงาน แต่เขาได้รับอนุญาตสำหรับผู้ใต้บังคับบัญชาของเขาที่จะลบล้างคำสั่งของเขากับรุ่นของตัวเองของพวกเขาหากพวกเขาสามารถเกิดขึ้นกับสิ่งที่ดีกว่า
หวังว่าจะช่วย
ฟังก์ชั่นบทคัดย่อ (วิธีการ):
●วิธีนามธรรมเป็นวิธีการที่ประกาศด้วยคำหลักนามธรรม
●มันไม่มีร่างกาย
●ควรใช้งานโดยคลาสที่ได้รับ
●หากวิธีการเป็นนามธรรมชั้นเรียนควรเป็นนามธรรม
ฟังก์ชั่นเสมือนจริง (วิธีการ):
●วิธีเสมือนเป็นวิธีที่ประกาศด้วยคำหลักเสมือนจริงและสามารถแทนที่โดยวิธีการเรียนที่ได้รับโดยใช้คำหลักแทนที่
●ขึ้นอยู่กับคลาสที่ได้รับไม่ว่าจะแทนที่หรือไม่
คำตอบนั้นมีให้หลายครั้ง แต่คำถามเกี่ยวกับเวลาที่จะใช้คือการตัดสินใจในขณะออกแบบ ฉันจะเห็นว่าเป็นแนวปฏิบัติที่ดีในการพยายามรวมคำจำกัดความวิธีการทั่วไปไว้ในอินเทอร์เฟซที่แตกต่างกันและดึงพวกเขาเข้าสู่คลาสที่ระดับนามธรรมที่เหมาะสม การทิ้งชุดทั่วไปของคำจำกัดความวิธีนามธรรมและเสมือนลงในคลาสทำให้ชั้นไม่สามารถทนทานได้เมื่อมันเป็นการดีที่สุดที่จะกำหนดคลาสที่ไม่เป็นนามธรรมซึ่งใช้ชุดของอินเตอร์เฟสที่กระชับ เช่นเคยขึ้นอยู่กับสิ่งที่เหมาะสมที่สุดสำหรับความต้องการเฉพาะของแอปพลิเคชันของคุณ
ฟังก์ชั่นบทคัดย่อไม่สามารถมีร่างกายและจะต้องถูกแทนที่โดยชั้นเรียนของเด็ก
ฟังก์ชั่นเสมือนจริงจะมีร่างกายและอาจหรือไม่อาจถูกแทนที่โดยชั้นเรียนของเด็ก
จากมุมมองเชิงวัตถุทั่วไป:
เกี่ยวกับวิธีนามธรรม : เมื่อคุณใส่วิธีนามธรรมในคลาสผู้ปกครองจริง ๆ แล้วคุณกำลังพูดกับคลาสเด็ก: เฮ้ทราบว่าคุณมีวิธีลายเซ็นเช่นนี้ และถ้าคุณต้องการที่จะใช้มันคุณควรใช้ตัวคุณเอง!
เกี่ยวกับฟังก์ชั่นเสมือนจริง : เมื่อคุณใส่วิธีเสมือนในคลาสพาเรนต์คุณจะพูดกับคลาสที่ได้รับ: เฮ้มีฟังก์ชั่นการทำงานที่ทำบางสิ่งให้คุณ หากสิ่งนี้มีประโยชน์สำหรับคุณเพียงแค่ใช้มัน ถ้าไม่ใช่ให้แทนที่สิ่งนี้และใช้โค้ดของคุณแม้ว่าคุณสามารถใช้การติดตั้งของฉันในรหัสของคุณได้!
นี่เป็นปรัชญาเกี่ยวกับความแตกต่างระหว่างแนวคิดทั้งสองนี้ใน General OO
ฟังก์ชั่นที่เป็นนามธรรมคือ "เพียงแค่" ลายเซ็นโดยไม่มีการใช้งาน มันถูกใช้ในส่วนต่อประสานเพื่อประกาศว่าจะใช้คลาสได้อย่างไร มันจะต้องดำเนินการในหนึ่งในชั้นเรียนที่ได้รับ
ฟังก์ชั่นเสมือนจริง (วิธีการจริง) เป็นฟังก์ชั่นที่คุณประกาศเช่นกันและควรดำเนินการในคลาสลำดับชั้นการสืบทอดอย่างใดอย่างหนึ่ง
อินสแตนซ์ที่สืบทอดมาของคลาสดังกล่าวสืบทอดการใช้งานเช่นกันเว้นแต่ว่าคุณจะใช้มันในคลาสลำดับชั้นที่ต่ำกว่า
หากคลาสมาจากคลาสนามธรรมนี้จะถูกบังคับให้แทนที่สมาชิกนามธรรม สิ่งนี้แตกต่างจากตัวดัดแปลงเสมือนซึ่งระบุว่าสมาชิกอาจถูกลบล้าง
ไม่มีอะไรที่เรียกคลาสเสมือนใน C #
สำหรับฟังก์ชั่น
คุณสามารถตัดสินใจตามความต้องการของคุณ
วิธีนามธรรมไม่มีการใช้งานมันถูกประกาศในระดับผู้ปกครอง คลาสย่อยเป็นที่ยอมรับสำหรับการใช้วิธีการนั้น
วิธีเสมือนควรมีการนำไปใช้ในระดับผู้ปกครองและอำนวยความสะดวกในชั้นเรียนเด็กเพื่อเลือกว่าจะใช้งานการดำเนินงานของระดับผู้ปกครองที่หรือมีการดำเนินการใหม่สำหรับตัวเองสำหรับวิธีการที่ในชั้นเรียนเด็ก
จากพื้นหลัง C ++, C # virtual สอดคล้องกับ C ++ virtual ในขณะที่ C # abstract สอดคล้องกับ C ++ pure virtual function
ฟังก์ชั่นที่เป็นนามธรรมหรือวิธีการที่เป็นสาธารณะ "ชื่อของการดำเนินงาน" เปิดเผยโดยชั้นเรียนจุดมุ่งหมายของมันพร้อมกับชั้นเรียนนามธรรมเป็นหลักให้รูปแบบของข้อ จำกัด ในการออกแบบวัตถุกับโครงสร้างที่วัตถุจะต้องดำเนินการ
ในความเป็นจริงคลาสที่สืบทอดมาจากคลาสนามธรรมจะต้องให้การใช้งานกับวิธีนี้โดยทั่วไปคอมไพเลอร์จะเพิ่มข้อผิดพลาดเมื่อไม่ได้
การใช้คลาสและวิธีการที่เป็นนามธรรมมีความสำคัญส่วนใหญ่เพื่อหลีกเลี่ยงปัญหานั้นโดยเน้นที่รายละเอียดของการใช้งานเมื่อออกแบบคลาสโครงสร้างของคลาสนั้นสัมพันธ์กับการใช้งานมากเกินไปดังนั้นการสร้างการพึ่งพาและการเชื่อมต่อระหว่างคลาสที่ทำงานร่วมกัน
ฟังก์ชั่นหรือวิธีการเสมือนเป็นเพียงวิธีการที่สร้างแบบจำลองพฤติกรรมสาธารณะของคลาส แต่เราสามารถปล่อยให้มันเป็นอิสระในการแก้ไขในห่วงโซ่การสืบทอดเพราะเราคิดว่าชั้นเรียนเด็กอาจจำเป็นต้องใช้ส่วนขยายเฉพาะสำหรับพฤติกรรมนั้น
พวกเขาทั้งสองแสดงรูปแบบของpolymorpfhismในกระบวนทัศน์การวางแนววัตถุ
เราสามารถใช้วิธีนามธรรมและฟังก์ชันเสมือนเข้าด้วยกันเพื่อสนับสนุนโมเดลการสืบทอดที่ดี
เราออกแบบโครงสร้างนามธรรมที่ดีของวัตถุหลักของการแก้ปัญหาของเราจากนั้นสร้างการใช้งานขั้นพื้นฐานโดยการค้นหาผู้ที่มีแนวโน้มที่จะมีความเชี่ยวชาญเพิ่มเติมและเราทำให้สิ่งเหล่านี้เป็นเสมือนจริงในที่สุดเราก็เชี่ยวชาญการใช้งานขั้นพื้นฐานของเรา
ที่นี่ฉันกำลังเขียนโค้ดตัวอย่างบางส่วนหวังว่านี่อาจเป็นตัวอย่างที่จับต้องได้เพื่อดูพฤติกรรมของอินเทอร์เฟซคลาสนามธรรมและคลาสทั่วไปในระดับพื้นฐานมาก คุณยังสามารถค้นหารหัสนี้ใน github เป็นโครงการหากคุณต้องการใช้มันเป็นตัวอย่าง: https://github.com/usavas/JavaAbstractAndInterfaceDemo
public interface ExampleInterface {
// public void MethodBodyInInterfaceNotPossible(){
// }
void MethodInInterface();
}
public abstract class AbstractClass {
public abstract void AbstractMethod();
// public abstract void AbstractMethodWithBodyNotPossible(){
//
// };
//Standard Method CAN be declared in AbstractClass
public void StandardMethod(){
System.out.println("Standard Method in AbstractClass (super) runs");
}
}
public class ConcreteClass
extends AbstractClass
implements ExampleInterface{
//Abstract Method HAS TO be IMPLEMENTED in child class. Implemented by ConcreteClass
@Override
public void AbstractMethod() {
System.out.println("AbstractMethod overridden runs");
}
//Standard Method CAN be OVERRIDDEN.
@Override
public void StandardMethod() {
super.StandardMethod();
System.out.println("StandardMethod overridden in ConcreteClass runs");
}
public void ConcreteMethod(){
System.out.println("Concrete method runs");
}
//A method in interface HAS TO be IMPLEMENTED in implementer class.
@Override
public void MethodInInterface() {
System.out.println("MethodInInterface Implemented by ConcreteClass runs");
// Cannot declare abstract method in a concrete class
// public abstract void AbstractMethodDeclarationInConcreteClassNotPossible(){
//
// }
}
}
เพื่อความเข้าใจของฉัน:
วิธีการบทคัดย่อ:
เฉพาะคลาสนามธรรมเท่านั้นที่สามารถใช้เมธอด abstract คลาสที่ได้รับนั้นจำเป็นต้องใช้เมธอดและไม่มีการนำไปใช้ในคลาส
วิธีการเสมือนจริง:
ชั้นสามารถประกาศสิ่งเหล่านี้และยังให้การดำเนินการเหมือนกัน คลาสที่ได้รับนั้นจำเป็นต้องใช้เมธอดเพื่อแทนที่มัน