Bir özelliğin ya da bir yöntemin (PHP 7.1.0 ve sonrası) görünürlüğü,
bildirim sırasında önüne şu anahtar sözcüklerden biri getirilerek
belirlenebilir:
public
, protected
ya da
private
.
public olarak bildirilmiş özelliklere ve yöntemlere her
yerden erişilebilir. protected bildirimli özelliklere ve
yöntemlere sadece tanımlandığı sınıfdan, ebeveyn sınıflardan ve miras
alınarak private bildirimli özelliklere ve yöntemlere
ise sadece özelliğin tanımlandığı sınıfın içinden erişilebilir.
Sınıf özellikleri public
, protected
ya da private
olarak tanımlanabilir.
Görünürlük belirtilmeden bildirilen özelliklerin görünürlüğünün
public
olduğu varsayılır.
Örnek 1 - Özellik bildirimi
<?php
/**
* Sınıfım tanımı
*/
class Sınıfım
{
public $genel = 'Genel';
protected $korumalı = 'Korumalı';
private $özel = 'Özel';
function selamVer()
{
echo $this->genel;
echo $this->korumalı;
echo $this->özel;
}
}
$nesne = new Sınıfım();
echo $nesne->genel; // Çalışır
echo $nesne->korumalı; // Ölümcül Hata
echo $nesne->özel; // Ölümcül Hata
$nesne->selamVer(); // Genel, Korumalı ve Özel görüntüler
/**
* ÖbürSınıfım tanımı
*/
class ÖbürSınıfım extends Sınıfım
{
// public ve protected özellikleri yeniden tanımlayabiliriz,
// ancak private olanlar tanımlanamaz
public $genel = 'Genel2';
protected $korumalı = 'Öbür korumalı';
function selamVer()
{
echo $this->genel;
echo $this->korumalı;
echo $this->özel;
}
}
$nesne2 = new ÖbürSınıfım();
echo $nesne2->genel; // Çalışır
echo $nesne2->korumalı; // Ölümcül Hata
echo $nesne2->özel; // Tanımsız
$nesne2->selamVer(); // Genel2, Öbür korumalı ve Undefined görüntülenir
?>
PHP 8.4'ten itibaren, özelliklerin görünürlükleri bakışımsız olarak
ayarlanabilir, okuma (get
) ve yazma
(set
) için farklı kapsamlar olabilir. Özellikle,
set
görünürlüğü, öntanımlı görünürlükten daha izin
verici olmadığı sürece ayrı olarak belirtilebilir.
Örnek 2 - Bakışımsız Özellik Görünürlüğü
<?php
class Book
{
public function __construct(
public private(set) string $title,
public protected(set) string $author,
protected private(set) int $pubYear,
) {}
}
class SpecialBook extends Book
{
public function update(string $author, int $year): void
{
$this->author = $author; // OK
$this->pubYear = $year; // Onulmaz Hata
}
}
$b = new Book('How to PHP', 'Peter H. Peterson', 2024);
echo $b->title; // Çalışır
echo $b->author; // Çalışır
echo $b->pubYear; // Onulmaz Hata
$b->title = 'How not to PHP'; // Onulmaz Hata
$b->author = 'Pedro H. Peterson'; // Onulmaz Hata
$b->pubYear = 2023; // Onulmaz Hata
?>
Bakışımsız görünürlükle ilgili birkaç uyarı var:
set
görünürlüğü olabilir.
set
görünürlüğü get
ile aynı
veya daha kısıtlayıcı olmalıdır. Yani,
public protected(set)
ve
protected protected(set)
kullanımına izin verilir,
ancak protected public(set)
bir sözdizimi hatasına
neden olur.
public
ise, ana görünürlük atlanabilir.
Yani, public private(set)
ve private(set)
aynı sonucu verecektir.
private(set)
görünürlüğüne sahip bir özellik
otomatik olarak final
olur ve bir alt sınıfta
yeniden bildirilemez.
set
görünürlüğünü takip eder, get
'i değil.
get
hem de set
işlemini
içerir ve bu nedenle her zaman daha kısıtlayıcı olan
set
görünürlüğünü takip eder.
Bir sınıf başka bir sınıfı genişlettiğinde, alt sınıf
final
olmayan herhangi bir özelliği yeniden tanımlayabilir. Bunu yaparken, yeni görünürlük ana sınıfla aynı veya
ondan daha geniş olduğu sürece, ana görünürlüğü veya
set
görünürlüğünü genişletebilir. Ancak, bir
private
özelliği geçersiz kılınırsa, aslında ana
sınıfın özelliğinin değiştirilmediği, ancak farklı bir dahili isme
sahip yeni bir özellik oluşturduğu unutulmamalıdır.
Örnek 3 - Bakışımsız Özellik Kalıtımı
<?php
class Book
{
protected string $title;
public protected(set) string $author;
protected private(set) int $pubYear;
}
class SpecialBook extends Book
{
public protected(set) $title; // OK, çünkü okumak daha geniş, yazmak ise aynı.
public string $author; // OK, çünkü okumak aynı, yazmak ise daha geniş.
public protected(set) int $pubYear; // Onulmaz hata. private(set) özellikler finaldir.
}
?>
Sınıf yöntemleri public
, protected
ya da private
olarak tanımlanmalıdır. Bunlardan
herhangi biri kullanılmadan yapılmış yöntem tanımlarının
public
kullanılarak yapıldığı varsayılır.
Örnek 4 - Yöntem bildirimi
<?php
/**
* Sınıfım tanımı
*/
class Sınıfım
{
// public kurucu bildirimi
public function __construct() { }
// public yöntem bildirimi
public function Genel() { }
// protected yöntem bildirimi
protected function Korumalı() { }
// private yöntem bildirimi
private function Özel() { }
// Bu da public bir yöntem
function Falanca()
{
$this->Genel();
$this->Korumalı();
$this->Özel();
}
}
$sınıfım = new Sınıfım;
$sınıfım->Genel(); // Çalışır
$sınıfım->Korumalı(); // Ölümcül Hata
$sınıfım->Özel(); // Ölümcül Hata
$sınıfım->Falanca(); // Public, Protected ve Private çalışır
/**
* ÖbürSınıfım tanımı
*/
class ÖbürSınıfım extends Sınıfım
{
// Bu public bir yöntemdir
function Filanca()
{
$this->Genel();
$this->Korumalı();
$this->Özel(); // Ölümcül Hata
}
}
$öbürSınıfım = new Sınıfım;
$öbürSınıfım->Genel(); // Çalışır
$öbürSınıfım->Filanca(); // Genel ve Korumalı çalışır, Özel çalışmaz
class Bar
{
public function dnm() {
$this->dnmÖzel();
$this->dnmGenel();
}
public function dnmGenel() {
echo "Bar::dnmGenel\n";
}
private function dnmÖzel() {
echo "Bar::dnmÖzel\n";
}
}
class Foo extends Bar
{
public function dnmGenel() {
echo "Foo::dnmGenel\n";
}
private function dnmÖzel() {
echo "Foo::dnmÖzel\n";
}
}
$fo = new Foo();
$fo->dnm(); // Bar::dnmÖzel
// Foo::dnmGenel
?>
PHP 7.1.0 ve sonrasında, sınıf sabitleri public, private veya protected olarak tanımlanabilir. Bu sözcükler olmaksızın tanımlanmış sabitlerin public olarak tanımlandıkları varsayılır.
Örnek 5 - PHP 7.1.0 ve sonrasında sabit bildirimleri
<?php
/**
* Tanımla: MyClass
*/
class MyClass
{
// public sabit bildirimi
public const MY_PUBLIC = 'genel';
// protected sabit bildirimi
protected const MY_PROTECTED = 'korumalı';
// private sabit bildirimi
private const MY_PRIVATE = 'özel';
public function foo()
{
echo self::MY_PUBLIC;
echo self::MY_PROTECTED;
echo self::MY_PRIVATE;
}
}
$myclass = new MyClass();
MyClass::MY_PUBLIC; // Çalışır
MyClass::MY_PROTECTED; // Ölümcül hata
MyClass::MY_PRIVATE; // Ölümcül hata
$myclass->foo(); // genel, korumalı ve özel çalışır
/**
* Tanımla: MyClass2
*/
class MyClass2 extends MyClass
{
// public
function foo2()
{
echo self::MY_PUBLIC;
echo self::MY_PROTECTED;
echo self::MY_PRIVATE; // Ölümcül hata
}
}
$myclass2 = new MyClass2;
echo MyClass2::MY_PUBLIC; // Çalışır
$myclass2->foo2(); // genel ve korumalı çalışır, özel çalışmaz
?>
Aynı türdeki nesneler, aynı örnekler olmasalar bile, diğerlerinin özel ve korunan üyelerine erişime sahip olacaktır. Bunun sebebi, gerçeklenime özgü ayrıntıların bu nesnelerin içindeyken zaten biliniyor olmasıdır.
Örnek 6 - Aynı nesne türündeki özel üyelere erişim
<?php
class Test
{
private $foo;
public function __construct($foo)
{
$this->foo = $foo;
}
private function bar()
{
echo 'Private yönteme erişildi.';
}
public function baz(Test $other)
{
// private özelliği değiştirilebilir:
$other->foo = 'hello';
var_dump($other->foo);
// private yöntemi de çağırılabilir:
$other->bar();
}
}
$test = new Test('test');
$test->baz(new Test('other'));
?>
Yukarıdaki örneğin çıktısı:
string(5) "hello" Private yönteme erişildi.