ความแตกต่างระหว่างสาธารณะส่วนตัวและได้รับการคุ้มครองคืออะไร


988

เมื่อไหร่และทำไมฉันจึงควรใช้public, privateและprotectedฟังก์ชั่นและตัวแปรภายในชั้นเรียน? ความแตกต่างระหว่างพวกเขาคืออะไร?

ตัวอย่าง:

// Public
public $variable;
public function doSomething() {
  // ...
}

// Private
private $variable;
private function doSomething() {
  // ...
}

// Protected
protected $variable;
protected function doSomething() {
  // ...
}

59
ฉันคิดว่าคำถามนี้จะได้รับประโยชน์จากคำตอบด้วยตัวอย่างที่เป็นประโยชน์ของการใช้แต่ละคำแทนที่จะให้คำจำกัดความที่แท้จริงของคำหลักแต่ละคำ
Matthew

70
ฉันคิดว่าคำถามนี้ควรเป็นสาธารณะไม่ได้รับการคุ้มครอง
dotancohen

คำตอบ:


1260

คุณใช้:

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

  • private ขอบเขตเมื่อคุณต้องการให้ทรัพย์สิน / วิธีการของคุณปรากฏในคลาสของตัวเองเท่านั้น

  • protected ขอบเขตเมื่อคุณต้องการให้ทรัพย์สิน / วิธีการของคุณสามารถมองเห็นได้ในชั้นเรียนทั้งหมดที่ขยายชั้นปัจจุบันรวมทั้งชั้นผู้ปกครอง

เพิ่มเติม: (สำหรับข้อมูลที่ครอบคลุม)


79
protectedขอบเขตเมื่อคุณต้องการที่จะทำให้ตัวแปรของคุณ / ทำงานมองเห็นได้ในทุกชั้นที่ขยายชั้นเรียนในปัจจุบันและคลาสแม่
Shahid

4
@Shahid - ฉันไม่เข้าใจประเด็นของคุณ คลาสใดที่ขยายคลาส A จะขยายคลาสพาเรนต์ A ด้วยเช่นกัน?
JDelage

4
@JDelage - โปรดดูลิงค์http://www.php.net/manual/en/language.oop5.visibility.php#109324
Shahid

4
@Growler ทำไมต้องใช้วัตถุเลยล่ะ?
J.Steve

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

1176

DD

สาธารณะ:

เมื่อคุณประกาศเมธอด (ฟังก์ชัน) หรือคุณสมบัติ (ตัวแปร) เป็นpublicเมธอดและคุณสมบัติเหล่านั้นสามารถเข้าถึงได้โดย:

  • คลาสเดียวกับที่ประกาศไว้
  • คลาสที่สืบทอดคลาสที่ประกาศข้างต้น
  • องค์ประกอบต่างประเทศใด ๆ นอกคลาสนี้ยังสามารถเข้าถึงสิ่งเหล่านั้นได้

ตัวอย่าง:

<?php

class GrandPa
{
    public $name='Mark Henry';  // A public variable
}

class Daddy extends GrandPa // Inherited class
{
    function displayGrandPaName()
    {
        return $this->name; // The public variable will be available to the inherited class
    }

}

// Inherited class Daddy wants to know Grandpas Name
$daddy = new Daddy;
echo $daddy->displayGrandPaName(); // Prints 'Mark Henry'

// Public variables can also be accessed outside of the class!
$outsiderWantstoKnowGrandpasName = new GrandPa;
echo $outsiderWantstoKnowGrandpasName->name; // Prints 'Mark Henry'

มีการป้องกัน:

เมื่อคุณประกาศเมธอด (ฟังก์ชัน) หรือคุณสมบัติ (ตัวแปร) เป็นprotectedเมธอดและคุณสมบัติเหล่านั้นสามารถเข้าถึงได้โดย

  • คลาสเดียวกับที่ประกาศไว้
  • คลาสที่สืบทอดคลาสที่ประกาศข้างต้น

