Practicing Loose'ly Coupling code in php - php

I'm new to PHP or any progamming language and im practic'n how to code a loose coupling
<?php
interface IPolygon{
public function getArea();
}
class Polygon{
private $ipolygon;
public function __construct(IPolygon $ipolygon){
$this->ipolygon = $ipolygon;
}
public function calArea(){
return this->ipolygon->getArea();
}
}
class Circle implements IPolygon{
private $radius;
private $pi = 3.14;
public function __construct($radius){
$this->radius = $radius;
}
public function getArea(){
return $pi*$radius*$radius;
}
}
class Triangle implements IPolygon{
private $base;
private $height;
public function __construct($base , $height){
$this->base = $base;
$this->height = $height;
}
public function getArea(){
return $base*$height/2;
}
}
$c = new Circle(14);
$p = new Polygon($c);
echo "<hr />";
$p->calArea();
?>
Error
Notice: Undefined variable: ipolygon in C:\xampp\htdocs\OOP\Polygon.php on line 16
Notice: Undefined variable: pi in C:\xampp\htdocs\OOP\Polygon.php on line 30
Notice: Undefined variable: radius in C:\xampp\htdocs\OOP\Polygon.php on line 30
Notice: Undefined variable: radius in C:\xampp\htdocs\OOP\Polygon.php on line 30
can someone explain me how is it done?

As a general rule all class properties are referenced using $this->
That means:
<?php
interface IPolygon{
public function getArea();
}
class Polygon{
private $ipolygon;
public function __construct(IPolygon $ipolygon){
$this->ipolygon = $ipolygon;
}
public function calArea(){
return $this->ipolygon->getArea();
}
}
class Circle implements IPolygon{
private $radius;
private $pi = 3.14;
public function __construct($radius){
$this->radius = $radius;
}
public function getArea(){
return $this->pi*$this->radius*$this->radius;
}
}
class Triangle implements IPolygon{
private $base;
private $height;
public function __construct($base , $height){
$this->base = $base;
$this->height = $height;
}
public function getArea(){
return $this->base*$this->height/2;
}
}
$c = new Circle(14);
$p = new Polygon($c);
echo "<hr />";
$p->calArea();
It works: http://sandbox.onlinephpfunctions.com/code/e7f79bb186ffac952ebc4c2b5a8098e1efaeb874

Related

Getting Uncaught Error: Call to undefined method Vehicles::setPassengerSeats()

