Dapatkah variabel pribadi diwariskan dalam php?

Saat Anda mendeklarasikan variabel instan dari kelas privat, Anda tidak dapat mengaksesnya di kelas lain jika Anda mencoba melakukannya, kesalahan waktu kompilasi akan dihasilkan

Tapi, jika Anda mewarisi kelas yang memiliki bidang pribadi, termasuk semua anggota kelas lainnya, variabel pribadi juga diwariskan dan tersedia untuk subkelas.

Tapi, Anda tidak dapat mengaksesnya secara langsung, jika Anda melakukannya kesalahan waktu kompilasi akan dihasilkan

Contoh

Demo Langsung

class Person{
   private String name;
   public Person(String name){
      this.name = name;
   }
   public void displayPerson() {
      System.out.println("Data of the Person class: ");
      System.out.println("Name: "+this.name);
   }
}
public class Student extends Person {
   public Student(String name){
      super(name);
   }
   public void displayStudent() {
      System.out.println("Data of the Student class: ");
      System.out.println("Name: "+super.name);
   }
   public static void main(String[] args) {
      Student std = new Student("Krishna");
   }
}

Kesalahan waktu kompilasi

Student.java:17: error: name has private access in Person
   System.out.println("Name: "+super.name);
                                    ^
1 error
_

Untuk mengakses anggota privat superclass, Anda perlu menggunakan metode setter dan getter dan memanggilnya menggunakan objek subclass

Anggota yang dideklarasikan dilindungi hanya dapat diakses di dalam kelas itu sendiri dan oleh kelas yang diwariskan dan kelas induk. Anggota yang dideklarasikan sebagai pribadi hanya dapat diakses oleh kelas yang mendefinisikan anggota tersebut

Ini benar-benar berfungsi. Yaitu jika saya mendeklarasikan sesuatu yang dilindungi atau pribadi, itu tidak dapat diakses dari sebuah instance (ala $a->prop; ). Dan ketika saya mendeklarasikan sesuatu sebagai pribadi, itu hanya dapat berada di dalam kelas itu sendiri dan, secara teoritis dan fungsional , tidak diteruskan ke ekstensi apa pun dari kelas root. Dalam praktiknya ini tampaknya berhasil. jika saya mendeklarasikan $prop sebagai private $this->prop tidak akan berfungsi di kelas anak (kecuali saya mendeklarasikan $prop private lain di dalam kelas anak itu).

Oke sekarang Anda mengatakan dengan baik jika Anda akan melakukannya lalu mengapa tidak membuat $prop protected alih-alih pribadi? . sekali lagi ini berfungsi, secara fungsional .

Pertanyaan saya adalah tentang sesuatu yang saya perhatikan melalui objek var_dumps

		class Test1{
		public 		$tesVar	=	'Veronica';
		public 		$hold	=	array();
		protected 	$name	=	'';
		public 		$another=	'other';
		private 	$births	=	'Test2';
		private 	$OnlyHere	=	'only once';

		function Test1($name){
			$this->name=$name;
		}
		function output (){
				foreach ($this as $k=>$that){
					echo $k,'=',$that,'<br>';
				}
				if (isset($this->OnlyHere)) {echo $this->OnlyHere.'<br>';}
				else {echo "just chickens!";}
				echo    '<b>I produce ', (($this->births) ?$this->births:'nothing'),'</b><br>' ;
				echo '-----<br>';
		
		}
		function makeChild ($name="anonn"){
			if($this->births)  { 
				$this->hold[$name]=new $this->births($name);
				return $this->hold[$name];
			} 
			return false;
		}
	}
	class Test2 extends Test1{
		private 	$births		=	'Test3';
	}
	class Test3 extends Test2{
		private 	$births		=	false;// neuters class
	}
	
	$Test1=new Test1('Start');

	$Test1->tesVar="And Ray";
	$Test1->makeChild("first");
	$Test1->hold['first']->makeChild('second');
	echo'<pre>';
	$Test1->hold['first']->output();
	var_dump($Test1);