สมาชิกคนนอกไม่สามารถเข้าถึงตัวแปรเหล่านั้นได้ "คนนอก" ในแง่ที่ว่าพวกเขาไม่ใช่วัตถุของคลาสที่ประกาศตัวเอง

ตัวอย่าง:

<?php

class GrandPa
{
    protected $name = 'Mark Henry';
}

class Daddy extends GrandPa
{
    function displayGrandPaName()
    {
        return $this->name;
    }

}

$daddy = new Daddy;
echo $daddy->displayGrandPaName(); // Prints 'Mark Henry'

$outsiderWantstoKnowGrandpasName = new GrandPa;
echo $outsiderWantstoKnowGrandpasName->name; // Results in a Fatal Error

ข้อผิดพลาดที่แน่นอนคือ:

ข้อผิดพลาดร้ายแรงของ PHP: ไม่สามารถเข้าถึงคุณสมบัติที่ได้รับการป้องกัน GrandPa :: $ name


เอกชน:

เมื่อคุณประกาศเมธอด (ฟังก์ชัน) หรือคุณสมบัติ (ตัวแปร) เป็นprivateเมธอดและคุณสมบัติเหล่านั้นสามารถเข้าถึงได้โดย:

  • คลาสเดียวกับที่ประกาศไว้

สมาชิกคนนอกไม่สามารถเข้าถึงตัวแปรเหล่านั้นได้ บุคคลภายนอกในแง่ที่ว่าพวกเขาไม่ใช่วัตถุตัวอย่างของคลาสที่ประกาศเองและแม้แต่คลาสที่สืบทอดคลาสที่ประกาศ

ตัวอย่าง:

<?php

class GrandPa
{
    private $name = 'Mark Henry';
}

class Daddy extends GrandPa
{
    function displayGrandPaName()
    {
        return $this->name;
    }

}

$daddy = new Daddy;
echo $daddy->displayGrandPaName(); // Results in a Notice 

$outsiderWantstoKnowGrandpasName = new GrandPa;
echo $outsiderWantstoKnowGrandpasName->name; // Results in a Fatal Error

ข้อความผิดพลาดที่แน่นอนจะเป็น:

ประกาศ: คุณสมบัติที่ไม่ได้กำหนด: Daddy :: $ name
ข้อผิดพลาดร้ายแรง: ไม่สามารถเข้าถึงทรัพย์สินส่วนตัว GrandPa :: $ name


ผ่าชั้นคุณปู่โดยใช้การสะท้อนแสง

หัวเรื่องนี้ไม่ได้อยู่นอกขอบเขตจริงๆและฉันกำลังเพิ่มที่นี่เพียงเพื่อพิสูจน์ว่าการสะท้อนนั้นมีประสิทธิภาพจริงๆ ดังที่ฉันได้กล่าวไว้ในตัวอย่างสามข้อข้างต้นprotectedและprivateสมาชิก (คุณสมบัติและวิธีการ) ไม่สามารถเข้าถึงได้นอกชั้นเรียน

อย่างไรก็ตามด้วยการไตร่ตรองคุณสามารถทำสิ่งพิเศษได้แม้กระทั่งการเข้าถึงprotectedและprivateสมาชิกนอกชั้นเรียน!

การสะท้อนคืออะไร

Reflection เพิ่มความสามารถในการเรียนวิศวกรรมย้อนกลับส่วนต่อประสานฟังก์ชั่นวิธีการและส่วนขยาย นอกจากนี้ยังมีวิธีเรียกค้นความคิดเห็นเอกสารสำหรับฟังก์ชั่นชั้นเรียนและวิธีการต่างๆ

คำนำ

เรามีคลาสชื่อGrandpasและบอกว่าเรามีสามคุณสมบัติ เพื่อความเข้าใจง่ายลองพิจารณาชื่อของคุณปู่สามคนที่มีชื่อ:

  • มาร์คเฮนรี่
  • John Clash
  • Will Jones