I am getting this error:
uncaught error call to undefine method
Vehicles::setPassengerSeats() in
C:\xampp\htdocs\practice\vehicle.php:91.
I also have added screenshot of the error. Kindly check and tell me how can i solve it ? I think i have problem with my sub class but i don't know where?
Here is my source code:
<?php
class Vehicles{
private $noOfVehicles;
private $color;
private $fuel;
private $speed;
public function getNoOfVehicles(){
return $this->noOfMobiles;
}
public function setNoOfVehicles($Vehicles){
$this->noOfMobiles = $Vehicles;
echo "No of Vehicles are: ".$this->noOfVehicles."</br>";
}
public function getColor(){
return $this->color;
}
public function setColor($look){
$this->color = $look;
echo "</br>The Color of Vehicle is: ".$this->color."</br>";
}
public function getFuel(){
return $this->fuel;
}
public function setFuel($petrol){
$this->fuel = $petrol;
echo "</br>The fuel is: ".$this->color."</br>";
}
public function getSpeed(){
return $this->speed;
}
public function setSpeed($vehicleSpeed){
$this->speed = $vehicleSpeed;
echo "</br>The speed of vehicle is: ".$this->speed."</br>";
}
}
class PassengerVehicles extends Vehicles{
private $passengerSeats;
public function getPassengerSeats(){
return $this->passengerSeats;
}
public function setPassengerSeats($seats){
return $this->passengerSeats = $seats;
echo "</br>Passenger Seats are: ".$this->passengerSeats."</br>";
}
}
class TransportationVehicles extends Vehicles{
private $noOfDoors;
private $loadCapacity;
public function getNoOfDoors(){
return $this->noOfDoors;
}
public function setNoOfDoors($doors){
return $this->noOfDoors = $doors;
echo "</br>The No of Doors are: ".$this->noOfDoors."</br>";
}
public function getLoadCapacity(){
return $this->loadCapacity;
}
public function setLoadCapacity($capacity){
return $this->loadCapacity = $capacity;
echo "The Load Capacity is: ".$this->loadCapacity."</br>";
}
}
$VehiclesObj = new Vehicles;
$VehiclesObj->setNoOfVehicles("15");
$VehiclesObj->setColor("Black");
$VehiclesObj->setFuel("5 Litre");
$VehiclesObj->setSpeed("120 km/h");
$VehiclesObj->setPassengerSeats("4");
$VehiclesObj->setNoOfDoors("4");
$VehiclesObj->setLoadCapacity("500 KG");
?>
You call method setPassengerSeats which is in another class not in Vehicles You should create instance first, then to call this method:
$passangerVehicle = new PassengerVehicles;
$passangerVehicle->setPassengerSeats("4");
You can't call child methods from a parent. You need to create an instance of the child to be able to call parent methods
class Vehicles{
private $noOfVehicles;
private $color;
private $fuel;
private $speed;
public function getNoOfVehicles(){
return $this->noOfMobiles;
}
public function setNoOfVehicles($Vehicles){
$this->noOfMobiles = $Vehicles;
echo "No of Vehicles are: ".$this->noOfVehicles."</br>";
}
public function getColor(){
return $this->color;
}
public function setColor($look){
$this->color = $look;
echo "</br>The Color of Vehicle is: ".$this->color."</br>";
}
public function getFuel(){
return $this->fuel;
}
public function setFuel($petrol){
$this->fuel = $petrol;
echo "</br>The fuel is: ".$this->color."</br>";
}
public function getSpeed(){
return $this->speed;
}
public function setSpeed($vehicleSpeed){
$this->speed = $vehicleSpeed;
echo "</br>The speed of vehicle is: ".$this->speed."</br>";
}
}
class PassengerVehicles extends Vehicles{
private $passengerSeats;
public function getPassengerSeats(){
return $this->passengerSeats;
}
public function setPassengerSeats($seats){
return $this->passengerSeats = $seats;
echo "</br>Passenger Seats are: ".$this->passengerSeats."</br>";
}
}
class TransportationVehicles extends Vehicles{
private $noOfDoors;
private $loadCapacity;
public function getNoOfDoors(){
return $this->noOfDoors;
}
public function setNoOfDoors($doors){
$this->noOfDoors = $doors;
echo "</br>The No of Doors are: {$this->noOfDoors}</br>";
return $this->noOfDoors;
}
public function getLoadCapacity(){
return $this->loadCapacity;
}
public function setLoadCapacity($capacity){
return $this->loadCapacity = $capacity;
echo "The Load Capacity is: ".$this->loadCapacity."</br>";
}
}
$truck = new TransportationVehicles();
$truck->setNoOfVehicles("15");
$truck->setColor("Black");
$truck->setFuel("5 Litre");
$truck->setSpeed("120 km/h");
$truck->setNoOfDoors("4");
$truck->setLoadCapacity("500 KG");
$taxi = (new PassengerVehicles())->setPassengerSeats('4');
In this case, you will have two instances of the Vehicles class + own child.
The first instance is related to the Vehicle itself + transport properties like $noOfDoorsand $loadCapacity - a truck for example.
The second is an instance of a passenger based vehicle - taxi for example.
And you tried to get passengers option of a taxi from a bus.

Extended classes and undefined Variables - PHP [duplicate]

This question already has answers here:
PHP - Private class variables giving error: undefined variable
(4 answers)
Closed 4 years ago.
Square and Rectangle are classes that extends abstract class ShapesClass, defining their own Area methods.
abstract class ShapesClass
{
// Force Extending class to define this method
abstract public function Area();
}
class Square extends ShapesClass
{
private $side = 0;
function __construct($n)
{
$side = $n;
}
function Area()
{
echo $side * $side;
}
}
class Rectangle extends ShapesClass
{
var $length = 0;
var $width = 0;
function __construct($a,$b)
{
$length = $a;
$width = $b;
}
function Area()
{
echo $length * $width;
}
}
$listShapes = array();
$listShapes[0] = new Square(3);
$listShapes[1] = new Rectangle(3,4);
$listShapes[0]->Area();
$listShapes[1]->Area();
I get undefined variable errors on side, length and width.
Doesn't these three variables have default values and are also set by the constructor.
You actually want to refer to them as $this->foo
function __construct($a,$b)
{
$this->length = $a;
$this->width = $b;
}
Basically $foo acts like a local, variable, scoped to current method. $this->foo acts like a instance variable, which is available anywhere in the class.
In your code whenever we create variables for any class we can call them inside methods with the class reference only i.e. $this
Also, in php we can define the variables with var there are public, protected and private keywords to define any variable.
So, you can update your code with the below code
abstract class ShapesClass
{
// Force Extending class to define this method
abstract public function Area();
}
class Square extends ShapesClass
{
private $side = 0;
function __construct($n)
{
$this->side = $n;
}
function Area()
{
echo $this->side * $this->side;
}
}
class Rectangle extends ShapesClass {
private $length = 0;
private $width = 0;
function __construct($a,$b)
{
$this->length = $a;
$this->width = $b;
}
function Area()
{
echo $this->length * $this->width;
}
}
$listShapes = array();
$listShapes[0] = new Square(3);
$listShapes[1] = new Rectangle(3,4);
$listShapes[0]->Area();
$listShapes[1]->Area();

