ทุกปีที่วิทยาลัยของฉันฉันได้ใช้public
และต้องการที่จะทราบความแตกต่างระหว่างpublic
, private
และprotected
?
นอกจากนี้สิ่งที่ไม่static
ตรงข้ามกับการไม่มีอะไร?
ทุกปีที่วิทยาลัยของฉันฉันได้ใช้public
และต้องการที่จะทราบความแตกต่างระหว่างpublic
, private
และprotected
?
นอกจากนี้สิ่งที่ไม่static
ตรงข้ามกับการไม่มีอะไร?
คำตอบ:
จากdocs.microsoft.com :
ประเภทหรือสมาชิกสามารถเข้าถึงได้โดยรหัสอื่นใดในการชุมนุมเดียวกันหรือการชุมนุมอื่นที่อ้างอิงมัน
ประเภทหรือสมาชิกสามารถเข้าถึงได้ด้วยรหัสในคลาสหรือโครงสร้างเดียวกัน
ประเภทหรือสมาชิกสามารถเข้าถึงได้โดยรหัสในคลาสหรือโครงสร้างเดียวกันหรือในคลาสที่ได้รับ
private protected
(เพิ่มใน C # 7.2)ชนิดหรือสมาชิกสามารถเข้าถึงได้โดยรหัสในคลาสหรือโครงสร้างเดียวกันหรือในคลาสที่ได้รับจากแอสเซมบลีที่เหมือนกัน แต่ไม่ใช่จากแอสเซมบลีอื่น
ประเภทหรือสมาชิกสามารถเข้าถึงได้โดยรหัสใด ๆ ในการชุมนุมเดียวกัน แต่ไม่ได้มาจากการชุมนุมอื่น
ชนิดหรือสมาชิกสามารถเข้าถึงได้โดยรหัสใด ๆ ในแอสเซมบลีเดียวกันหรือโดยคลาสที่ได้รับในแอสเซมบลีอื่น
เมื่อไม่มีการตั้งค่าตัวแก้ไขการเข้าถึงจะใช้ตัวดัดแปลงการเข้าถึงเริ่มต้น ดังนั้นจึงมีรูปแบบการปรับเปลี่ยนการเข้าถึงบางอย่างแม้ว่าจะไม่ได้ตั้งค่าไว้
static
ส่วนขยายโมดิฟายเออร์คงที่ในคลาสหมายความว่าคลาสไม่สามารถสร้างอินสแตนซ์ได้และสมาชิกทั้งหมดของมันเป็นแบบสแตติก สมาชิกแบบสแตติกมีหนึ่งเวอร์ชันโดยไม่คำนึงถึงจำนวนอินสแตนซ์ของชนิดการล้อมรอบที่ถูกสร้าง
คลาสแบบสแตติกนั้นโดยทั่วไปเหมือนกับคลาสแบบไม่คงที่ แต่มีความแตกต่างเดียว: คลาสแบบสแตติกไม่สามารถสร้างอินสแตนซ์ภายนอกได้ กล่าวอีกนัยหนึ่งคุณไม่สามารถใช้คำหลักใหม่เพื่อสร้างตัวแปรประเภทคลาส เนื่องจากไม่มีตัวแปรอินสแตนซ์คุณเข้าถึงสมาชิกของคลาสแบบคงที่โดยใช้ชื่อคลาสเอง
แต่มีสิ่งดังกล่าวเป็นตัวสร้างแบบคงที่ คลาสใดก็ได้สามารถมีหนึ่งในนั้นรวมถึงคลาสแบบคงที่ พวกเขาไม่สามารถเรียกได้โดยตรงและไม่สามารถมีพารามิเตอร์ (นอกเหนือจากพารามิเตอร์ประเภทใด ๆ ในชั้นเรียนของตัวเอง) ตัวสร้างแบบคงที่ถูกเรียกโดยอัตโนมัติเพื่อเริ่มต้นคลาสก่อนที่อินสแตนซ์แรกจะถูกสร้างขึ้นหรือสมาชิกแบบคงที่ใด ๆ ที่มีการอ้างอิง ดูเหมือนว่านี้:
static class Foo()
{
static Foo()
{
Bar = "fubar";
}
public static string Bar { get; set; }
}
คลาสแบบสแตติกมักใช้เป็นบริการคุณสามารถใช้คลาสดังนี้:
MyStaticClass.ServiceMethod(...);
ภาพรวมกราฟิก (สรุปโดยย่อ)
เนื่องจากคลาสแบบสแตติกถูกปิดผนึกจึงไม่สามารถสืบทอดได้ (ยกเว้นจาก Object) ดังนั้นคำหลักที่ป้องกันจึงไม่ถูกต้องในคลาสแบบสแตติก
สำหรับค่าเริ่มต้นหากคุณไม่ใส่ตัวดัดแปลงการเข้าถึงไว้ข้างหน้าให้ดูที่นี่:
การมองเห็นเริ่มต้นสำหรับคลาส C # และสมาชิก (ฟิลด์วิธีการ ฯลฯ )?
Non-ซ้อนกัน
enum public
non-nested classes / structs internal
interfaces internal
delegates in namespace internal
class/struct member(s) private
delegates nested in class/struct private
ที่ซ้อนกัน:
nested enum public
nested interface public
nested class private
nested struct private
นอกจากนี้ยังมีการปิดผนึกคำหลักซึ่งทำให้ชั้นไม่สามารถสืบทอดได้
นอกจากนี้ใน VB.NET คำหลักบางครั้งก็แตกต่างกันดังนั้นนี่คือสูตรชีท:
สาธารณะ - หากคุณสามารถดูชั้นเรียนได้คุณจะเห็นวิธีการ
ส่วนตัว - หากคุณเป็นส่วนหนึ่งของชั้นเรียนคุณสามารถดูวิธีการได้
ได้รับการป้องกัน - เช่นเดียวกับส่วนตัวรวมทั้งผู้สืบทอดทั้งหมดยังสามารถดูวิธีการได้
คงที่ (คลาส) - จำความแตกต่างระหว่าง "ระดับ" และ "วัตถุ"? ลืมทุกอย่าง พวกเขาเหมือนกันกับ "คงที่" ... คลาสเป็นอินสแตนซ์หนึ่งและเท่านั้นของตัวเอง
คงที่ (วิธีการ) - เมื่อใดก็ตามที่คุณใช้วิธีนี้มันจะมีกรอบของการอ้างอิงที่เป็นอิสระจากอินสแตนซ์ที่เกิดขึ้นจริงของชั้นมันเป็นส่วนหนึ่งของ
โพสต์ไดอะแกรมที่ยอดเยี่ยมอีกครั้งจากคำตอบนี้
นี่คือตัวดัดแปลงการเข้าถึงทั้งหมดใน Venn diagrams จากการ จำกัด มากขึ้นไปที่หลากหลายยิ่งขึ้น:
private
:
private protected
: - เพิ่มใน C # 7.2
internal
:
protected
:
protected internal
:
public
:
using System;
namespace ClassLibrary1
{
public class SameAssemblyBaseClass
{
public string publicVariable = "public";
protected string protectedVariable = "protected";
protected internal string protected_InternalVariable = "protected internal";
internal string internalVariable = "internal";
private string privateVariable = "private";
public void test()
{
// OK
Console.WriteLine(privateVariable);
// OK
Console.WriteLine(publicVariable);
// OK
Console.WriteLine(protectedVariable);
// OK
Console.WriteLine(internalVariable);
// OK
Console.WriteLine(protected_InternalVariable);
}
}
public class SameAssemblyDerivedClass : SameAssemblyBaseClass
{
public void test()
{
SameAssemblyDerivedClass p = new SameAssemblyDerivedClass();
// NOT OK
// Console.WriteLine(privateVariable);
// OK
Console.WriteLine(p.publicVariable);
// OK
Console.WriteLine(p.protectedVariable);
// OK
Console.WriteLine(p.internalVariable);
// OK
Console.WriteLine(p.protected_InternalVariable);
}
}
public class SameAssemblyDifferentClass
{
public SameAssemblyDifferentClass()
{
SameAssemblyBaseClass p = new SameAssemblyBaseClass();
// OK
Console.WriteLine(p.publicVariable);
// OK
Console.WriteLine(p.internalVariable);
// NOT OK
// Console.WriteLine(privateVariable);
// Error : 'ClassLibrary1.SameAssemblyBaseClass.protectedVariable' is inaccessible due to its protection level
//Console.WriteLine(p.protectedVariable);
// OK
Console.WriteLine(p.protected_InternalVariable);
}
}
}
using System;
using ClassLibrary1;
namespace ConsoleApplication4
{
class DifferentAssemblyClass
{
public DifferentAssemblyClass()
{
SameAssemblyBaseClass p = new SameAssemblyBaseClass();
// NOT OK
// Console.WriteLine(p.privateVariable);
// NOT OK
// Console.WriteLine(p.internalVariable);
// OK
Console.WriteLine(p.publicVariable);
// Error : 'ClassLibrary1.SameAssemblyBaseClass.protectedVariable' is inaccessible due to its protection level
// Console.WriteLine(p.protectedVariable);
// Error : 'ClassLibrary1.SameAssemblyBaseClass.protected_InternalVariable' is inaccessible due to its protection level
// Console.WriteLine(p.protected_InternalVariable);
}
}
class DifferentAssemblyDerivedClass : SameAssemblyBaseClass
{
static void Main(string[] args)
{
DifferentAssemblyDerivedClass p = new DifferentAssemblyDerivedClass();
// NOT OK
// Console.WriteLine(p.privateVariable);
// NOT OK
//Console.WriteLine(p.internalVariable);
// OK
Console.WriteLine(p.publicVariable);
// OK
Console.WriteLine(p.protectedVariable);
// OK
Console.WriteLine(p.protected_InternalVariable);
SameAssemblyDerivedClass dd = new SameAssemblyDerivedClass();
dd.test();
}
}
}
Private Protected
ก็จะเป็น: ชั้นเดียวกัน = Yes
ประกอบเดียวกันชั้นเรียนมา = Yes
ประกอบเดียวกันชั้นใด = NO
การชุมนุมที่แตกต่างกันเรียนมา = NO
การชุมนุมที่แตกต่างกันชั้นใด NO
= ข้อเสนอแนะเพิ่มเติมอีกประการหนึ่งก็คือจะไม่สลับลำดับคำสั่งprotected internal
เนื่องจากจะเป็นการทำลายปอดอักเสบจากคำตอบของ @ user1810087
เกี่ยวกับคำถามที่ไม่มีอะไร
อีกวิธีหนึ่งที่มองเห็นได้ของตัวดัดแปลงการเข้าถึงปัจจุบัน(C # 7.2) หวังว่าสคีมาช่วยให้จดจำได้ง่ายขึ้น
(คลิกที่ภาพเพื่อดูแบบโต้ตอบ)
หากคุณต่อสู้เพื่อให้จำได้ว่าการปรับเปลี่ยนการเข้าถึงสองคำจำภายนอกภายใน
อืมมม
ดูที่นี่: การเข้าถึงปรับเปลี่ยน
โดยสังเขป:
สาธารณะให้วิธีการหรือพิมพ์การมองเห็นที่สมบูรณ์จากประเภท / คลาสอื่น ๆ
ไพรเวตอนุญาตเฉพาะชนิดที่มีการเข้าถึงเมธอด / ตัวแปรแบบไพรเวตไปยังเมธอด / ตัวแปรแบบไพรเวต (โปรดทราบว่าคลาสที่ซ้อนกันยังมีการเข้าถึงเมธอด / ตัวแปรคลาสที่มีอยู่ด้วย)
การป้องกันคล้ายกับไพรเวตยกเว้นคลาสที่ได้รับสามารถเข้าถึงวิธีที่ได้รับการป้องกันได้
"ไม่มีอะไร" เท่ากับ VB.NET ที่เทียบเท่ากับ null แม้ว่าถ้าคุณกำลังอ้างถึง "ไม่มีอะไร" หมายถึง "ไม่มีตัวดัดแปลงการเข้าถึง" แต่มันก็ขึ้นอยู่กับว่ากฎข้อหัวแม่มือที่หยาบมาก (แน่นอนใน C #) คือถ้าคุณไม่ได้ระบุตัวดัดแปลงการเข้าถึงอย่างชัดเจนวิธีการ / ตัวแปร การประกาศมักจะถูก จำกัดเท่าที่ควรจะเป็น กล่าวคือ
public class MyClass
{
string s = "";
}
มีประสิทธิภาพเช่นเดียวกับ:
public class MyClass
{
private string s = "";
}
บทความ MSDN ที่เชื่อมโยงจะเสนอคำอธิบายโดยสมบูรณ์เมื่อไม่มีการระบุตัวแก้ไขการเข้าถึงอย่างชัดเจน
สาธารณะ - สามารถเข้าถึงได้โดยทุกคนจากทุกที่
ส่วนตัว - สามารถเข้าถึงได้ด้วยในชั้นเรียนที่เป็นส่วนหนึ่งของ
ได้รับการป้องกัน - สามารถเข้าถึงได้จากกับในชั้นเรียนหรือวัตถุใด ๆ ที่สืบทอดจากชั้นเรียน
ไม่มีอะไรที่เป็นเหมือนโมฆะ แต่ใน VB
คงที่หมายถึงคุณมีหนึ่งอินสแตนซ์ของวัตถุนั้นวิธีการสำหรับทุกอินสแตนซ์ของคลาสนั้น
mmm ...
คงที่หมายความว่าคุณสามารถเข้าถึงฟังก์ชั่นนั้นโดยไม่ต้องมีตัวอย่างของชั้นเรียน
คุณสามารถเข้าถึงได้โดยตรงจากคำจำกัดความของชั้นเรียน
สถานะส่วนตัวบ่งชี้ว่าตัวแปรสามารถเข้าถึงได้โดยวัตถุของคลาสเดียวกันเท่านั้น สถานะการป้องกันขยายการเข้าถึงที่จะรวมลูกหลานของชั้นเช่นกัน
"จากตารางด้านบนเราสามารถเห็นความเคารพระหว่างส่วนตัวและได้รับการปกป้อง ... ฉันคิดว่าทั้งสองเหมือนกัน .... ดังนั้นสิ่งที่จำเป็นสำหรับคำสั่งแยกสองคำนั้น"
ตรวจสอบลิงค์MSDNสำหรับข้อมูลเพิ่มเติม
ตัวดัดแปลงการเข้าถึงเหล่านั้นระบุตำแหน่งที่สมาชิกของคุณจะมองเห็นได้ คุณควรอ่านสิ่งนี้ ใช้ลิงค์ที่ IainMH มอบให้เป็นจุดเริ่มต้น
สมาชิกแบบสแตติกเป็นหนึ่งต่อคลาสและไม่ใช่หนึ่งต่อหนึ่งอินสแตนซ์
ระวังการเข้าถึงชั้นเรียนของคุณอย่างระมัดระวัง คลาสและเมธอดสาธารณะและที่ได้รับการป้องกันจะสามารถเข้าถึงได้โดยทุกคน
Microsoft ยังไม่ได้อธิบายการแสดงตัวดัดแปลงการเข้าถึง (คำหลักสาธารณะการป้องกัน ฯลฯ ) เมื่อสร้างคลาสใหม่ใน Visual Studio ดังนั้นให้ระมัดระวังและคิดเกี่ยวกับการเข้าถึงชั้นเรียนของคุณเพราะเป็นประตูสู่การใช้งานภายในของคุณ
ฉันคิดว่ามันเกี่ยวข้องกับการออกแบบ OOP ที่ดี หากคุณเป็นผู้พัฒนาห้องสมุดคุณต้องการซ่อนผลงานภายในของห้องสมุดของคุณ ด้วยวิธีนี้คุณสามารถแก้ไขการทำงานภายในของห้องสมุดได้ในภายหลัง ดังนั้นคุณทำให้สมาชิกและวิธีการช่วยเหลือของคุณเป็นส่วนตัวและมีเพียงวิธีการอินเทอร์เฟซสาธารณะเท่านั้น วิธีที่ควรเขียนทับควรได้รับการป้องกัน
C # มีตัวดัดแปลงการเข้าถึงทั้งหมด6 รายการ :
ส่วนตัว : สมาชิกที่ประกาศด้วยความสามารถในการเข้าถึงนี้สามารถมองเห็นได้ภายในประเภทที่มีมันจะไม่สามารถมองเห็นได้กับประเภทที่ได้รับประเภทอื่น ๆ ในการชุมนุมเดียวกันหรือประเภทนอกประกอบที่มี กล่าวคือการเข้าถึงนั้น จำกัด เฉพาะประเภทที่บรรจุเท่านั้น
ได้รับการป้องกัน : สมาชิกที่ประกาศด้วยการช่วยการเข้าถึงนี้สามารถมองเห็นได้ภายในประเภทที่ได้มาจากประเภทที่มีอยู่ภายในการชุมนุมที่มีและประเภทที่ได้มาจากประเภทที่มีอยู่ด้านนอกของการชุมนุมที่มี เช่นการเข้าถึงถูก จำกัด ประเภทที่ได้รับจากประเภทที่มี
ภายใน : สมาชิกที่ประกาศด้วยความสามารถในการเข้าถึงนี้สามารถมองเห็นได้ภายในแอสเซมบลีที่ประกอบด้วยสมาชิกนี้จะไม่สามารถมองเห็นการชุมนุมใด ๆ ภายนอกแอสเซมบลีที่ประกอบด้วย เช่นการเข้าถึงจะ จำกัด เฉพาะการประกอบที่มีเท่านั้น
การป้องกันภายใน : สมาชิกที่ประกาศพร้อมการเข้าถึงนี้สามารถมองเห็นได้ภายในประเภทที่ได้มาจากประเภทที่มีอยู่ภายในหรือภายนอกของแอสเซมบลีที่มีอยู่มันยังสามารถมองเห็นประเภทใด ๆ ภายในแอสเซมบลีที่ประกอบด้วย เช่นการเข้าถึงถูก จำกัด ไว้ที่มีการชุมนุมหรือประเภทที่ได้รับ
พับลิก : สมาชิกที่ประกาศพร้อมการเข้าถึงนี้สามารถมองเห็นได้ภายในแอสเซมบลีที่มีสมาชิกนี้หรือแอสเซมบลีอื่น ๆ ที่อ้างอิงแอสเซมบลีที่ประกอบด้วย เช่นการเข้าถึงไม่ จำกัด
C # 7.2 กำลังเพิ่มระดับการเข้าถึงใหม่:
การป้องกันส่วนบุคคล : สมาชิกที่ประกาศพร้อมความสามารถในการเข้าถึงนี้สามารถมองเห็นได้ภายในประเภทที่ได้รับจากประเภทนี้ประกอบด้วยภายในแอสเซมบลีที่ประกอบด้วย ไม่สามารถมองเห็นได้ในทุกประเภทที่ไม่ได้มาจากประเภทที่มีหรือด้านนอกของแอสเซมบลีที่ประกอบด้วย เช่นการเข้าถึงถูก จำกัด ประเภทที่ได้รับภายในการชุมนุมที่มี
แหล่งที่มารวมถึงรหัสตัวอย่างของตัวดัดแปลงการเข้าถึงส่วนตัวที่ได้รับการป้องกัน