ขอให้เราทำให้พวกเขา (ปรับเปลี่ยนกำหนด) public, protectedและprivateตามลำดับ คุณรู้ดีว่าprotectedและprivateสมาชิกไม่สามารถเข้าถึงนอกชั้นเรียน ตอนนี้ขอขัดแย้งกับการใช้คำสั่งสะท้อน

รหัส

<?php

class GrandPas   // The Grandfather's class
{
    public     $name1 = 'Mark Henry';  // This grandpa is mapped to a public modifier
    protected  $name2 = 'John Clash';  // This grandpa is mapped to a protected  modifier
    private    $name3 = 'Will Jones';  // This grandpa is mapped to a private modifier
}


# Scenario 1: without reflection
$granpaWithoutReflection = new GrandPas;

# Normal looping to print all the members of this class
echo "#Scenario 1: Without reflection<br>";
echo "Printing members the usual way.. (without reflection)<br>";
foreach($granpaWithoutReflection as $k=>$v)
{
    echo "The name of grandpa is $v and he resides in the variable $k<br>";
}

echo "<br>";

#Scenario 2: Using reflection

$granpa = new ReflectionClass('GrandPas'); // Pass the Grandpas class as the input for the Reflection class
$granpaNames=$granpa->getDefaultProperties(); // Gets all the properties of the Grandpas class (Even though it is a protected or private)


echo "#Scenario 2: With reflection<br>";
echo "Printing members the 'reflect' way..<br>";

foreach($granpaNames as $k=>$v)
{
    echo "The name of grandpa is $v and he resides in the variable $k<br>";
}

เอาท์พุท:

#Scenario 1: Without reflection
Printing members the usual way.. (Without reflection)
The name of grandpa is Mark Henry and he resides in the variable name1

#Scenario 2: With reflection
Printing members the 'reflect' way..
The name of grandpa is Mark Henry and he resides in the variable name1
The name of grandpa is John Clash and he resides in the variable name2
The name of grandpa is Will Jones and he resides in the variable name3

ความเข้าใจผิดที่พบบ่อย:

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

<?php

class GrandPas   // The Grandfather's class
{
    public     $name1 = 'Mark Henry';  // This grandpa is mapped to a public modifier
    protected  $name2 = 'John Clash';  // This grandpa is mapped to a protected modifier
    private    $name3 = 'Will Jones';  // This grandpa is mapped to a private modifier
}

$granpaWithoutReflections = new GrandPas;
print_r($granpaWithoutReflections);

เอาท์พุท:

GrandPas Object
(
    [name1] => Mark Henry
    [name2:protected] => John Clash
    [name3:GrandPas:private] => Will Jones
)

ฟังก์ชั่นการแก้จุดบกพร่อง

print_r, var_exportและvar_dumpมีฟังก์ชั่นการดีบัก พวกเขานำเสนอข้อมูลเกี่ยวกับตัวแปรในรูปแบบที่มนุษย์อ่านได้ ฟังก์ชั่นทั้งสามนี้จะเปิดเผยprotectedและprivateคุณสมบัติของวัตถุที่มี PHP 5 สมาชิกชั้นคงที่จะไม่แสดง


แหล่งข้อมูลเพิ่มเติม:



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

@JamesG มันอธิบายเล็กน้อยในความคิดเห็นอื่น ๆ ข้างต้น stackoverflow.com/questions/4361553/…
cjmling

ฉันไม่รู้ว่าทำไมอาจเป็นคำถามเล็ก ๆ น้อย ๆ แต่ไม่มีใครพูดถึงว่าใน PHP มีตัวดัดแปลงการเข้าถึงอีกสองตัว: นามธรรมและสุดท้ายคำหลักนี้สามารถใช้สำหรับคลาส PHP เท่านั้น แต่ยังคงเข้าถึงตัวดัดแปลง
bxN5