Calling my objects and its functions

I am new to php and trying using Factory Method.
I want to instantiate my class Shapes using 'build' function,such that when the class 'Circle' is instantiated its area and circumference is calculated and if the class 'Rectangle' is called ,its area and circumference is calculated and returned.
This is what I have so far and what i want to achieve.This doesnt work and i am sure there is a better way of doing it!
$allmyshapes = Shapes::build($initData);
foreach($allmyshapes as $value) {
if ($value =='Circle'){
$x = new Circle();
echo $x::area();
echo $x::circumference();
}
if ($value =='Rectangle'){
$y = new Rectangle();
echo $y::area();
echo $y::circumference();
}
}
My Class:
class Shapes {
public static function build($initData){
}
foreach($newlist as $value){
if($value[0]=='Circle'){
$shape1 =new Circle($value[1],$value[2]);
}
if($value[0]== 'Rectangle'){
$shape2 =new Rectangle($value[1],$value[2]);
}
}
return array($shape1,$shape2);
}
}
class Circle extends Shapes {
public $radius;
public $centre_point;
public function __construct($radius, $centre_point) {
$this->radius = $radius;
$this->centre_point = $centre_point;
}
public function area(){
return (pi() *$this->radius * $this->radius);
}
public function circumference(){
return 2 * pi() *$this->radius;
}
}
class Rectangle extends Shapes {
public $x;
public $y;
public function __construct($x, $y) {
$this->x= $x;
$this->y = $y;
}
public function area() {
return $this->x * $this->y;
}
public function circumference() {
return 2 * ($this->x+ $this->y);
}
}
There's nothing wrong with your classes, it was how you were using them to output information:
class Shapes {
public static function build($initData){
//$initdata is a heredoc
$newlist = explode("\n", $initData);
foreach($newlist as $key => $initData){
$newlist[$key] = explode("\t", $initData);
}
foreach($newlist as $value){
if($value[0] == 'Circle'){
$shape1 = new Circle($value[1], $value[2]);
}
if($value[0] == 'Rectangle'){
$shape2 = new Rectangle($value[1], $value[2]);
}
}
return array($shape1, $shape2);
}
}
class Circle extends Shapes {
public $radius;
public $centre_point;
public function __construct($radius, $centre_point){
$this->radius = $radius;
$this->centre_point = $centre_point;
}
public function area(){
return (pi() * $this->radius * $this->radius);
}
public function circumference(){
return 2 * pi() * $this->radius;
}
public function draw(){
return ( $this->radius.":".$this->centre_point);
}
}
class Rectangle extends Shapes {
public $x;
public $y;
public function __construct($x, $y){
$this->x = $x;
$this->y = $y;
}
public function area(){
return $this->x * $this->y;
}
public function circumference(){
return 2 * ($this->x + $this->y);
}
}
$initData = <<<ENDINIT
Circle 5 2
Rectangle 5 10
Ellipse 10 10 4 5
ENDINIT;
$allmyshapes = Shapes::build($initData);
foreach($allmyshapes as $value){
if(get_class($value) === 'Circle'){
echo nl2br("**Circle**\nArea: ".$value->area()."\nCircumference: ".$value->circumference()."\n");
}
if(get_class($value) === 'Rectangle'){
echo nl2br("**Rectangle**\nArea: ".$value->area()."\nCircumference: ".$value->circumference()."\n");
}
}
I added 2 functions to your provided code, get_class() & nl2br(). the nl2br can be removed if you are using this in CLI format, but its main function was for output readability when using a web browser to view the output.
get_class() will solve your issue of trying to figure out what constructor was used in the creation of the object.