Ketika properti adalah PRIVATE, itu masih muncul di var_dump objek turunan, bahkan jika TIDAK dideklarasikan di kelas mereka (saya berharap ini untuk DILINDUNGI, tetapi tidak untuk PRIVATE). Ini adalah .. properti tidak dapat diakses .. tetapi TAMPAKNYA sudah disetel?. ?

Lebih aneh lagi, jika Anda mendeklarasikan kembali properti pribadi sehingga memiliki nilai yang berbeda… maka Anda memiliki GANDA instance dari properti yang sama (sekali lagi hanya yang baru saja dideklarasikan yang benar-benar dapat diakses dari kelas… tetapi masih aneh)


object(Test1)#1 (5) {
  ["tesVar"]=>
  string(7) "And Ray"
  ["hold"]=>
  array(1) {
    ["first"]=>
    object(Test2)#2 (6) {
      ["births:private"]=>
      string(5) "Test3"
      ["tesVar"]=>
      string(8) "Veronica"
      ["hold"]=>
      array(1) {
        ["second"]=>
[I]        object(Test2)#3 (6) {
[B]          ["births:private"]=>
          string(5) "Test3"[/B]
          ["tesVar"]=>
          string(8) "Veronica"
          ["hold"]=>
          array(1) {
            ["anonn"]=>
            object(Test2)#4 (6) {
              ["births:private"]=>
              string(5) "Test3"
              ["tesVar"]=>
              string(8) "Veronica"
              ["hold"]=>
              array(0) {
              }
              ["name:protected"]=>
              string(5) "anonn"
              ["another"]=>
              string(5) "other"
[B]              ["births:private"]=>
              string(5) "Test2"[/B]
            }
          }[/I]
          ["name:protected"]=>
          string(6) "second"
          ["another"]=>
          string(5) "other"
          ["births:private"]=>
          string(5) "Test2"
        }
      }
      ["name:protected"]=>
      string(5) "first"
      ["another"]=>
      string(5) "other"
      ["births:private"]=>
      string(5) "Test2"
    }
  }
  ["name:protected"]=>
  string(5) "Start"
  ["another"]=>
  string(5) "other"
  ["births:private"]=>
  string(5) "Test2"
}


'Semi-duplikasi' ini tidak terjadi jika properti disetel ke DILINDUNGI alih-alih PRIBADI, tetap saja tampaknya tidak masuk akal juga

JUGA
Dalam pengujian saya 'hanya sekali' tidak boleh digaungkan karena properti yang memuatnya adalah PRIVATE dan tidak diwarisi oleh kelas anak
Saya akan berharap, bahwa dalam objek apa pun, TETAPI salah satu kelas TEST1, isset( $this->OnlyHere) itu akan salah

Sebenarnya, ini bahkan lebih berbelit-belit dari itu. Apa yang tampaknya terjadi adalah FUNGSI YANG DIPEROLEH (output()), dieksekusi di kelas root dan bukan di kelas instance, dan dengan demikian mereka juga memiliki akses ke semua properti kelas root PRIVATE. Solusinya adalah dengan menulis ulang fungsi SAMA PERSIS dalam kelas anak pertama. Tapi bukankah itu meniadakan inti dari OOP?

Bisakah seseorang menjelaskan (disederhanakan) tentang hal ini?

Ini bekerja persis seperti yang seharusnya. Menyetel properti ke kehendak pribadi tidak menghentikannya untuk diwariskan. Itu masih dipakai dan diberi nilai oleh kelas root. Satu-satunya perbedaan antara private dan protected adalah apakah kelas anak memiliki akses langsung ke nilainya atau tidak. Dalam contoh Anda, fungsi output() menggemakan semua variabel dalam cakupannya

Misalnya, pikirkan tentang cara kerja fungsi get dan set. Mereka mengizinkan akses ke variabel anggota pribadi oleh seorang anak tanpa mengizinkan akses langsung ke nilai itu sendiri. Jika fungsi induk tidak memiliki akses ke nilai dalam cakupannya sendiri, maka tidak akan ada alasan keberadaannya

Misalnya

<?php

class Test1 {
    
    private $name;
    
    public function __construct(){}
    
    public function set( $name )
    {
            $this->name = $name;
    } 
    
