NuSphere Forums Forum Index
NuSphere Forums
Reply to topic
Code Completion on type hinting with interfaces


Joined: 28 Oct 2005
Posts: 6
Reply with quote
First of all allow me to express how much I enjoy using PHPEd-I can't imagine how I survived using Zend Studio before. To help speed along the process of trouble shooting, I am using PHPEd v4.0 build 4039. I'm attempting to use interfaces and type hint objects as interfaces within a function parameter list. However, PHPEd's code completion engine apparently doesn't recognize methods declared within an interface or recognize methods inherited by an abstract class that does not explicitly declare/define the methods in the interface. A following snippet of code should help since I don't feel I am expressing this in a clear and concise way:
Code:

interface obj
{
    public abstract function hi();
}

abstract class myObj implements obj
{
    abstract public function hi();
}

abstract class myObj2 implements obj
{
    abstract public function bar();
}

function test1(myObj $obj) //note type is myObj
{
    $obj->hi(); //for this one code completion recognizes the hi() method in myObj
}

function test2(obj $obj) //note type is obj (which is an interface)
{
    $obj->hi(); //this one code completion does not show anything for the interface
}

function test3(myObj2 $obj) //note type is myObj2
{
    $obj->hi(); //this one code completion only shows bar(); no hi() which is declared in interface myObj2 is implementing
}


I would really appreciate it if this issue can be addressed.

Thanks,
David
View user's profileFind all posts by davidloSend private message
Site Admin

Joined: 13 Jul 2003
Posts: 8334
Reply with quote
Hello David,
Thanks for your words regarding PHPED.

Sure, this issue will be addressed and I'm adding it to our plans with rather high priority.
Thanks for the code sample too.

It may make sense for you to try intermediate builds so you'd make sure that we're on the same page regarding Code completion improvements.

-dmitri.
View user's profileFind all posts by dmitriSend private messageVisit poster's website
Site Admin

Joined: 13 Jul 2003
Posts: 8334
Reply with quote
Code:
function test2(obj $obj) //note type is obj (which is an interface)
{
    $obj->hi(); //this one code completion does not show anything for the interface
}

works in 4042

Code:
function test3(myObj2 $obj) //note type is myObj2
{
    $obj->hi(); //this one code completion only shows bar(); no hi() which is declared in interface myObj2 is implementing
}

hmm... myObj2 has no hi() method...
yes, I do understand that it comes with myObj2 interface, but isn't it too quirky Question
View user's profileFind all posts by dmitriSend private messageVisit poster's website


Joined: 28 Oct 2005
Posts: 6
Reply with quote
Suppose that I have 2 concrete classes that extend the class myObj2. I can't instantiate myObj2 objects directly (it's an abstract class) so I need to instantiate the other 2 concrete classes derived from myObj2. If I need a method that operates on both 2 concrete classes in a similar fashion, then the code will look something like this:
Code:
interface obj
{
    public abstract function hi();
}

abstract class myObj2 implements obj
{
    abstract public function bar();
}

class myObj21 extends myObj2
{
    public function bar()
    {
        echo "bar";
    }

    public function hi()
    {
        echo "I'm an myObj21 object";
    }
}

class myObj22 extends myObj2
{
    public function bar()
    {
        echo "bar";
    }

    public function hi()
    {
        echo "I'm an myObj22 object";
    }
}

function test3(myObj2 $obj) //note type is myObj2
{
    $obj->hi(); //this one code completion only shows bar(); no hi() which is declared in interface myObj2 is implementing
}

$a=new myObj21();
$b=new myObj22();
test3($a); //this should print "I'm an myObj21 object"
test3($b); //this should print "I'm an myObj22 object"


Hopefully you see how I'm trying to use an abstract class (that doesn't explicitly declare a function) as a type hint Smile
David
View user's profileFind all posts by davidloSend private message
Site Admin