1
ผมขอแนะนำให้คุณอ่านคำอธิบายเกี่ยวกับสิ่งที่เป็นนามธรรมให้โดย Dhairya Lakhera ที่นี่: stackoverflow.com/questions/2558559/... มันเป็นส่วนเสริมที่สมบูรณ์แบบสำหรับคำอธิบายของ Shankar Damodaran
Julio Marchi

83

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

หากคุณ "โค้ดไปยังอินเทอร์เฟซมากกว่าการนำไปใช้งาน" ก็มักจะตรงไปตรงมาในการตัดสินใจการมองเห็น โดยทั่วไปแล้วตัวแปรควรเป็นส่วนตัวหรือได้รับการป้องกันเว้นแต่คุณจะมีเหตุผลที่ดีที่จะเปิดเผยพวกเขา ใช้ accessors สาธารณะ (getters / setters) แทนเพื่อ จำกัด และควบคุมการเข้าถึง internals ของคลาส

หากต้องการใช้รถยนต์เป็นแบบเปรียบเทียบสิ่งต่าง ๆ เช่นความเร็วเกียร์และทิศทางจะเป็นตัวแปรอินสแตนซ์ส่วนตัว คุณไม่ต้องการให้คนขับควบคุมสิ่งต่างๆเช่นอัตราส่วนอากาศ / เชื้อเพลิงโดยตรง คุณจะต้องดำเนินการบางอย่างแทนวิธีสาธารณะ อินเตอร์เฟซที่ไปที่รถอาจจะรวมถึงวิธีการเช่นaccelerate(), deccelerate()/ brake(), setGear(), turnLeft(), turnRight()ฯลฯ

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

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

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


3
หนังสือที่แนะนำในการแก้ไขโพสต์นี้ยอดเยี่ยมมากจริงๆ ก้อนที่ฉันได้พิสูจน์แล้วค่อนข้างสว่างไสว สองสามบทแรกตอบคำถามส่วนใหญ่ที่เกี่ยวข้องกับชั้นเรียนของฉัน
โยสิยาห์

หนังสือที่ได้รับอนุญาตให้ฉันเข้าใจวัตถุจริงๆโดยไม่ต้องเบียดเสียดออกคิดของฉันที่มีรายละเอียดที่ไม่จำเป็นเช่นตัวอย่างในสมอลล์ทอล์คได้โดยเดวิดเทย์เลอร์เป็นObject Oriented เทคโนโลยี: คู่มือการผู้จัดการและวิศวกรรมธุรกิจที่มีวัตถุ Teechnology ทั้งสองมีเพียง 100 หน้าและง่ายต่อการอ่านในช่วงบ่าย แน่นอนว่ามีรูปแบบการออกแบบของ Gamma et al ถึงแม้ว่าวิธีการพื้นฐานสามารถอธิบายได้ง่ายๆโดย 'subclass สิ่งที่คุณต้องการเปลี่ยนแปลง'
Patanjali

การเปรียบเทียบที่ดีมาก คุณมีหนึ่งสำหรับการป้องกัน vs ส่วนตัว?
Jānis Elmeris

79

private - สามารถเข้าถึงได้จากภายในชั้นเรียนเท่านั้น

protected - สามารถเข้าถึงได้จากภายในชั้นเรียนและชั้นเรียน INHERITING

public - สามารถเข้าถึงได้จากรหัสนอกชั้นเรียนเช่นกัน

สิ่งนี้ใช้กับฟังก์ชั่นเช่นเดียวกับตัวแปร


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

7
ฉันไม่คิดอย่างนั้นจริงๆแล้วดูเหมือนว่าคำตอบที่เลือกคือคำตอบที่สับสน ดูความคิดเห็น Shahids IMHO วิธีการป้องกันสามารถเข้าถึงได้อย่างดีจากภายในชั้นเรียนเดิม
โอลาฟ

คลาสสามารถเข้าถึงสาธารณะของคลาสอื่นได้หรือไม่
Serjas