    public function getName()
    {
        return $this->name;
    }
    
    public function parentOutput()
    {
        echo $this->name . '<br />';
    }
    
}

class Test2 extends Test1 {
    
    public function __construct( $name ) 
    {
        $this->set( $name ); // works because it is a function defined in the parent and retains access to parent variable. 
       
    }
    
    public function childOutput()
    {
        echo $this->name . '<br />'; // will no work because the value exists but is invisible in the current scope.
    }
    
    
}

$test = new Test2( 'John Doe' );
$test->parentOutput(); // will display the name 
$test->childOutput(); // will cause an error
_

Memanggil metode keluaran akan menampilkan nama karena fungsi tersebut dideklarasikan di kelas induk dan mempertahankan akses ke semua variabel anggota induk

Memanggil metode childOutput akan menimbulkan kesalahan karena dideklarasikan di kelas anak. Meskipun mewarisi variabel nama, ia tidak dapat melihatnya atau mengaksesnya tanpa menggunakan fungsi getName

Namun, jika kita menulis ulang childOutput berikut ini akan berhasil, karena fungsi getName mempertahankan akses ke variabel nama


    public function childOutput()
    {
        echo $this->getName() . '<br />'; // value access through parent function
    }

Apakah ini membantu sama sekali?

Ini berfungsi persis seperti yang seharusnya. Menyetel properti ke kehendak pribadi tidak menghentikannya untuk diwariskan. Satu-satunya perbedaan antara private dan protected adalah apakah kelas anak memiliki akses langsung ke nilainya atau tidak.

Itulah yang saya coba konfirmasi. Masuk akal bagi saya sejak awal, tetapi juga tampak 'boros' karena properti yang tidak dapat diakses masih disimpan di kelas anak (jika itu masuk akal)

Saya memiliki SATU PERTANYAAN yang tersisa, dan metode yang diwariskan tampaknya bertindak seolah-olah mereka berada di kelas induk (dan karena itu mereka memiliki akses ke properti atau nilai properti yang ditetapkan pada lingkup induk

Mungkin ini bukan tujuan pewarisan dan saya salah berpikir seperti ini.. yaitu bahwa metode pewarisan memiliki ruang lingkup saat ini, bukan ruang lingkup induk. Alasan saya merasa tidak praktis adalah karena (karena Anda pada dasarnya menggunakan ini dalam contoh Anda) variabel ajaib $this->… akan selalu menunjuk ke kelas dari mana metode tersebut diwariskan dan BUKAN kelas saat ini… kecuali metode tersebut disalin

Inilah yang saya maksud



class Test1 {

    private $name;
    private $value= 10;
    public function output()
    {
        echo $this->value . '<br />'; //
    }

}
class Test2 extends Test1 {
   private  $value=5; // for the sake  of example, lets say $value must be '5' anytime an intance of Test2 is dealt with.
}

$test = new Test2();
$test->output(); // will display the 'value' property of the class ; one would expect '10' if Test1, '5' if Test2.



_

Ini berfungsi, namun jika kita menulis ulang fungsi lagi di kelas anak (tentu saja hal itu mengalahkan upaya apa pun untuk berhemat kode dan membuat kode menjadi berlebihan)

 class Test1 {

    private $name;
    private $value= 10;
    public function output()
    {
        echo $this->value . '<br />'; //
    }

}
class Test2 extends Test1 {
   private  $value=5;
    public function output()
    {
        echo $this->value . '<br />'; //
    }

}

$test = new Test2();
$test->output(); // will display the 'value' property of the class ; one would expect '10' if Test1, '5' if Test2.



Tampaknya perbaikan yang cukup sederhana untuk hanya membuat $value protected , bukan publik, tetapi bagaimana jika $value tidak seharusnya ada sama sekali di TEST 2?



class Test1 {

    private $name;
    private $value= 10;
    public function output()
    {
        echo $this->value . '<br />'; //
    }

}
class Test2 extends Test1 {}
$test = new Test2();
$test->output();

_

Saya masih menampilkan 1) dan menghapus $value di Test2 tidak akan membantu, karena fungsinya benar-benar berjalan di Test1 dan bekerja pada properti Test1, meskipun itu adalah turunan dari Test2. semoga pertanyaan saya masuk akal…

