ผู้ออกแบบ Java เกลียดความซับซ้อนของ C++ ดังนั้น Java จึงกระชับมากและ GC ยังทำให้การจัดการหน่วยความจำสะดวกมาก C# สนใจใน GC และเทคโนโลยีเครื่องเสมือนของ Java และหวังว่าจะรวมภาษา Microsoft หลัก ๆ หลายภาษาเข้ากับ .NET . ดังนั้น C# จึงไม่ง่ายหรือซับซ้อนในแง่ของภาษา
แนวคิดการออกแบบของทั้งสองภาษาก็แตกต่างกันเช่นกัน Java เป็นภาษาที่คอมไพล์และตีความ ในขณะที่ C# เป็นภาษาที่คอมไพล์แล้วคอมไพล์และรัน Java ไม่มีผู้รับมอบสิทธิ์ แต่ C# มีผู้รับมอบสิทธิ์ Java มีแนวโน้มที่จะใช้อินเทอร์เฟซเพื่อใช้ฟังก์ชันของผู้รับมอบสิทธิ์ ในขณะที่ Abstract Class ใน C# มีบทบาทมากกว่าอินเทอร์เฟซ
Java เป็นไปตามกฎการตั้งชื่ออูฐ และ C# เป็นไปตามกฎการตั้งชื่อ Pascal แต่ตอนนี้คน Java เริ่มใช้ C# มากขึ้นเรื่อยๆ และในขณะเดียวกัน พวกเขาก็นำกฎการตั้งชื่ออูฐมาใช้กับ C# ซึ่งอาจทำให้โค้ด C# อ่านยากขึ้นเรื่อยๆ ทำไม C# ไม่ติดตามอูฐตั้งแต่แรก? ฉันไม่เห็นสิ่งที่ไม่ดีเกี่ยวกับการตั้งชื่ออูฐ
1. ชื่อคลาสนี้และคลาสภายใน
ใน Java เรามักจะเห็นการใช้งานคล้ายกับชื่อคลาส นี่คืออินสแตนซ์ของวัตถุปัจจุบัน ทำไมจึงปรากฏอยู่ข้างหน้า? โปรแกรมเมอร์ C# จะสับสนกับสิ่งนี้
ใน Java มีการใช้คลาสภายในในหลาย ๆ ที่ และสมาชิกของคลาสภายนอกสามารถเข้าถึงได้ในคลาสภายใน ในเวลานี้ เมื่อใช้สิ่งนี้ในคลาสภายใน คำถามจะเกิดขึ้นว่านี่คือใคร และมันคืออะไร หมายถึง มันเป็นอินสแตนซ์วัตถุปัจจุบันของคลาสภายในหรืออินสแตนซ์วัตถุปัจจุบันของคลาสภายนอกหรือไม่
ใน Java โดยการเพิ่มชื่อคลาสของคลาสภายนอกไว้ข้างหน้า หมายความว่าอินสแตนซ์อ็อบเจ็กต์ปัจจุบันของคลาสภายนอกถูกใช้ในคลาสภายใน
ลองดูตัวอย่างด้านล่าง
//คำจำกัดความของคลาสภายนอก
คลาสสาธารณะ OuterClass {
//คำจำกัดความของคลาสภายใน
คลาสส่วนตัว InnerClass
-
// ไม่มีรหัสสมาชิกที่กำหนดไว้ในคลาสภายใน ที่นี่เราเข้าถึงสมาชิกในคลาสภายนอก
สาธารณะ int getId () { กลับ OuterClass.this.id }
โมฆะสาธารณะ setId (int id) { OuterClass.this.id = id;}
// ชื่อสมาชิกถูกกำหนดไว้ในคลาสภายใน และสมาชิกในคลาสภายในจะเข้าถึงได้โดยตรง โดยค่าเริ่มต้น จะเข้าถึงสมาชิกในคลาสปัจจุบัน
ชื่อสตริงส่วนตัว
สตริงสาธารณะ getName() { return this.name;}
// คุณสามารถเพิ่มชื่อของคลาสภายในไว้ข้างหน้าสิ่งนี้ได้
setName โมฆะสาธารณะ (ชื่อสตริง) { InnerClass.this.name = ชื่อ;}
// คลาสภายในยังสามารถเข้าถึงสมาชิกที่มีชื่อเดียวกันในคลาสภายนอก และจำเป็นต้องเพิ่มชื่อของคลาสภายนอก
สตริงสาธารณะ getOuterName() { กลับ OuterClass.this.name;}
โมฆะสาธารณะ setOuterName (ชื่อสตริง) { OuterClass.this.name = ชื่อ;}
@แทนที่
สตริงสาธารณะ toString()
-
ส่งคืน "Id: " + this.getId() + ", ชื่อภายใน: " + this.getName() + ", ชื่อภายนอก: " + this.getOuterName();
-
-
//รหัสสมาชิกและชื่อที่กำหนดในคลาสภายนอก
รหัสส่วนตัวส่วนตัว;
ชื่อสตริงส่วนตัว
InnerClass InnerInstance ส่วนตัว;
OuterClass สาธารณะ ()
-
this.innerInstance = InnerClass ใหม่ ();
this.innerInstance.setId(20);
this.innerInstance.setName("ทอม");
this.innerInstance.setOuterName("อลิซ");
-
สตริงสาธารณะ toString()
-
กลับ this.innerInstance.toString();
-
-
ใน C# คลาสจะถูกแบ่งออกเป็นคลาสที่ซ้อนกันและคลาสที่ไม่ซ้อนกัน คลาสแรกคือคลาสที่ประกาศภายในประเภทข้อมูลอื่น หลังเป็นคลาสที่กำหนดโดยตรงในเนมสเปซที่แน่นอน คลาสที่ซ้อนกันมักไม่ค่อยมีการกำหนดไว้ใน C#
คลาสที่ไม่ฝังตัวอนุญาตให้ใช้เฉพาะการควบคุมการเข้าถึงสาธารณะและภายในเท่านั้น ในขณะที่คลาสในตัวอนุญาตให้ใช้อักขระควบคุมการเข้าถึงทั้งห้าตัว ได้แก่ ส่วนตัว ได้รับการป้องกัน ป้องกันภายใน สาธารณะ และภายใน คลาสภายในยังสามารถเข้าถึงวิธีการทั้งหมดของคลาสภายนอก รวมถึงวิธีการอินสแตนซ์และวิธีการส่วนตัว แต่จำเป็นต้องส่งผ่านอินสแตนซ์ของคลาสภายนอกอย่างชัดเจน
คลาสภายในใน C# สามารถใช้ประเภทและวิธีการคงที่ที่กำหนดโดยคลาสภายนอก แต่ไม่สามารถใช้วิธีอินสแตนซ์ของคลาสภายนอกได้โดยตรง ดังนั้นจึงไม่มีปัญหาข้างต้น
ใน C# คลาสภายนอกทำหน้าที่เหมือนเนมสเปซสำหรับคลาสภายใน ตราบใดที่การควบคุมการเข้าถึงอนุญาต คุณสามารถใช้วิธีการต่อไปนี้เพื่อสร้างอินสแตนซ์ของวัตถุคลาสภายใน
OuterClass.InnerClass obj = new OuterClass.InnerClass(); อินสแตนซ์นี้ไม่มีความสัมพันธ์โดยตรงกับอินสแตนซ์ใด ๆ ของคลาสภายนอก คล้ายกับคลาสภายในแบบคงที่ใน Java
2. ชื่อคลาส.คลาสและประเภท
ใน Java เรามักจะเห็นการใช้ class name.class การใช้งานนี้เทียบเท่ากับ typeof (ชื่อคลาส) ใน C# ซึ่งใช้เพื่อรับการอ้างอิงอินสแตนซ์ประเภทวัตถุ
ใน Java แต่ละคลาสจะมีอ็อบเจ็กต์ Class ที่สอดคล้องกัน เมื่อคลาสถูกเขียนและคอมไพล์ อ็อบเจ็กต์ Class จะถูกสร้างขึ้นในไฟล์ .class ที่สร้างขึ้นเพื่อแสดงข้อมูลประเภทของคลาส สามวิธีในการรับคลาสอินสแตนซ์:
รับอินสแตนซ์คลาสของออบเจ็กต์โดยการเรียกเมธอด getClass() ของอินสแตนซ์ออบเจ็กต์
ใช้วิธีคงที่ forName() ของ Class เพื่อรับอินสแตนซ์ของ Class โดยใช้ชื่อของคลาส Class.forName(xxx.xx.xx) ส่งคืนคลาส ฟังก์ชันคือการขอให้ JVM ค้นหาและโหลดคลาสที่ระบุ ซึ่งหมายความว่า JVM จะดำเนินการส่วนโค้ดคงที่ของคลาส
รับอินสแตนซ์คลาสโดยใช้ชื่อคลาส .calss สำหรับคลาสการห่อหุ้มของประเภทข้อมูลพื้นฐาน คุณยังสามารถใช้ .TYPE เพื่อรับอินสแตนซ์คลาสของประเภทข้อมูลพื้นฐานที่เกี่ยวข้องได้
วิธีรับอินสแตนซ์ของวัตถุประเภทใน C# นั้นง่ายกว่าและชัดเจนกว่า
ได้รับจากการเรียกเมธอด GetType() ของอินสแตนซ์ข้อมูล วิธีการนี้สืบทอดมาจาก Object ดังนั้นออบเจ็กต์ใดๆ ใน C# จึงมีเมธอด GetType() คือ x.GetType() โดยที่ x คือชื่อตัวแปร
x ใน typeof(x) ต้องเป็นชื่อคลาส ชื่อประเภท ฯลฯ เฉพาะเจาะจง และไม่สามารถเป็นชื่อตัวแปรได้
ผ่านวิธีคงที่ System.Type.GetType() ของ System.Type
3. ชั้นเรียนที่ไม่ระบุชื่อ
ใน Java คลาสที่ไม่ระบุตัวตนจะถูกใช้บ่อยกว่าเช่นกัน ตัวอย่างเช่น ใน Android เมื่อใช้งานการตรวจสอบปุ่ม คุณมักจะเห็นโค้ดเช่นนี้
@แทนที่
โมฆะสาธารณะ onClick (ดู arg0) {
เจตนา เจตนา = เจตนาใหม่ ( MainActivity.this, ActivityFrameLayout.class);
setTitle("FrameLayout");
startActivity( เจตนา );
-
-
ที่นี่ OnClickListenter เป็นอินเทอร์เฟซจริง ๆ แล้วสามารถใช้อินเทอร์เฟซเพื่อสร้างอินสแตนซ์ของวัตถุได้หรือไม่ ไม่แน่นอน
ดังนั้นจาวาจึงสร้างคลาสที่ไม่ระบุชื่อที่ใช้อินเทอร์เฟซที่นี่โดยอัตโนมัติ สิ่งที่เราสร้างคืออินสแตนซ์อ็อบเจ็กต์ของคลาสที่ไม่ระบุชื่อนี้
ข้อดีของสิ่งนี้คือเราไม่จำเป็นต้องกำหนดคลาสที่ใช้เพียงครั้งเดียว จากนั้นสร้างอินสแตนซ์อ็อบเจ็กต์ผ่านคลาสนี้ ซึ่งช่วยลดความยุ่งยากในการพัฒนาโปรแกรม
ตัวอย่างเช่น เรามีอินเทอร์เฟซดังต่อไปนี้
instance.onClick(); ใน C# เราจะไม่ใช้แบบฟอร์มนี้เลย ผ่านการมอบหมาย ฟังก์ชันเดียวกันนี้สามารถทำได้ง่ายมาก
โปรดทราบว่าไม่มีผู้รับมอบสิทธิ์ใน Java
หากเราพิมพ์ประเภทของอินสแตนซ์นี้ คุณจะเห็นประเภทที่แท้จริงของคลาสที่ไม่ระบุชื่อนี้
แนวคิดของแอตทริบิวต์ควรจะเป็นที่คุ้นเคยสำหรับทุกคน ฟังก์ชันสมาชิกของคลาสสามารถเข้าถึงสมาชิกแอตทริบิวต์ในคลาสนี้ได้อย่างอิสระ อย่างไรก็ตาม การเข้าถึงคุณสมบัติของคลาสอื่นจากคลาสหนึ่งจะยุ่งยากกว่า หลายครั้งที่เราใช้วิธีการ Getxxx และ Setxxx ซึ่งดูไม่เป็นธรรมชาติอย่างยิ่ง ตัวอย่างเช่น ใน Java หรือ C++ โค้ดจะเป็นดังนี้:
อย่างไรก็ตามใน C# วิธีการดังกล่าวถือเป็น "แอตทริบิวต์" รหัสเดียวกันใน C# กลายเป็น:
foo.size++;
label.font.bold = จริง;
อย่างที่คุณเห็น C# นั้นอ่านและเข้าใจง่ายกว่าอย่างเห็นได้ชัด นอกจากนี้เรายังสามารถเห็นสถานการณ์ที่คล้ายกันจากโค้ดรูทีนย่อยของ "วิธีการคุณสมบัติ" นี้:
จาวา/ซี++:
ค#:
เพื่อที่จะแยกความแตกต่างของวิธีการที่มีคุณลักษณะนี้จากสมาชิกของแอตทริบิวต์ของคลาส สมาชิกของแอตทริบิวต์จะเรียกว่า "fields" ในภาษา C# และ "attribute" จะกลายเป็นคำนามพิเศษสำหรับ "วิธีการที่มีคุณลักษณะ" นี้ ที่จริงแล้ว วิธีการแอตทริบิวต์ประเภทนี้มักพบใน VB และ DELPHI ใน VB ก็เรียกว่าแอตทริบิวต์ นอกจากนี้ Get และ Set จะต้องปรากฏเป็นคู่ใน C# คุณสมบัติไม่สามารถมีได้เฉพาะ Get โดยไม่มี Set (ใน Java และ C++ สามารถมีได้เฉพาะ Get หรือ Set เท่านั้น) ข้อดีของการทำเช่นนี้ใน C# คือมันง่าย รักษา หากคุณต้องการแก้ไขแอตทริบิวต์บางอย่าง คุณจะต้องใส่ใจกับวิธีการรับและตั้งค่าพร้อมกันและแก้ไขพร้อมกัน คุณจะไม่เปลี่ยนสิ่งนี้และลืมสิ่งนั้นไป
5. กลไกการจัดทำดัชนีวัตถุ (Indexer)
กลไกการจัดทำดัชนีวัตถุถูกนำมาใช้ใน C# เพื่อให้ชัดเจนยิ่งขึ้น ดัชนีวัตถุคืออาร์เรย์ของวัตถุ เรามาพูดถึงมันเกี่ยวกับคุณสมบัติในส่วนก่อนหน้า คุณสมบัติจำเป็นต้องซ่อนวิธีการรับและตั้งค่า แต่ในกลไกดัชนี วิธีการรับหรือการตั้งค่าของแต่ละวัตถุจะถูกเปิดเผย ตัวอย่างเช่น ตัวอย่างต่อไปนี้แสดงให้เห็นประเด็นนี้ชัดเจนยิ่งขึ้น ข้อมูลข้างต้นแนะนำความแตกต่างระหว่าง C# และ Java
เรื่องราว [ดัชนี] = คุณค่า;
-
-
-
-
-
ข้างต้นจะแนะนำความแตกต่างระหว่าง C# และ JAVA ฉันหวังว่ามันจะเป็นประโยชน์สำหรับคุณที่จะเข้าใจ C# และ JAVA