// Solved
// I didn't echo output
I want to test static variable in traits.
what is the issue of static $city variable.
Here why $o::$city is not working
===============
trait Chargeable
{
public static $city = 'Dhaka';
public function charge()
{
echo "I am a Chargeable trait mehtod...... <br />";
}
abstract public function sayHello();
public static function myHello()
{
echo "Say My Hello ... ";
}
}
class Toy
{
}
class ElectricCarToy extends Toy
{
use Chargeable;
public function sayHello()
{
echo "Helloooo ....... <br />";
}
}
$o = new ElectricCarToy();
$o->charge();
$o->sayHello();
echo $o::$city;
$o::myHello();
======================
Output:
I am a Chargeable trait mehtod......
Helloooo .......
Say My Hello ...
please echo or print it like below
echo $o::$city.'<br />';
print($o::$city.'<br />');
Related
I need to create a work method that takes as a parameter an instance of the successor of Work. here is my code
declare(strict_types=1);
```
declare(strict_types=1);
interface Primat {
public function eat(bool $e);
public function drink(bool $d);
}
trait ofPlank{
function cofeeTime($cof){ echo 'drink cofee ';}
}
abstract class Human{
public string $name;
abstract public function work(string $work);
}
class Dev extends Human implements primat{
use ofPlank;
public $rank = array(
1=>'junior',
2=>'middle',
3=>'senior',
4=>'lead'
);
public int $rankState = 0;
public function __construct(int $currentRank)
{
$this->rankState = $currentRank;
}
public function show()
{
echo $this->rank[$this->rankState];
}
public function Up()
{
$this->rankState++;
}
public function Down()
{
$this->rankState--;
}
public function eat( $e)
{
if ($e ==1){
echo 'eat';}
else {
echo 'hungry';
}
// TODO: Implement eat() method.
}
public function drink($d)
{
if ($d ==1){
echo 'drink';}
else {
echo 'need water';
} ; // TODO: Implement drink() method.
}
use ofPlank;
public function work($work)
{
$work = 'go to work';
// TODO: Implement work() method.
}
} echo 'backend promotion from';
$backend = new Dev(1,);
echo $backend->show()."\n";
$backend->Up();
echo 'to ';
echo $backend->show()."\n";
echo '|backend need eat->';
$backend->eat($e=1);
//var_dump($backend);
echo '|ofplank ';
$backend->cofeeTime(cof );
?>
<br><?php
echo 'frontend lvl ';
$frontend = new dev(1,);
echo $frontend->show()."\n";
echo '|frontend need water->';
$backend->drink($d=2);
?>
<br>
<br>
<br>
<br>
<br>
```
I already tried to implement this task, and googled similar topics, nothing came out, I would be grateful if you tell me where to go or what to read. Thank you all for your time!
I am studying Head First - design patterns and translating the exercises to PHP.
I dont get any errors but there is a bug that I cannot figure out.
Edit ( Code ):
abstract class Cat
{
public $meowBehaviour, $eatBehaviour;
function __construct(MeowBehaviour $meowBehaviour, EatBehaviour $eatBehaviour)
{
$this->meowBehaviour = $meowBehaviour;
$this->eatBehaviour = $eatBehaviour;
}
public abstract function sits();
public function performMeowBehaviour()
{
$this->meowBehaviour->meow();
}
public function performEatBehaviour()
{
$this->eatBehaviour->eat();
}
}
interface EatBehaviour {
public function eat();
}
class EatCatFood implements EatBehaviour {
public function eat()
{
echo "I eat cat food. <br />";
}
}
class EatGazzelle implements EatBehaviour {
public function eat()
{
echo "I hunt and eat gazzelle. <br />";
}
}
interface MeowBehaviour {
public function meow();
}
class Meow implements MeowBehaviour {
public function meow()
{
echo "meow <br />";
}
}
class Roar implements MeowBehaviour {
public function meow()
{
echo "ROAR! <br />";
}
}
class HouseCat extends Cat
{
function __construct()
{
parent::__construct(new Meow, new EatCatFood);
}
public function sits()
{
echo "if I fits I sits";
}
}
class CatSimulator {
public $cat;
public function __construct()
{
$this->cat = new HouseCat;
$this->cat->performMeowBehaviour();
$this->cat->performEatBehaviour();
}
}
$c = new CatSimulator;
the output from CatSimulator is
meow
meow
I eat cat food.
I cannot figure out why 'meow' is repeated.
In PHP function names are case-insensitive. So here:
class Meow implements MeowBehaviour {
public function meow()
{
echo "meow <br />";
}
}
... meow() is treated as a constructor (PHP 4.x style) - and gets called on $this->cat = new HouseCat; line, echoing the first 'meow'.
You can rename the class, of course, but there's another alternative: add explicit constructor in that class, as here:
class Meow implements MeowBehaviour {
public function __construct() {}
public function meow()
{
echo "meow <br />";
}
}
Now meow method will be called only once.
It's important that __construct() precedes meow(), otherwise E_STRICT error will be raised. You can read more about it here.
I'm trying to set the "setFlyBhavior(FlyBehavior $newFlyBehavior)" dynamically. Can anyone explain why it will not work in the code below? I appreciate your help.
<?php
abstract class Duck {
public $flyBehavior;
public function performFly() {
return $this->flyBehavior->fly();
}
public function setFlyBhavior(FlyBehavior $newFlyBehavior) {
$this->flyBehavior = $newFlyBehavior;
}
}
interface FlyBehavior {
public function fly();
}
class GotWings implements FlyBehavior {
public function fly(){
return "<br />I'm flying with wings!!<br />";
}
}
class NotWings implements FlyBehavior {
public function fly(){
return "<br />I can't fly I have no wings!!<br />";
}
}
class FlyingDuck extends Duck {
public function __construct(){
$this->flyBehavior = new GotWings();
}
}
$ducky = new FlyingDuck();
// Code works when the setFlyBehavior function is commented out.
$ducky->setFlyBehavior(new NoWings);
echo "<br />I'm a Duck: " . $ducky->performFly();
?>
Note: The code works when not calling the "ducky->setFlyBehavior function. I also tried defining the setFlyBehavior function in the Duck class without using type casting, which also failed e.g.
public function setFlyBhavior($newFlyBehavior) {
$this->flyBehavior = $newFlyBehavior;
}
You are calling the wrong function and class names.
Replace the line:
$ducky->setFlyBehavior(new NoWings);
With:
$ducky->setFlyBhavior(new NotWings);
I have the following class and I want to implement chaining methods. I am kinda teaching my ownself so I thought it would be neat to test chaining. However that didnt work. What would I need to do that
echo $animal->name.' says'.$animal->speak()->likes()."<br />";
here is my complete code
<?php
class Animal{
var $name;
function __construct(){
$this->name = $name;
}
}
class Dog extends Animal{
public function speak(){
return "Woof Woof";
}
public function likes(){
return "steaks";
}
}
class Cat extends Animal{
public function speak(){
return "Meow Meow";
}
public function likes(){
return "tuna";
}
}
$animals = array(new Dog('skippy'), new Cat('snowball'));
foreach($animals as $animal){
echo $animal->name.' says'.$animal->speak()->likes()."<br />";
}
?>
<?php
class Animal {
function speak() {
echo "Random Noise!\n";
return $this;
}
}
class Dog extends Animal {
function bark() {
echo "bark!\n";
return $this;
}
}
$a = new Dog();
$a->speak()->bark();
You need to return $this in order to chain your methods.
If you want to chain method, you need to return $this in the method for chaining.
try to write instead of
echo $animal->name.' says'.$animal->speak()->likes()."<br />";
that :
printf('%s says %s %s',#animal->name,$animal->speak()->likes());
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.