Joined: 13 Jul 2003
Posts: 8334
Reply with quote
what you're trying to explain was clear from the first code sample.

I'm talking about ambiguity of the language. Either you need interfaces or abstract classes. Effectively they are the SAME. Using them together makes very little sense to me. In particular, why don't you pass the interface instead of abstract class? Alternatively, why don't you forget of the interface and add all abstract methods into your abstract class? Both variants would work fine in PHPED.
View user's profileFind all posts by dmitriSend private messageVisit poster's website


Joined: 28 Oct 2005
Posts: 6
Reply with quote
The reason why I'm using interfaces and abstract classes is because I may need to derive an abstract class from multiple interfaces and extend another class as an abstract class that is the basis for more extension. I can't have a class extend two classes but I can have it implement more than one interface. On the same principle I may need to derive a class from an abstract class (with all it's class data members) and also from another interface that is unrelated. So while I do agree with you that functionally interfaces and abstract classes are more or less the same, language wise I can't extend 3 abstract classes like I can implement 3 interfaces. Likewise if I implement everything as interfaces, then I cannot have a class data member propagate down the inheritance tree-I'll need to redeclare the data member every time which doesn't work too well with static variables and I cannot define method bodies like I can in abstract classes. An example of this would be:
Code:
<?php
interface obj
{
    abstract public function hi();
   
    public $hi; //does not work-generates Parse error
    public function doSomething() //does not work-generates Parse error
    {
        //do something
    }
}

interface cacheable
{
    abstract public function cache();
}

abstract class deadObj extends statVar, formVar //does not work-generates Parse error
{
    //class body
}

class normalObj implements obj
{
    public function hi()
    {
        return "I'm a normal object without anything extra than the obj interface";
    }
}

abstract class cacheableObj implements obj, cacheable
{
    protected static $cacheableobjCount=0; //this inherited class member would not function the way I want it to if I implemented it individually-I want to count all cacheableObj created in entire script execution
   
    public function _construct()
    {
        cacheableObj::$cacheableobjCount++;
    }
   
    abstract public function toString();
}

class underivedStatVar implements obj, cacheable //if no intermediary abstract class
{
    private $str;
   
    public function hi()
    {
        return "I am a stat object";
    }
   
    public function cache()
    {
        //do something
    }
   
    public function toString()
    {
        return "statVar: " . $this->str;
    }   
}

class underivedFormVar implements obj, cacheable //if no intermediary abstract class
{
    private $get;
   
    public function hi()
    {
        return "I am a form object";
    }
   
    public function cache()
    {
        //do something
    }
   
    public function toString()
    {
        return "formVar: " . $this->get;
    }
}

class statVar extends cacheableObj
{
    private $str;
   
    public function hi()
    {
        return "I am a stat object";
    }
   
    public function cache()
    {
        //do something
    }
   
    public function toString()
    {
        return "statVar: " . $this->str;
    }
}

class formVar extends cacheableObj
{
    private $get;
   
    public function hi()
    {
        return "I am a form object";
    }
   
    public function cache()
    {
        //do something
    }
   
    public function toString()
    {
        return "formVar: " . $this->get;
    }
}

//now say I want a function that calls toString() for formVar and statVar
function bar(cacheableObj $obj)
{
    echo $obj->toString(); //this works the way it should
}

//now say I want a function that calls toString() for both underivedStatVar and underivedFormVar without cacheableObj
function bar2(obj $obj) //obj doesn't support toString(), so technically can't use
{
    //it works (dynamic typing), but it seems like bad programming practice since we did all the type hinting
    //also what would stop me from passing a normalObj object? it satisfies the obj requirement
    echo $obj->toString();
}
?>

It's a rather long example but I hope it shows where I'm coming from Smile
David
View user's profileFind all posts by davidloSend private message
Code Completion on type hinting with interfaces
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
All times are GMT - 5 Hours  
Page 1 of 1  

  
  
 Reply to topic