ฟีเจอร์ใดจะถือว่าเป็น“ พลเมืองชั้นหนึ่ง” ในภาษา / แพลตฟอร์มการเขียนโปรแกรม


61

ฉันเห็นข้อความหลายครั้งเช่น - โปรดทำให้คุณลักษณะนี้เป็นพลเมืองชั้นหนึ่งด้วยภาษา / แพลตฟอร์ม " ตัวอย่างเช่นมีการพูดเกี่ยวกับ enums ใน C # /. net ดังนั้นคุณสมบัตินี้จึงถูกพิจารณาว่าเป็น "พลเมืองชั้นหนึ่ง" ในภาษาโปรแกรม / แพลตฟอร์ม?

คำตอบ:


40

คำนิยาม

วัตถุเป็นชั้นหนึ่งเมื่อ:

  • สามารถเก็บไว้ในตัวแปรและโครงสร้างข้อมูล
  • สามารถส่งผ่านเป็นพารามิเตอร์ไปยังรูทีนย่อย
  • สามารถส่งคืนเป็นผลมาจากรูทีนย่อย
  • สามารถสร้างได้ที่รันไทม์
  • มีตัวตนที่แท้จริง (เป็นอิสระจากชื่อที่กำหนด)

คำว่า "วัตถุ" ถูกนำมาใช้อย่างหลวม ๆ ที่นี่ไม่จำเป็นต้องอ้างถึงวัตถุในการเขียนโปรแกรมเชิงวัตถุ ประเภทข้อมูลสเกลาร์ที่ง่ายที่สุดเช่นจำนวนเต็มและจำนวนจุดลอยตัวนั้นเกือบจะเป็นชั้นหนึ่งเสมอ

http://en.wikipedia.org/wiki/First_class_object


1
ดังนั้นสิ่งที่ทำให้ enums วัตถุที่สองใน. net / C #?
Gulshan

7
@Gulshan - คุณสามารถโต้แย้งการขาดตัวตนที่แท้จริง - C # enums นั้นเป็นเพียงน้ำตาล syntactic (เช่น "ชื่อที่กำหนด") สำหรับค่าจำนวนเต็ม เปรียบเทียบกับ Java ซึ่ง enums เป็นวัตถุในสิทธิ์ของตนเอง
mikera

@mikera ใน. NET enums เป็นค่าที่อยู่ในสิทธิของตนเอง Java ไม่ได้มีค่าใด ๆ วัตถุเท่านั้นที่แตกต่างเท่านั้น
SK-logic

@mikera: แม้ว่าจะป้องกันไม่ให้ enums ของ Java มีคุณสมบัติที่ดีเช่นความสามารถในการเป็นตัวแทนของบิตฟิลด์กับพวกเขา ในขณะที่การใช้งานของพวกเขาน่าจะเป็นเฟิร์สคลาสมากขึ้น แต่ API ส่วนใหญ่ยังคงมีค่าคงที่จำนวนเต็ม (หรือสตริง) จำนวนมากและการใช้งานจำนวนมากนั้นไม่สามารถแทนที่ด้วย enums ได้อย่างง่ายดาย
Joey

ฉันไม่คิดว่า enums สามารถสร้างได้ที่รันไทม์ใน. Net ได้ไหม ฉันคิดว่าพวกเขายังคงอยู่เสมอ
travis

33

แนวคิดของ"พลเมืองชั้นหนึ่ง" หรือ "องค์ประกอบชั้นหนึ่ง"ในภาษาโปรแกรมได้รับการแนะนำโดยนักวิทยาศาสตร์คอมพิวเตอร์ชาวอังกฤษChristopher Stracheyในทศวรรษที่ 1960 ในบริบทของฟังก์ชั่นชั้นหนึ่ง สูตรที่โด่งดังที่สุดของหลักการนี้น่าจะอยู่ในโครงสร้างและการตีความของโปรแกรมคอมพิวเตอร์โดย Gerald Jay Sussman และ Harry Abelson:

  • อาจถูกตั้งชื่อโดยตัวแปร
  • อาจถูกส่งผ่านเป็นอาร์กิวเมนต์ไปยังโพรซีเดอร์
  • อาจถูกส่งคืนเป็นผลลัพธ์ของขั้นตอน
  • อาจรวมอยู่ในโครงสร้างข้อมูล

