I have the following code:
Class definition:
<?php
class Person{
var $name;
public $height;
protected $socialInsurance = "yes";
private $pinnNumber = 12345;
public function __construct($personsName){
$this->name = $personsName;
}
public function setName($newName){
$this->name = $newName;
}
public function getName(){
return $this->name;
}
public function sayIt(){
return $this->pinnNumber;
}
}
class Employee extends Person{
}
And the part with instances:
<!DOCTYPE html>
<HTML>
<HEAD>
<META charset="UTF-8" />
<TITLE>Public, private and protected variables</TITLE>
</HEAD>
<BODY>
<?php
require_once("classes/person.php");
$Stefan = new Person("Stefan Mischook");
echo("Stefan's full name: " . $Stefan->getName() . ".<BR />");
echo("Tell me private stuff: " . $Stefan->sayIt() . "<BR />");
$Jake = new Employee("Jake Hull");
echo("Jake's full name: " . $Jake->getName() . ".<BR />");
echo("Tell me private stuff: " . $Jake->sayIt() . "<BR />");
?>
</BODY>
</HTML>
Output:
Stefan's full name: Stefan Mischook.
Tell me private stuff: 12345
Jake's full name: Jake Hull.
Tell me private stuff: 12345 // Here I was expecting an error
As I understand, the private variable is accessible only from it's own class, and the protected variable is accessible also from the classes that extend the class. I have the private variable $pinnNumber. So I expected, that I get an error if I call $Jake->sayIt(). Because $Jake is member of class Employee that extends class Person. And the variable $pinnNumber should be accessible only from class Person, not from the class Employee.
Where is the problem?
Actually, that's not how it works.
As you didn't extend the sayIt() method, there is no "accessibility problem", there would be one if you did something like this:
<?php
class Person{
var $name;
public $height;
protected $socialInsurance = "yes";
private $pinnNumber = 12345;
public function __construct($personsName){
$this->name = $personsName;
}
public function setName($newName){
$this->name = $newName;
}
public function getName(){
return $this->name;
}
public function sayIt(){
return $this->pinnNumber;
}
}
class Employee extends Person{
public function sayIt(){
return $this->pinnNumber;//not accessible from child class
}
}
Protected, public and private are just enviroment scopes, in your case, for a Class. Since your satIt() function is public, you can access the function which then has the correct enviroment scope to access any private or protected variables.
If you tried to do:
$Jake->pinnNumber
Outside the Class, then you'd get the error.
You should research more about Scopes in methods and Classes, then you can move onto anonymous functions ;)
Related
I am experimenting with php class inheritance, I wrote the below code and got an uncaught error that the User class is not found. Please any help about where am going wrong will be fine.
the first block is the User class
<?php
class User{
private $name;
private $age;
public function _construct($name, $age){
$this->name = $name;
$this->age = $age;
}
}
?>
below is the customer class that inherit the user class.
<?php
class Customer extends User{
private $balance;
public function __construct($name, $age, $balace) {
parent::_construct($name, $age);
$this->balance = $balace;
}
public function pay($amount){
return $this->name ." paid $".$amount;
}
public function getBalance(){
return $this->balance;
}
}
$customer = new Customer("Matt", 23, 500);
echo $customer->getBalance();
I have checked your code by implementing it in a single file. It works fine.
If you are having 2 files for both classes, you need to include the User class file into the Customer class file like below.
require_once('User.php');
Shouldn't it generate error when i try to set the value of a property from the extended class instead of a base class?
<?php
class first{
public $id = 22;
private $name;
protected $email;
public function __construct(){
echo "Base function constructor<br />";
}
public function printit(){
echo "Hello World<br />";
}
public function __destruct(){
echo "Base function destructor!<br />";
}
}
class second extends first{
public function __construct($myName, $myEmail){
$this->name = $myName;
$this->email = $myEmail;
$this->reveal();
}
public function reveal(){
echo $this->name.'<br />';
echo $this->email.'<br />';
}
}
$object = new second('sth','aaa#bbb.com');
?>
Private variables are not accessible in subclasses. Thats what the access modifier protected is for. What happened here is that when you access a variable that doesn't exist, it creates one for you with the default access modifier of public.
Here is the UML to show you the state:
Please note: the subclass still has access to all the public and protected methods and variables from its superclass - but are not in the UML diagram!
The following code does not produce the output with the name Jock. I suspect because in the class Animal the $name is private, but the construct is public so should the subclass not be able to get the $name from the construct. I do not want to make $name public.
class Animal{
private $name;
public function __construct($name) {
$this->name = $name;
}
public function Greet(){
echo "Hello, I'm some sort of animal and my name is ", $this->name ;
}
}
class Dog extends Animal{
private $type;
public function __construct($name,$type) {
$this->type = $type;
parent::__construct($name);
}
public function Greet(){
echo "Hello, I'm a ", $this->type, " and my name is ", $this->name;
}
}
$dog2 = new Dog('Jock','dog');
$dog2->Greet();
You are right: delete the private variable or use protected in the first line of the class animal and you're fine.
class Animal{
protected $name; //see here!
public function __construct($name) {
$this->name = $name;
}
public function Greet(){
echo "Hello, I'm some sort of animal and my name is ".$this->name ;
}
}
$animal = new Animal("Gizmo");
$animal->greet(); //produces the desired result.
echo $animal->name; //this will throw an error - unable to access protected variable $name
$name won't be public since it is an argument used in the public constructor and is therefore confined to the scope of that function. The property name on the dog will be public however unless you use protected.
Dots are used to concat strings. However echo allows commas to output multiple expressions.
public function Greet(){
echo "Hello, I'm a ".$this->type." and my name is ".$this->name;
}
Also when using double quotes; you can put the variables inside the string:
public function Greet(){
echo "Hello, I'm a $this->type and my name is $this->name";
}
the private variable only accessed inside the same class, you need to use protected for the name variable in class Animal.
class Animal{
protected $name;
public function __construct($name) {
$this->name = $name;
}
public function Greet(){
echo "Hello, I'm some sort of animal and my name is ", $this->name;
}
}
class Dog extends Animal{
private $type;
public function __construct($name,$type) {
$this->type = $type;
parent::__construct($name);
}
public function Greet(){
echo "Hello, I'm a ", $this->type, " and my name is ", $this->name;
}
}
$dog2 = new Dog('Jock','dog');
$dog2->Greet();
You could use setter & getter methods to help you modify and retrieve your instance variables without needing to declare them as public.
If you are using eclipse:
Right click on the class > Source > Generate Getters & Setters
which will create functions for all of your variables as so:
public String getName(){return this.name;}
public String setName(String name){this. name = name; }
You could then use these methods to access and edit your class variables
Shouldn't it generate error when i try to set the value of a property from the extended class instead of a base class?
<?php
class first{
public $id = 22;
private $name;
protected $email;
public function __construct(){
echo "Base function constructor<br />";
}
public function printit(){
echo "Hello World<br />";
}
public function __destruct(){
echo "Base function destructor!<br />";
}
}
class second extends first{
public function __construct($myName, $myEmail){
$this->name = $myName;
$this->email = $myEmail;
$this->reveal();
}
public function reveal(){
echo $this->name.'<br />';
echo $this->email.'<br />';
}
}
$object = new second('sth','aaa#bbb.com');
?>
Private variables are not accessible in subclasses. Thats what the access modifier protected is for. What happened here is that when you access a variable that doesn't exist, it creates one for you with the default access modifier of public.
Here is the UML to show you the state:
Please note: the subclass still has access to all the public and protected methods and variables from its superclass - but are not in the UML diagram!
I've been programming mainly with JAVA and have written procedural programs in PHP, but now I'm try to write some OOP bases programs in PHP and I'm facing a problem.
I've got two files , Zoo.php and Dog.php , each contains a class.
Dog.php:
<?php
class Dog {
private $name;
private $color;
public function __construct($name,$color) {
$this->name = $name;
$this->color = $color;
}
public function getName(){
return $this->name;
}
public function getColor(){
return $this->color;
}
}
And Zoo.php:
<?php
class Zoo {
private $name;
private $dogs;
public function __construct($name) {
$this->name = $name;
$dogs = array();
}
public function addDog($dogName,$dogColor){
$dog = new Dog($dogName,$dogColor);
array_push($this->dogs,$dog);
}
public function getAllDogs(){
var_dump($dogs);
}
}
echo "start";
$z = new Zoo("test_zoo");
$z->addDog("blackie","black");
$z->getAllDogs();
The code above outputs :
Fatal error: Class 'Dog' not found in C:\wamp\www\Zoo.php on line 13
I'd like to know what's wrong with the code above and how creating an object instance within another object should be done in PHP. Thanks in advance.
I gues you are not including Dog class.
<?php
include "Dog.php";
class Zoo {
/* ... */
}
Or you can use autoloading to auto include any class by default.
It's not about OOP. Just you forgot to include Dog file to use it you Zoo class :
<?php
include 'Dog.php'; // or whatever path
class Zoo { ...
Everything else should be ok and seems to be a good use of PHP OOP btw. :)
You haven't included your Dog.php in your Zoo.php. Therefore you can't create an new instance.
Just above class Zoo add this:
include("Dog.php");
class Zoo {
All you need to return function .
Three mistakes here, u'll see all of them in my code . Constructer nothing return , behave like void , so we need a method that returns dog specification.If you wanna use the classes in separate file, so u've to use php method that "include" or "require" or "require_once" etc ( see the difference of this method)
<?php
class Dog {
private $name;
private $color;
public function __construct($name,$color) {
$this->name = $name;
$this->color = $color;
}
public function getName(){
return $this->name;
}
public function getColor(){
return $this->color;
}
public function getDogs(){
return array("name"=>$this->name,"color"=>$this->color);
}
}
class Zoo extends Dog{
private $name;
private $dogs=array();
public function __construct($name) {
$this->name = $name;
$dogs = array();
}
public function addDog($dogName,$dogColor){
$dog = new Dog($dogName,$dogColor);
array_push($this->dogs,$dog->getDogs());
}
public function getAllDogs(){
var_dump($this->dogs);
}
}
echo "start";
$z = new Zoo("test_zoo");
$z->addDog("blackie","black");
$z->getAllDogs();
?>