1
@Serjas: ไม่เพียงวัตถุอื่นเว้นแต่ว่าพวกเขาจะคงที่วิธีการ / เขต
DanMan

ฉันไม่ทราบว่าสิ่งนี้ใช้กับทุกภาษาการเขียนโปรแกรม แต่ใน PHP คุณสมบัติ / วิธีการ "ป้องกัน" สามารถเข้าถึงได้ทั้งในระดับที่มีการประกาศหรือชั้นเรียนที่สืบทอดจากชั้นเรียนที่กำหนดคุณสมบัติ / วิธีการ
John Slegers

25

ความแตกต่างมีดังนี้:

Public :: ตัวแปรสาธารณะหรือวิธีการสามารถเข้าถึงได้โดยตรงโดยผู้ใช้ชั้นเรียนใด ๆ

Protected :: ตัวแปรหรือวิธีที่ได้รับการป้องกันไม่สามารถเข้าถึงได้โดยผู้ใช้ของคลาส แต่สามารถเข้าถึงได้ภายในคลาสย่อยที่สืบทอดมาจากคลาส

Private :: ตัวแปรส่วนตัวหรือวิธีการสามารถเข้าถึงได้เฉพาะภายในจากชั้นเรียนที่มีการกำหนดไว้ซึ่งหมายความว่าตัวแปรส่วนตัวหรือวิธีการที่ไม่สามารถเรียกจากเด็กที่ขยายชั้นเรียน


17

ขอบเขตการมองเห็นพร้อมตัวอย่างบทคัดย่อ :: ทำให้เข้าใจง่าย

การเปิดเผยคุณสมบัติหรือเมธอดนี้ถูกกำหนดโดยการประกาศล่วงหน้าของหนึ่งในสามคำหลัก (สาธารณะการป้องกันและส่วนตัว)

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

  • บทคัดย่อเช่น คิดว่าขอบเขตการมองเห็นสาธารณะเป็น"ปิคนิคสาธารณะ"ที่ทุกคนสามารถเข้ามาได้

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

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

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

  • ด้วยการเปรียบเทียบการปิคนิคคิดว่าเป็น"การปิคนิคของ บริษัท ที่อนุญาตให้สมาชิกของ บริษัท เท่านั้น"ในการปิคนิค ไม่ใช่ครอบครัวไม่อนุญาตให้บุคคลทั่วไปใช้

15
/**
 * Define MyClass
 */
class MyClass
{
    public $public = 'Public';
    protected $protected = 'Protected';
    private $private = 'Private';

    function printHello()
    {
        echo $this->public;
        echo $this->protected;
        echo $this->private;
    }
}

$obj = new MyClass();
echo $obj->public; // Works
echo $obj->protected; // Fatal Error
echo $obj->private; // Fatal Error
$obj->printHello(); // Shows Public, Protected and Private


/**
 * Define MyClass2
 */
class MyClass2 extends MyClass
{
    // We can redeclare the public and protected method, but not private
    protected $protected = 'Protected2';

    function printHello()
    {
        echo $this->public;
        echo $this->protected;
        echo $this->private;
    }
}

$obj2 = new MyClass2();
echo $obj2->public; // Works
echo $obj2->private; // Undefined
echo $obj2->protected; // Fatal Error
$obj2->printHello(); // Shows Public, Protected2, Undefined

สกัดจาก :

http://php.net/manual/en/language.oop5.visibility.php


12

⚡️นี่เป็นวิธีที่ง่ายต่อการจำขอบเขตของpublic, และprotectedprivate

PUBLIC:

  • public ขอบเขต: ตัวแปรสาธารณะ / ฟังก์ชั่นสามารถใช้ได้กับทั้งวัตถุและชั้นเรียนอื่น ๆ

PROTECTED:

  • protected ขอบเขต: ตัวแปร / ฟังก์ชั่นที่ได้รับการป้องกันนั้นมีให้สำหรับคลาสทั้งหมดที่ขยายคลาสปัจจุบัน
  • No! วัตถุไม่สามารถเข้าถึงขอบเขตนี้

