0

I have the following PHP code to describe a color. In short, I used PHP 4 way back in the day and am trying to get my head around 5.5 now so this is the first time I'm really using objects in PHP.

Anyway I have a logic error, that I think has to do with the default value set in the Color class. Could someone please explain why my constructors aren't working, or what's going on?

class Color {
    private $red =      1;
    private $green =    1;
    private $blue =     1;
    private $alpha =    1;

    public function __toString() { return "rgb(" . $this->red . ", "
        . $this->green . ", " . $this->blue . ", " . $this->alpha . ")"; }
}

class RGBColor extends Color {
    public function __construct($red, $green, $blue) {
        $this->red = $red;      $this->green = $green;
        $this->blue = $blue;    $this->alpha = 1;
    }
}

class RGBAColor extends Color {
    public function __construct($red, $green, $blue, $alpha) {
        $this->red = $red;      $this->green = $green;
        $this->blue = $blue;    $this->alpha = $alpha;
    }

    public function __toString() { return "rgba(" . $this->red 
        . ", " . $this->green . ", " . $this->blue . ", " . $this->alpha . ")"; }
}

$c = new Color();
echo "Color: " . $c . "<br>";

$c1 = new RGBColor(0.6, 0.4, 1.0);
echo "RGB Color: " . $c1 . "<br>";

$c2 = new RGBAColor(0.6, 0.4, 1.0, 0.5);
echo "RGBA Color: " . $c2 . "<br>";

I get the following output...

Color: rgb(1, 1, 1, 1)
RGB Color: rgb(1, 1, 1, 1)
RGBA Color: rgba(0.6, 0.4, 1, 0.5)

When I should be getting...

Color: rgb(1, 1, 1, 1)
RGB Color: rgb(0.6, 0.4, 1.0)
RGBA Color: rgba(0.6, 0.4, 1, 0.5)

Thanks! -Cody

1
  • Putting the $red &c. member variables in the base class looks a bit odd. What if you later want to support HSL and HSLA color values? Will you convert from/to RGB(A) when constructing/outputting the objects? Fair enough if you only want to use RGBA internally, but make certain that you're making the decision rather than falling into it. Commented Oct 26, 2013 at 7:01

3 Answers 3

2

It's not a matter of initialization order but of visibility. A private variable is accessible only by methods defined in the same class. Color::__toString() accesses the variables defined on Color, but the constructors in the child classes access different variables on the child classes. As a simple example:

<?php
class A {
    private $p = __CLASS__;
}

class B extends A {
    function __construct() {
        $this->p = __CLASS__;
    }
}

$b = new B;
var_dump($b);

outputs:

class B#1 (2) {
  private $p =>
  string(1) "A"
  public $p =>
  string(1) "B"
}

If you want a member variable to be accessible in descendants, make it protected rather than private.

Sign up to request clarification or add additional context in comments.

1 Comment

Oh crap I knew that. Thanks!
2

Use protected not private for variables you want use on children classes. Another approach is to write setters and getters.

Comments

0

I am guessing maybe int and float problem , seems PHP round it to integer.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.