PHP trait : What is the logical error in this Code

I have invested approximately 4 hours on this code but not getting the Required Result while the Code Snippet is running normally. The Code is as follows:
trait CircleShape{
public function input($radius){
$this->$radius = $radius;
}
}
trait AngleShape{
public function input($height, $width){
$this->$height = $height;
$this->$width = $height;
}
}
trait GeneralMethod{
public function get($property){
return $this->$property;
}
}
class Shape{
private $height, $width, $radius;
const PI = 3.1415;
use GeneralMethod, AngleShape, CircleShape{
AngleShape::input insteadof CircleShape;
CircleShape::input as inputCircle;
}
}
class Circle extends Shape{
public function area(){
return parent::PI * $this->get('radius') * $this->get('radius');
}
}
class Rectangle extends Shape{
use GeneralMethod, AngleShape, CircleShape{
AngleShape::input insteadof CircleShape;
CircleShape::input as inputCircle;
}
public function area(){
return $this->get('height') * $this->get('width');
}
}
$rect = new Rectangle;
$rect->input(12, 2);
Echo "Area: " . $rect->area() . "\n";
$cir = new Circle;
$cir->inputCircle(10);
Echo "Circle Area : " . $cir->area() . "\n";
What is the Logic Error in this Code?
Why I am getting following Output:
Rectangle Area : 0
Circle Area : 0
$this->$radius = $radius;
should be
$this->radius = $radius;
And same with $height and $width.
here you are trying by The pseudo-variable $this and arrow operator (->) for calling one variable then you should drop off $ in-front of variable

I want to initialize attribute without creating object

when I run the below code I got error in line echo $attribute;
The error code: "Catchable fatal error: Object of class SomeShape could not be converted to string in ":
What wrong in this code?
Thanks.
<?php
class Shape
{
static public $width;
static public $height;
}
class SomeShape extends Shape
{
public function __construct()
{
$test=self::$width * self::$height;
echo $test;
return $test;
}
}
class SomeShape1 extends Shape
{
public function __construct()
{
return self::$height * self::$width * .5;
}
}
Shape::$width=60;
Shape::$height=5;
echo Shape::$height;
$attribute = new SomeShape;
echo $attribute;
$attribute1 = new SomeShape1;
echo $attribute1;
?>
What you are trying to do is echo an object, its like you are echoing an array(worst than echoing an array since echoing an object throuws error), while what you should be doing is accessing it's attribute or method etc. However if u wanna c what is in your object, you gotto use var_dump instead of echo .
In short, echo $attribute is wrong. Use var_dump($attribute)
Don't do a return in a constructor.
If you want to echo a value, trys to add a __toString() function (manual)
You cannot echo an object without implementing the __toString method.
Alternatively you could var_dump the object:
var_dump($attribute);
But what I think you are actually trying to do is more like this:
class Shape {
public $width;
public $height;
public function __construct($width, $height) {
$this->width = $width;
$this->height = $height;
}
}
class SomeShape extends Shape {
public function getArea() {
return $this->width * $this->height;
}
}
class SomeShape1 extends Shape {
public function getHalfArea() {
return $this->width * $this->height * .5;
}
}
$shape = new SomeShape(10, 20);
echo $shape->getArea();
$shape = new SomeShape1(10, 20);
echo $shape->getHalfArea();
the solution that I found is:
I don't want to add more attribute to class shape but this solve my problem as I wish.may be there is more similar solution I will love to see. but this is my idea I define in class shape "public $attribute;" Inside the class SomeShape I wrote on "public function __construct()" "$this->attribute=self::$width * self::$height;" In the main scope I wrote "echo $object->attribute."";"
<?php
class Shape
{
static public $width;
static public $height;
public $attribute;
}
class SomeShape extends Shape
{
public function __construct()
{
$this->attribute=self::$width * self::$height;
}
}
class SomeShape1 extends Shape
{
public function __construct()
{
$this->attribute=self::$width * self::$height * .5;
}
}
Shape::$width=60;
Shape::$height=5;
$object = new SomeShape;
echo $object->attribute."<br />";
$object1 = new SomeShape1;
echo $object1->attribute;
?>

Categories