PRIVATE:

  • private ขอบเขต: ตัวแปร / ฟังก์ชั่นส่วนตัวจะมองเห็นได้เฉพาะในระดับปัจจุบันที่มีการกำหนดไว้
  • No! คลาสที่ขยายคลาสปัจจุบันไม่สามารถเข้าถึงขอบเขตนี้ได้
  • No! วัตถุไม่สามารถเข้าถึงขอบเขตนี้

อ่านทัศนวิสัยของเมธอดหรือตัวแปรในคู่มือ PHP


9

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

Update : ฉันไปเป็นค่าเริ่มต้นของprotectedทุกวันนี้เพราะฉันมาพบว่ามันดีพอสำหรับการใส่ในแค็ปซูลและไม่เข้าทางตอนที่ฉันขยายชั้นเรียน (ซึ่งฉันพยายามหลีกเลี่ยง) เฉพาะในกรณีที่ฉันมีเหตุผลที่ดีที่จะใช้อีกสองฉันจะ

เหตุผลที่ดีสำหรับprivateวิธีการหนึ่งก็คือสิ่งที่ใช้สิ่งที่มีอยู่ในตัวของวัตถุนั้นที่แม้กระทั่งชั้นเรียนที่ขยายไม่ควรเปลี่ยน (เหตุผลจริงนอกเหนือจากการห่อหุ้มเช่นการจัดการของรัฐภายใน) ในที่สุดก็ยังง่ายพอที่จะติดตามว่ามีprotectedการใช้วิธีใดโดยปกติดังนั้นฉันจึงเริ่มต้นจนถึงprotectedทุกวันนี้ อาจจะไม่ใช่เป้าหมาย 100% "ในร่องลึก" ฉันยอมรับ


3
ด้วยการอัปเดตของคุณ: คุณช่วยให้ชัดเจนขึ้นว่า "ดีพอ" และ "เหตุผลที่ดี" ไปด้วยกันได้อย่างไร ตัวอย่างเช่นการใช้privateจะยังคง"ดีพอ"แต่คุณไม่แนะนำว่าแม้ว่าเหตุผลก่อนหน้านี้คุณจะให้เสียงเหมือน "เหตุผลที่ดี" อีกต่อไป: การห่อหุ้ม
hakre

@ ฮาเคร: เหตุผลที่เราควรมุ่งมั่นในการห่อหุ้มคือการหลีกเลี่ยงการรั่วไหลของรัฐในขอบเขตด้านนอก protectedทำเช่นนั้นแล้ว แต่คุณยังคงความยืดหยุ่นไว้สำหรับส่วนขยาย / การสืบทอด privateอีกครั้งจนกว่าคุณจะมีเหตุผลที่ดีที่จะทำให้มัน
DanMan

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

ฉันจะไม่โต้เถียงกับประเด็นโดยรวมของคุณเพราะมันยุติธรรมเพียงพอ แต่protectedไม่รั่วไหลออกไปนอกขอบเขต (รหัสที่เรียก / เข้าถึงวิธีการ / เขตข้อมูล) แต่มีเพียงขอบเขตภายใน (ขยายชั้นเรียน) มีความแตกต่างเล็กน้อยตามที่คุณอาจจะเป็น มันง่ายกว่ามากในการติดตามการใช้งานของprotectedเขตข้อมูลมากกว่าpublicหนึ่งแห่ง
DanMan

6

คู่มือ PHP มีดีอ่านคำถามที่นี่

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


6

สำหรับฉันนี่เป็นวิธีที่มีประโยชน์ที่สุดในการทำความเข้าใจกับคุณสมบัติสามประเภท:

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

ตัวอย่างการใช้งานจากนอกชั้นเรียน:

$myObject = new MyObject()
$myObject->publicVar = 'newvalue';
$pubVar = $myObject->publicVar;

