I am trying to use a display function in my extened class that first fetches a display function in the parent class. It however does not display the variable in the echo statement. The gameType (In this case "One-day") does not display.
<?php
class Cricket
{
protected $gameType;
function __construct($gameType)
{
$this->gameType=$gameType;
}
function display()
{
echo 'The cricket match is a ' . $this->gameType . " match";
}
}
class Bowler extends Cricket
{
public $type;
public $number;
function __construct($type,$number)
{
$this->type=$type;
$this->number=$number;
parent::__construct($this->gameType);
}
function display()
{
parent:: display();
echo " with " . $this->number . " " . $this->type . " bowler";
}
}
$one = new Cricket("day-night");
$one->display();
echo'<br>';
$two = new Cricket("day-night");
$two = new Bowler("left-hand","2");
$two->display();
?>
The process of instantiating your Bowler class will in fact, as is implied by calling the parents constructor parent::__construct();, create a brand new Cricket class as well as the Bowler class.
So attempting to access a property of this newly created Cricket class makes no sense.
So when you instantiate the Bowler class you will also have to pass any data that the Cricket class requires for it's successful construction.
So for example
<?php
class Cricket
{
protected $gameType;
function __construct($gameType)
{
$this->gameType=$gameType;
}
function display()
{
echo 'The cricket match is a ' . $this->gameType . " match";
}
}
class Bowler extends Cricket
{
public $type;
public $number;
function __construct($gameType, $type, $number)
{
$this->type=$type;
$this->number=$number;
parent::__construct($gameType);
}
function display()
{
parent:: display();
echo " with " . $this->number . " " . $this->type . " bowler";
}
}
$two = new Bowler('day-night', "left-hand","2");
$two->display();
Related
I am writing this simple code and do not know what the issue with constructor is:
class Animal {
public $_type;
public $_breed;
public function __construct ($t, $b) {
echo "i have initialized<br/>";
$this ->_type = $t;
$this ->_breed = $b;
echo "type is " .$_type. "<br/>";
echo "breed is " .$_breed. "<br/>";
}
public function __destruct () {
echo "i am dying";
}
}
$dog = new Animal("Dog", "Pug");
Why do you have a space after $this? Remove the space.
Also, add $this when calling a variable.
class Animal {
public $_type;
public $_breed;
public function __construct ($t, $b) {
echo "i have initialized<br/>";
$this->_type = $t; // <-- remove space
$this->_breed = $b; // <-- remove space
echo "type is " .$this->_type. "<br/>"; // <-- add $this
echo "breed is " .$this->_breed. "<br/>"; // <-- add $this
}
public function __destruct () {
echo "i am dying";
}
}
You are initializing them fine, but retrieving them wrong...
Since $_type and $_breed are scoped at the object level, you need to tell PHP what scope you're referencing them in.
Therefore, instead of
echo $_breed;
You need
echo $this->_breed;
On a side note, it's very strange practice to prefix variable names with _ these days, even moreso if they are public variables. This will likely confuse other developers working with your code.
Try this (note the echo lines):
class Animal {
public $_type;
public $_breed;
public function __construct ($t, $b) {
echo "i have initialized<br/>";
$this->_type = $t;
$this->_breed = $b;
//You have to use '$this' keyword to access
//class attibutes:
echo "type is " . $this->_type . "<br/>";
echo "breed is " . $this->_breed . "<br/>";
}
public function __destruct () {
echo "i am dying";
}
}
$_type and $_breed is variable of class so you need to use using this keyword
echo "type is " .$this->_type. "<br/>";
echo "breed is " .$this->_breed. "<br/>";
Although this not violate the syntax of the php, I suggest that this two lines
echo "type is " .$dog->_type. "<br/>";
echo "breed is " .$dog->_breed. "<br/>";
must not be put in __construct() instead use this outside the class,
Like this,
class Animal {
public $_type;
public $_breed;
public function __construct ($t, $b) {
$this ->_type = $t;
$this ->_breed = $b;
}
public function __destruct () {
echo "i am dying";
}
}
$dog = new Animal("Dog", "Pug");
echo "i have initialized<br/>";
echo "type is " .$dog->_type. "<br/>";
echo "breed is " .$dog->_breed. "<br/>";
With constructor property promotion in PHP 8, you can now declare and set properties as parameters of the constructor.
See here.
class someClass
{
// Can delete these declarations and put them in the constructor instead //
/*
protected int $id;
protected string $name;
protected int $type;
protected string $frontend_name;
protected int $account_id;
protected someOtherClass $object;
*/
public function __construct(
protected int $id,
protected string $name,
protected int $type,
protected string $frontend_name,
protected int $account_id,
protected someOtherClass $object,) // you can also have a trailing comma now!
{
$this->init();
}
protected function init() {
// do other stuff
}
}
I have made a very basic type of my class and as mentioned in question Why child object can not access inherited function from its parent? I have added one new field and new constructor. show_param() is defined in parent class but I can not use it in child class?!
<?php
class Test {
private $age;
private $fname;
private $lname;
public function __construct($age,$fname,$lname)
{
$this->age = $age;
$this->fname = $fname;
$this->lname = $lname;
echo "A new constructor in " . __CLASS__ . ".<br />";
}
public function __destruct()
{
echo 'The class "', __CLASS__, '" was destroyed.<br />';
}
public function set_age($age)
{
$this->age = $age;
}
public function get_age()
{
return $this->age;
}
public function __toString()
{
return $this->fname." ".$this->lname;
}
public function show_param()
{
echo $this->age."<br />";
echo $this->fname."<br />";
echo $this->lname."<br />";
}
}
//Child definition
class T1 extends Test
{
private $level;
public function __construct($age,$fname,$lname,$level)
{
$this->level = $level;
$this->age = $age;
$this->fname = $fname;
$this->lname = $lname;
echo "A child constructor in " . __CLASS__ . ".<br />";
}
public function get_level()
{
return $this->level;
}
public function set_level($level)
{
$this->level= $level;
}
}
$a = new T1(23,"Bernard","Grey","Under");
echo $a->show_param();
?>
Result:
A child constructor in T1.
A child constructor in T1.
The class "Test" was destroyed.
The class "Test" was destroyed.
Expected:
A child constructor in T1.
A child constructor in T1.
Bernard
Grey
23
The class "Test" was destroyed.
The class "Test" was destroyed.
Use the parent`s constructor in class T1:
class T1 extends Test
{
private $level;
public function __construct($age,$fname,$lname,$level)
{
parent::__construct($age,$fname,$lname);
$this->level = $level;
echo "A child constructor in " . __CLASS__ . ".<br />";
}
public function get_level()
{
return $this->level;
}
public function set_level($level)
{
$this->level= $level;
}
}
I am trying to make a php product which works out area and perimeter of different shapes. There are different shapes e.g. square, rectangle, circle, triangles etc.
I currently have Total Area of all shapes, count how many shapes were worked out, highest perimeter working and there is the code for it,
edit2:
abstract class Shapes
{
protected $name;
protected $colour;
function __construct($n, $c)
{
$this->name = $n;
$this->colour = $c;
}
abstract public function area();
abstract public function perimeter();
public function printShape()
{
}
thanks
In your Shapes class, create a getter (method) called getName that returns the $name property.
e.g.
abstract class Shapes
{
protected $name;
protected $colour;
function __construct($n, $c)
{
$this->name = $n;
$this->colour = $c;
}
abstract public function area();
abstract public function perimeter();
public function printShape()
{
print "<h6>The area of the " . $this->colour . " " . $this->name . " is " . $this->area(
) . " and the perimeter is " . $this->perimeter() . "</h6>";
}
public function getName()
{
return $this->name;
}
}
Class a {
public function __construct($a){
$this->age = $a;
}
}
Class b extends a {
public function printInfo(){
echo 'age: ' . $this->age . "\n";
}
}
$var = new b('age');
$var->printInfo();
I understand how this code works, however is it possible to pass arguments to the constructor of the class and parent class?
My attempt below is causing an error
Class a {
public function __construct($a){
$this->age = $a;
}
}
Class b extends a {
public function __construct($name){
$this->name = $name;
}
public function printInfo(){
echo 'name: ' . $this->name . "\n";
echo 'age: ' . $this->age . "\n";
}
}
$var = new b('name', 'age');
$var->printInfo();
?>
Yes, you simply need to use the parent::__construct() method.
Like so:
class a{
/**
* The age of the user
*
* #var integer
*/
protected $age;
function __construct($a){
$this->age = $a;
}
}
class b extends a{
/**
* The name of the user
*
* #var string
*/
protected $name;
function __construct($name,$age){
// Set the name
$this->name = $name;
// Set the age
parent::__construct($age);
}
public function printInfo(){
echo 'name: ' . $this->name . "\n";
echo 'age: ' . $this->age . "\n";
}
}
$var = new b('name','age');
$var->printInfo();
Just make sure the variables are set to public or protected!
You can pass value to the parent constructor but the way you are doing is wrong,
$var = new b('name', 'age');
it is as if the child class accepts two parameters in its constructor but in real it has only one parameter.
You can pass parameter to parent constructor something like this
parent::__construct($var);
So change you class b to this
Class b extends a {
public function __construct($name, $age){
$this->name = $name;
parent::__construct($age);
}
public function printInfo(){
echo 'name: ' . $this->name . "\n";
echo 'age: ' . $this->age . "\n";
}
}
Yes you can pass the argument to the class as well as parent class
Class a {
public function __construct($age){
$this->age = $a;
}
}
Class b extends a {
public function __construct($name,$age){
parent::__construct($age);
$this->name = $name;
}
}
$var = new b('name', 'age');
?>
Just call parent::__construct in the child. for example
class Form extends Tag
{
function __construct()
{
parent::__construct();
// Called second.
}
}
Here is how is should go:
<?php
class a {
private $age;
public function __construct($age){
$this->age = $age;
}
public function getAge()
{
return $this->age;
}
}
class b extends a {
private $name;
public function __construct($age, $name){
parent::__construct($age);
$this->name = $name;
}
public function printInfo(){
echo 'name: ' . $this->name . "\n";
echo 'age: ' . $this->getAge() . "\n";
}
}
$b = new b(20, "Bob");
$b->printInfo();
?>
I am struck at overloading the parent's class methods from an inherited child at level2.
abstract class parent
-> child1 extends parent
-> final class child2 extends child1
I want to overload the methods of parent in child2
abstract class Shape
{
protected $length;
protected $height;
protected $a;
protected $b;
protected $c;
public function getCoordinates($length,$height)
{
$this->length=$length;
$this->height=$height;
}
public function getSides($a,$b,$c)
{
$this->a=$a;
$this->b=$b;
$this->c=$c;
}
abstract public function area();
abstract public function perimeter();
abstract public function display();
}
class rectangle extends Shape
{
public function area()
{
return round(($this->length)*($this->height),2);
}
public function perimeter()
{
return round(2*(($this->a)+($this->b)),2);
}
public function display()
{
echo "area is :". rectangle::area() . "<br>";
echo "perimeter is : ". rectangle::perimeter() ."<br>";
}
}
final class triangle extends rectangle
{
function __call($method_name, $arguments) // this is wrong ........please modify here to call area(),which is in shape class();
{
$accepted_methods = array("getCoordinates","area","perimeter");
}
public function area()
{
return round((($this->length)*($this->height)*($this->width)/2),2);
}
public function perimeter()
{
return round((($this->a)+($this->b)+($this->c)),2);
}
public function getCoordinates($length,$height,$width)
{
$this->length=$length;
$this->height=$height;
$this->width=$width;
}
public function display()
{
echo "area is :". triangle::area() . "<br>";
echo "perimeter is : ". triangle::perimeter() ."<br>";
}
}
$r=new rectangle();
$r->getCoordinates(1,2,4);
$r->getSides(6,2);
$r->display();
$ot = new triangle();
$ot->getCoordinates(1,2,4);
$ot->getSides(6,2,3);
$ot->display();
?>
Thanks in advance
$r->getSides(6,2);
Your abstract class demands three arguments! Plus the function is actually a setter method. You should name it setSides();. Same with getCoordinates().
Update: I think you are confusing inheritance with overloading. Here is an example for overloading with __call. I assume that's not what you are trying to do but what you have in your example. Maybe this will help.
abstract class overloadTestAbstract {
public function printOne($show) {
echo __METHOD__ . ': ' . $show . '<br />';
}
}
class overloadTestOne extends overloadTestAbstract {
public function __call($method,$arguments) {
$methods = array('printOne','printTwo','printThree');
if ( in_array($method,$methods) ) {
echo __METHOD__ . ' :OVERLOAD METHOD: ' . $arguments[0] . '<br />';
} else {
echo 'We are so sorry, but this method is available';
}
}
public function printTwo($show) {
echo __METHOD__ . ': ' . $show . '<br />';
}
}
Then if you do this:
$test = new overloadTestOne();
$test->printOne('Hello World');
$test->printTwo('Goodbye World');
$test->printThree('Hello World, again');
$test->printFour('Goodbye World, again');
you will get this
// print results
'overloadTestAbstract::printOne: Hello World'
'overloadTestOne::printTwo: Goodbye World'
'overloadTestOne::__call :OVERLOAD METHOD: Hello World, again'
'We are so sorry, but this method is available'
Although I have printOne and printTwo in the overload __call as accepted methods they are not used because these methods are already defined, they are handled by the existing methods as expected. On the other hand printThree gets overloaded because the method does not exist. Same with printFour but that method has no intend to print the argument. The array you have defined with the accepted methods doesn't do a thing. It is just an array. You have to assign some task to these methods or return some error like I did.