โดยทั่วไปหมายความว่าคุณสามารถทำอะไรกับองค์ประกอบภาษาการเขียนโปรแกรมนี้ทุกสิ่งที่คุณสามารถทำได้กับองค์ประกอบอื่น ๆ ทั้งหมดในภาษาการเขียนโปรแกรม

มันคือทั้งหมดที่เกี่ยวกับ "สิทธิที่เท่าเทียมกัน": คุณสามารถทำทั้งหมดข้างต้นด้วยพูดจำนวนเต็มดังนั้นทำไมสิ่งอื่น ๆ ควรจะแตกต่างกัน?

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

ตัวอย่างเช่นตัวดำเนินการ Java และวิธีการ Java มีชนิดที่คล้ายกัน คุณสามารถกำหนดวิธีการใหม่คุณสามารถ (บ้าง) เลือกชื่อของวิธีการของคุณเองได้อย่างอิสระคุณสามารถแทนที่วิธีการคุณสามารถวิธีการมากเกินไป James Gosling สามารถทำทุกสิ่งกับผู้ให้บริการได้เช่นกัน แต่คุณและฉันทำไม่ได้ ฉันหมายความว่าขัดกับความเชื่อที่นิยม, Java ไม่มากไปประกอบการการสนับสนุน: ตัวอย่างเช่น+ผู้ประกอบการมากเกินไปสำหรับbyte, short, int, long, float, doubleและStringและ IIRC ใน Java 7 ยังBigIntegerและBigDecimal(และอาจจะคู่ฉันลืม) ก็เพียงแค่ว่าคุณไม่มีอิทธิพลใด ๆ กับมัน นั่นทำให้ผู้ประกอบการระดับที่สองอย่างชัดเจนตามคำจำกัดความที่สองนี้ โปรดทราบว่าวิธีการยังคงไม่ใช่วัตถุชั้นหนึ่งตามคำจำกัดความแรก (นั่นทำให้ผู้ประกอบการชั้นที่สาม?)


6

โดยทั่วไปนี่หมายถึงโครงสร้างที่สามารถผ่านได้เป็นพารามิเตอร์สามารถกำหนดเป็นชนิดส่งคืนจากฟังก์ชันหรือสามารถกำหนดค่าได้ โดยปกติคุณจะต้องสามารถสร้างมันได้ที่รันไทม์ ตัวอย่างเช่นอินสแตนซ์ของคลาสจะเป็นพลเมืองชั้นหนึ่งใน c ++ หรือ java แต่ฟังก์ชั่นใน C จะไม่เป็น


อะไรทำให้คลาสเป็นพลเมืองชั้นหนึ่งใน c ++
Bjarke Freund-Hansen

2
@bjarkef: ดูเหมือนว่าได้รับคำตอบแล้วโดยการจับคู่คำอธิบายในประโยคก่อนหน้านี้
doppelgreener

@ โจนาธาน: ใช่ขอโทษฉันอ่านผิด "สร้างพวกเขาที่รันไทม์" ใช่คุณสามารถสร้างอินสแตนซ์ของคลาสที่รันไทม์ (วัตถุ) แต่ไม่ใช่คลาสเอง นั่นคือสิ่งที่ฉันสับสน
Bjarke Freund-Hansen

1
การส่งผ่านพารามิเตอร์ยังไม่เพียงพอ ใน C / C ++ ฉันจะยังคงพิจารณาหน้าที่เป็นพลเมืองชั้นสอง พวกเขาสามารถส่งผ่านเป็นพารามิเตอร์กลับเป็นผลลัพธ์ที่วางไว้ในวัตถุอื่น ๆ แต่พวกเขาไม่สามารถจัดการได้โดยปราศจากความช่วยเหลือของการสร้างอื่น ๆ (เช่น std :: bind จำเป็นต้องมีการผูกพารามิเตอร์กับฟังก์ชั่น)
Martin York

@ มาร์ตินฉันไม่เคยพูดว่าฟังก์ชั่นเป็นพลเมืองชั้นหนึ่งใน C / C ++
Pemdas

1

ฉันจะบอกว่าคุณสมบัติเป็นพลเมืองชั้นหนึ่งหากมีการใช้งานโดยภาษาเท่านั้น
เช่นมันไม่จำเป็นต้องมีคุณสมบัติหลายภาษาหรือห้องสมุดมาตรฐานในการใช้คุณสมบัตินั้น

ตัวอย่าง:

ใน C / C ++ ฉันไม่คิดว่าฟังก์ชั่นเป็นพลเมืองชั้นหนึ่ง (คนอื่นอาจ)
นี่เป็นเพราะมีวิธีการจัดการกับฟังก์ชั่นที่ได้รับการสนับสนุนโดยตรงจากภาษาน็อต แต่ต้องใช้คุณสมบัติภาษาอื่น ๆ ไม่สนับสนุนพารามิเตอร์การผูกกับฟังก์ชันโดยตรงและคุณต้องสร้าง functor เพื่อนำคุณลักษณะนี้ไปใช้


1
นั่นจะไม่ทำให้ฟังก์ชั่นที่ถูกผูกไว้ (หรือ "ปิด") ไม่ได้อยู่ชั้นหนึ่งในขณะที่ฟังก์ชั่นตัวเองคืออะไร? 0x สนับสนุนปัจจัยปิดในการวิเคราะห์ของคุณอย่างไร
เฟร็ด Nurk

@ เฟรดนูร์ค: ทุกอย่างขึ้นอยู่กับภาษา ในบางภาษาการปิดเป็นระบบชั้นหนึ่ง ในคนอื่นไม่ได้ ฉันยังไม่คุ้นเคยกับ C ++ 0x เท่านี้เพื่อแสดงความคิดเห็นอย่างชัดเจน
Martin York

สมมติว่าภาษานั้นเป็น C หรือ C ++ (แต่ไม่ใช่ 0x) ตามที่คุณตอบ คำจำกัดความของคุณสำหรับ "ชั้นหนึ่ง" จะทำให้ฟังก์ชั่นที่ถูกผูกไว้ (หรือ "ปิด") จะไม่เป็นชั้นหนึ่งในขณะที่ฟังก์ชั่นตัวเองอยู่หรือไม่?
Fred Nurk

@ เฟร็ด Nurk: ถ้าคุณ จำกัด สิ่งเดียวที่คุณสามารถทำได้กับฟังก์ชั่นที่จะทำให้พวกเขาปิดแล้วแน่นอน แต่สำหรับฉันมันก็เหมือนกับการพูดว่าถ้าแพลตฟอร์มของคุณรองรับการเพิ่มจำนวนเต็มเท่านั้นโดยการนำเข้าไลบรารี จำนวนเต็มเป็นพลเมืองชั้นหนึ่ง แต่ไม่พิจารณาการเพิ่มจำนวนเต็ม ในการปิดมุมมองของฉันคือการดำเนินการที่สามารถดำเนินการในฟังก์ชั่นที่ส่งคืนฟังก์ชันใหม่ได้อย่างมีประสิทธิภาพ (แต่ขึ้นอยู่กับวิธีที่คุณกำหนดไว้) แต่การปิดและการผูกพันเป็นเพียงการดำเนินการเพียงสองอย่างเท่านั้นที่เราแยกออกจากการสนทนา (ฉันไม่แน่ใจว่าเป็นคำถาม)
Martin York

@ มาร์ติน: ฉันต้องไม่อธิบายตัวเองให้ชัดเจน ได้รับ "คุณสมบัติเป็นพลเมืองชั้นหนึ่งหากมีการใช้งานโดยภาษาเพียงอย่างเดียว" ดังนั้นฟังก์ชั่นในภาษา C และ C ++ จะมีการใช้งานโดยภาษาเพียงอย่างเดียวและจะเป็นแบบชั้นหนึ่ง ฟังก์ชั่นที่ถูกผูกไว้ (ซึ่งอาจเรียกว่า "การปิด") คือสิ่งที่คุณกำลังพูดถึงด้วยพารามิเตอร์การโยง ฯลฯ แต่นั่นคือคุณสมบัติที่แตกต่าง
เฟร็ด Nurk

-1

ในการเพิ่มตัวอย่างให้กับคำตอบที่มีให้แล้ว:

ใน WCF / C # ขณะนี้คุณต้องทำเครื่องหมายวัตถุคลาสด้วยแอตทริบิวต์สัญญาบริการเพื่อให้มันทำงานเป็นบริการ ไม่มีสิ่งเช่น:

public **service** MyService (in relation public **class** MyClass). 

คลาสเป็นพลเมืองชั้นหนึ่งใน c # ซึ่งไม่ได้ใช้บริการ

หวังว่านี่จะช่วยได้

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