ได้รับการป้องกัน : ใช้สิ่งนี้เมื่อคุณต้องการบังคับให้โปรแกรมเมอร์คนอื่น (และตัวคุณเอง) ใช้ getters / setters นอกคลาสเมื่อเข้าถึงและตั้งค่าตัวแปร (แต่คุณควรจะสอดคล้องกันและใช้ getters และ setters ภายในคลาสด้วย) สิ่งนี้หรือprivateมีแนวโน้มที่จะเป็นวิธีเริ่มต้นที่คุณควรตั้งค่าคุณสมบัติคลาสทั้งหมด

ทำไม? เพราะถ้าคุณตัดสินใจในบางจุดในอนาคต (อาจจะเหมือนใน 5 นาที) ที่คุณต้องการจัดการกับค่าที่ส่งคืนสำหรับคุณสมบัตินั้นหรือทำบางสิ่งบางอย่างกับมันก่อนที่จะได้รับ / การตั้งค่าคุณสามารถทำได้โดยไม่ต้องทำการปรับสภาพทุกที่ ใช้ในโครงการของคุณ

ตัวอย่างการใช้งานจากนอกชั้นเรียน:

$myObject = new MyObject()
$myObject->setProtectedVar('newvalue');
$protectedVar = $myObject->getProtectedVar();

ส่วนตัว : privateคุณสมบัติคล้ายกับprotectedคุณสมบัติมาก แต่คุณสมบัติที่แตกต่าง / ความแตกต่างก็คือการprivateทำให้มันไม่สามารถเข้าถึงคลาสลูกได้โดยไม่ต้องใช้ getter หรือ setter ของคลาสพาเรนต์

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

ตัวอย่างการใช้งานภายในคลาสย่อย (ที่ขยาย MyObject):

$this->setPrivateVar('newvalue');
$privateVar = $this->getPrivateVar();


4

ตัวแปรใน PHP ถูกใช้ในสามประเภท:

สาธารณะ: ค่าของตัวแปรประเภทนี้มีอยู่ในทุกขอบเขตและเรียกใช้โค้ดของคุณ ประกาศเป็น:public $examTimeTable;

ส่วนตัว: ค่าของตัวแปรประเภทนี้จะใช้ได้เฉพาะกับคลาสที่เป็นของเท่านั้น private $classRoomComputers;

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

protected $familyWealth;


3

การฟื้นคำถามเก่า แต่ฉันคิดว่าวิธีที่ดีในการคิดสิ่งนี้คือในแง่ของ API ที่คุณกำหนด

  • public - ทุกอย่างที่ทำเครื่องหมายเป็นสาธารณะเป็นส่วนหนึ่งของ API ที่ทุกคนที่ใช้คลาส / อินเทอร์เฟซ / อื่น ๆ ของคุณจะใช้และพึ่งพา

  • protected- อย่าหลงกลนี่เป็นส่วนหนึ่งของ API! ผู้คนสามารถคลาสย่อยขยายรหัสของคุณและใช้สิ่งที่ได้รับการป้องกัน

  • private- คุณสมบัติและวิธีการส่วนตัวสามารถเปลี่ยนแปลงได้มากเท่าที่คุณต้องการ ไม่มีใครสามารถใช้สิ่งเหล่านี้ สิ่งเหล่านี้เป็นเพียงสิ่งเดียวที่คุณสามารถเปลี่ยนแปลงได้โดยไม่ทำให้เกิดการเปลี่ยนแปลง

หรือในแง่ของเซมเวอร์ :

  • การเปลี่ยนแปลงอะไรpublicหรือprotectedควรพิจารณาการเปลี่ยนแปลง MAJOR

  • มีอะไรใหม่publicหรือprotectedควรจะ (อย่างน้อย) ไมเนอร์

  • ใหม่ / การเปลี่ยนแปลงอะไรก็ได้ที่privateสามารถเป็น PATCH