Jika Tes 2 seharusnya tidak memiliki $nilai, maka Anda tidak boleh mewarisi dari kelas yang berisi $nilai (mis. Tes1). Mewarisi berarti Anda mengambil semua metode dan variabel dari kelas yang Anda perluas. Anda harus menggunakan variabel pribadi karena metode di kelas yang diwariskan mungkin memerlukan penggunaan variabel pribadi tersebut

Sekarang ketika Anda mendefinisikan ulang output(), Anda benar-benar menimpa metode dasar untuk output di Test1, jadi ketika Anda memiliki instance Test2()->output() Anda menjalankan output yang ditentukan dalam Test2() alih-alih Test1()

Memperluas paling baik diringkas dengan contoh berikut (setidaknya itu selalu membantu saya


class Animal
{
  private $fed = false;
  protected $type = "Unknown";
  public function MakeNoise()
  {
    echo "No Noise Defined";
  }

  public function GetType()
  {
    echo "Type of " . $this->type;
  }

  public function FeedMe()
  {
    $this->fed = true;
  }

  public function HasBeenFed()
  {
    return $this->fed;
  }
}

class Dog extends Animal
{
  public function __construct()
  {
    $this->type = "Dog";
  }

  public function MakeNoise()
  {
    echo "Woof Woof";
  }
}

class Cat extends Animal
{
  public function __construct()
  {
    $this->type = "Cat";
  }

  public function MakeNoise()
  {
    echo "Meow Meow";
  }
}

$dog = new Dog();
$dog->GetType(); // Type of Dog
$dog->MakeNoise(); // Woof Woof
$dog->HasBeenFed(); // false;
$dog->FeedMe();
$dog->HasBeenFed(); // true;
$cat = new Cat();
$cat->GetType(); // Type of Cat
$cat->MakeNoise(); // Meow Meow
$cat->HasBeenFed(); // false;
$cat->FeedMe();
$cat->HasBeenFed(); // true;
$animal = new Animal();
$animal->GetType(); // Type of Unknown
$animal->MakeNoise(); // No Noise Defined
$animal->HasBeenFed(); // false;
$animal->FeedMe();
$animal->HasBeenFed(); // true;

_

Baik Anjing maupun Kucing, tidak dapat mengakses $this->fed, tetapi memanggil HasBeenFed dan FeedMe sama-sama membutuhkan dan memiliki akses ke $this->fed

Saya tidak pernah benar-benar memikirkannya seperti itu. Masalahnya dengan PHP adalah memungkinkan kita untuk lolos dengan banyak hal yang tidak dapat kita lakukan dengan bahasa yang diketik secara ketat

Saat mewarisi kelas, konstruktor induk harus selalu dipanggil secara eksplisit. Anak itu tidak secara ajaib mendapatkan akses ke metode di kelas induk. Pertama-tama harus membuat instance yang dapat diakses yang dapat digunakan. Jadi sungguh, meskipun metode orang tua dapat diakses oleh anak, mereka harus tetap beroperasi dalam ruang lingkupnya sendiri. Orang tua tidak tahu bahwa itu telah diwariskan atau diperpanjang dan bertindak seperti itu

Hal lain yang perlu diingat adalah Anda selalu dapat mengakses metode yang telah diganti menggunakan induknya. operator


<?php

 class Test1 { 
     
    private $value = 10; 
    
    public function __construct( $value )
    {
        $this->value = $value;
    }
    public function output() 
    { 
        echo 'Test1\\'s value is ' . $this->value . '<br />'; // 
    } 
} 

class Test2 extends Test1 { 
    private  $value = 5;    

    public function __construct( $value )
    {
       parent::__construct( $value );
       $this->value = $value * 2;
    }
    public function output() 
    { 
        parent::output(); // outputs 5
        echo 'Test2\\'s value is ' . $this->value . '<br />'; // outputs 10
    }   
}

$test = new Test2( 5 ); 
$test->output(); 

Juga seperti yang dikatakan cpradio, jika Anda memperluas kelas yang memiliki nilai yang tidak Anda perlukan, maka arsitektur objek yang Anda gunakan harus dievaluasi ulang. Keindahan pemrograman adalah Anda dapat membuatnya bekerja dengan cara apa pun yang paling sesuai untuk Anda

Dapatkah variabel pribadi diwariskan dalam php?
Jeff_Mott

Kasus untuk dan melawan pribadi vs dilindungi. http. //fabien. potensi. org/article/47/pragmatism-over-theory-protected-vs-private

Koreksi saya jika saya salah, tetapi bukankah inti dari artikel ini menyatakan bahwa seseorang yang sebelumnya tidak pernah menggunakan private untuk apa pun, sekarang melakukannya, dan mendukung sehingga membantu API-nya?

Mungkin, saya terlalu sering bekerja di API di mana Anda hanya memaparkan apa yang bermakna dan masuk akal dan tidak lebih. Saya terutama menulis komponen yang berinteraksi dengan pihak ketiga atau layanan dalam perusahaan lokal, jadi saya terus bertanya pada diri sendiri (apakah ini sesuatu yang ingin/perlu ditimpa seseorang?) Jika jawabannya tidak 100% ya, itu akan ditandai

Jadi apakah saya melewatkan sesuatu tentang mengapa dilindungi lebih dihargai daripada pribadi? . Beri saya skenario kasus nyata di mana Anda menggunakan metode pribadi (dan Anda tanpa ragu memutuskan itu tidak akan atau perlu diperpanjang) dan Anda harus mengubahnya ke dilindungi/publik

Beberapa jawaban dan keterlibatan diri hanya datang dengan mengulangi pertanyaan yang sama pada munculnya jawaban lain untuk memaksa analisis seluk-beluk pertanyaan awal.

Pada tingkat teknis "metode override" telah menjadi jawaban yang diperbolehkan karena warisan dan metode yang dilindungi. Pertanyaan yang lebih dalam adalah mengapa metode override dan mengotak-atik rantai pewarisan diperlukan dan apakah harus mengutak-atik adalah tanda masalah desain lain yang lebih dalam.

Banyak kekeruhan topik ini berasal dari kebingungan bahwa pewarisan (detail implementasi teknis) sama dengan prinsip substitusi polimorfisme/Liskov (detail komunikasi/antarmuka eksternal)

Pokoknya saya akan menunjukkan bahwa jawaban sebenarnya terletak di luar komunitas PHP karena memiliki kebiasaan mengulangi semua yang nenek moyang kita lakukan namun najis demi pengalaman diri terkadang tanpa sadar mengubah merek praktik buruk dengan nama baru yang keren. Ada beberapa dekade informasi dan pengalaman untuk dikumpulkan tentang topik ini

Bisakah variabel pribadi diwariskan?

Anggota Pribadi di Superclass . Namun, jika superclass memiliki metode publik atau yang dilindungi untuk mengakses field privatnya, ini juga dapat digunakan oleh subclass. A subclass does not inherit the private members of its parent class. However, if the superclass has public or protected methods for accessing its private fields, these can also be used by the subclass.

Apakah metode pribadi diwariskan dalam PHP?

Metode kelas PHP yang dideklarasikan pribadi tidak dapat diakses oleh kelas anak, tetapi kelas anak dapat mendeklarasikan metode dengan nama yang sama tanpa harus mematuhi Prinsip Pergantian Liskov

Bagaimana cara mengakses variabel pribadi di PHP?

PHP OOP - Pengubah Akses .
publik - properti atau metode dapat diakses dari mana saja. Ini default
dilindungi - properti atau metode dapat diakses di dalam kelas dan oleh kelas yang berasal dari kelas itu
pribadi - properti atau metode HANYA dapat diakses di dalam kelas

Apakah PHP memiliki variabel pribadi?

Cara terbaik untuk mendeklarasikan variabel pribadi di Kelas PHP adalah dengan membuatnya di atas metode __Construction , dengan konvensi Anda dapat memulai variabel dengan garis bawah setelah tanda dolar ( . e $_private_variable) untuk memberi tahu pemrogram lain yang membaca kode Anda bahwa itu adalah variabel pribadi, brilian.