ดังนั้นในแง่ของการบำรุงรักษาโค้ดสิ่งที่ควรระวังคือสิ่งที่คุณทำpublicหรือprotectedเพราะสิ่งเหล่านี้คือสิ่งที่คุณสัญญากับผู้ใช้ของคุณ


1

เมื่อเราทำตาม php เชิงวัตถุในโครงการของเราเราควรปฏิบัติตามกฎบางอย่างเพื่อใช้ตัวดัดแปลงการเข้าถึงใน php วันนี้เราจะเรียนรู้อย่างชัดเจนว่าอะไรคือ access modifier และเราจะใช้มันได้อย่างไรตัวดัดแปลง access access ของ PHP ถูกใช้เพื่อตั้งค่าสิทธิ์การเข้าถึงด้วยคลาส PHP และสมาชิกของมันซึ่งเป็นหน้าที่และตัวแปรที่กำหนดไว้ภายในขอบเขตของคลาส ใน php มีสามขอบเขตสำหรับสมาชิกชั้นเรียน

  1. มหาชน
  2. เอกชน
  3. มีการป้องกัน

ตอนนี้ให้เราดูภาพต่อไปนี้เพื่อทำความเข้าใจระดับการเข้าถึงตัวแก้ไขการเข้าถึง ป้อนคำอธิบายรูปภาพที่นี่

ตอนนี้ให้เราดูรายการต่อไปนี้เพื่อทราบเกี่ยวกับคำหลัก PHP ที่เป็นไปได้ที่ใช้เป็นตัวดัดแปลงการเข้าถึง

สาธารณะ: - คลาสหรือสมาชิกที่กำหนดไว้ด้วยตัวดัดแปลงการเข้าถึงนี้จะสามารถเข้าถึงได้จากทุกที่แม้แต่ภายนอกขอบเขตของคลาส

ส่วนตัว: - สมาชิกชั้นเรียนที่มีคำหลักนี้จะสามารถเข้าถึงได้ภายในชั้นเรียนของตัวเอง เราไม่สามารถเข้าถึงข้อมูลส่วนตัวจากคลาสย่อย มันปกป้องสมาชิกจากการเข้าถึงชั้นนอก

ได้รับการป้องกัน: - เหมือนกับส่วนตัวยกเว้นโดยอนุญาตให้คลาสย่อยเข้าถึงสมาชิกซูเปอร์คลาสที่ได้รับการป้องกัน

ตอนนี้ดูตารางเพื่อทำความเข้าใจตัวดัดแปลงการเข้าถึงอ่านบทความเต็มphp access modifire


1

Public: เป็นสถานะเริ่มต้นเมื่อคุณประกาศตัวแปรหรือวิธีการใด ๆ ที่สามารถเข้าถึงได้โดยตรงไปยังวัตถุ

Protected: สามารถเข้าถึงได้เฉพาะภายในวัตถุและคลาสย่อย

Private: สามารถอ้างอิงได้เฉพาะภายในวัตถุไม่ใช่คลาสย่อย


0

คำหลักที่กล่าวถึงคือตัวดัดแปลงการเข้าถึงและช่วยให้เราสามารถใช้ Encapsulation (หรือการซ่อนข้อมูล) พวกเขาบอกคอมไพเลอร์ว่าคลาสอื่นควรมีสิทธิ์เข้าถึงฟิลด์หรือวิธีการที่ถูกกำหนดไว้

ส่วนตัว - เฉพาะคลาสปัจจุบันเท่านั้นที่สามารถเข้าถึงฟิลด์หรือเมธอด

ได้รับการป้องกัน - เฉพาะคลาสปัจจุบันและคลาสย่อย (และบางครั้งก็เป็นคลาสแพ็คเกจเดียวกัน) ของคลาสนี้เท่านั้นที่สามารถเข้าถึงฟิลด์หรือเมธอด

public - คลาสใด ๆ สามารถอ้างถึงฟิลด์หรือเรียกเมธอด

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