The SitePoint Forums have moved.

You can now find them here.
This forum is now closed to new posts, but you can browse existing content.
You can find out more information about the move and how to open a new account (if necessary) here.
If you get stuck you can get support by emailing forums@sitepoint.com

If this is your first visit, be sure to
check out the FAQ by clicking the
link above. You may have to register
before you can post: click the register link above to proceed. To start viewing messages,
select the forum that you want to visit from the selection below.

Advantages of Interfaces and Public Methods and Members

I'm pretty new to the OO side of things and have a few questions to ask.

1) What are the advantages of stating your members as public?
i.e. Which is better?

Code:

class foo {
var $bar;
.....
}

or

Code:

class foo {
public $bar;
.....
}

At the moment I use var as it's shorter to write (I know i'm lazy). Are there any real reasons why public is better?

2) Similar to the previous question, what are the advantages of stating your methods as public?
At the moment I just leave any public methods without any declaration to their visibility. Is there anything wrong with this? Are there any advantages to stating their visibility?

3) What are the advantages of using interfaces?
As I said I'm fairly new to OOP and have looked a bit at interfaces. I don't see the point in them! Maybe I'm just not 'getting' interfaces but they seem very reduntant. If anyone has any good tutorials on Interfaces or reasons to use them I would appreciate it.

There's really no difference other than version compatibility. var is the PHP4 way, and public is the PHP5 way. So, if you're writing PHP5 and want PHP4 compatibility, use var. Note: In PHP5, if you don't explicitly state the visibility of a member, it's implicity public. All object members in PHP4 are public so this is irrelevant for PHP4.

Same thing.

Interfaces are like rules for developers. Functionally, I don't think there's any benefit. Since you can typehint in PHP5, and interfaces are treated like classes, you can write methods to expect a parameter object with certain interface without forcing the developer to extend one of your classes. Some of the SPL interfaces are good examples of this, such as Iterator.

At the moment I use var as it's shorter to write (I know i'm lazy). Are there any real reasons why public is better?

It's about E_STRICT compliance - which you'll hopefully be trying to attain. The keywords don't really differ in function, it's just that the other one is deprecated.

At the moment I just leave any public methods without any declaration to their visibility. Is there anything wrong with this? Are there any advantages to stating their visibility?

This one is a matter of preference. Others like to leave it out, I like to be explicit. Neither side is more wrong than the other.

What are the advantages of using interfaces?

This one is quite a different beast, compared to the previous questions. An interface is a signature; in conjunction with type hinting, you can use them to make sure that an object really provides the methods you are going to use. The advantage of interfaces over pure abstract classes is that you can have two classes that implement one without having common ancestors. You'll come to appreciate this as you venture further on the path of OOP.

PHP5 also has the SPL library, which provides you with means to override certain functionalities such as iterating over an object, accessing it as an array etc. by implementing a predefined interface. It's quite powerful, and I recommend you take use of it when appropriate.

(1) & (2) None that I can think of. I'll be annoyed with the extra clutter whenever I finally move on from php4. It feels like a step back to Victorian times when people were mortified if a lady showed her ankles but nowadays we wonder what all the fuss was about. You can have a well-defined interface without them (nobody is doing $foo->bar, right...?) and I can't think of a unit test which would fail because something is public which should be private (private parts are not normally manipulated in unit tests).

Thanks for the quick replies. I think I will start using global instead of var for my class members; didn't realise that var was deprecated.

As for methods, I'm still undecided. It seems as though it just creates a bit more clutter and is kind of unneccessary. Would like to hear other people's opinions on this though.

Ezku, beetle: I can only really see the benefits of interfaces as you stated when using things such as iterators. It's only me using at the code so most of the time I feel that interfaces are reduntant. Has anyone got any good tutorials on interfaces so that I can understand them a little bit better?

For DomainObject, we don't really care that $config is a Config object, or a subclass of it. But, with how we've setup our script, all we care about is that $config has the isDev() method. Here's another approach using an interface instead

Looks almost the same - but this time DomainObject::logError expects config to use the interface iConfig. This means ANY object can be passed in as long as it implements the interface, so we're no longer forcing the user (code) to extend the Config class. Try to pass in anything else, and PHP will trigger a fatal error.

You can have a well-defined interface without them (nobody is doing $foo->bar, right...?) and I can't think of a unit test which would fail because something is public which should be private (private parts are not normally manipulated in unit tests).

Protected members makes it easier to refactor your code, because you can be sure that they are only used in a limited scope. Thus you will only have to check that code if you chahnge the member. I use protected whenever I can get away with it. I hardly ever use private though.
For the sake of symmetry, I have begun writing out the redundant public, but I'm not sure it's really appropriate.

Originally Posted by stardustwd

Thanks for the quick replies. I think I will start using global instead of var for my class members; didn't realise that var was deprecated.

Uhm .. public ... not global

Originally Posted by stardustwd

I can only really see the benefits of interfaces as you stated when using things such as iterators. It's only me using at the code so most of the time I feel that interfaces are reduntant. Has anyone got any good tutorials on interfaces so that I can understand them a little bit better?

Interfaces are hard to understand - they are very powerful though. Design is equally important if you're a one man army as if you're working in a team.

It's a bit academic, but I recently read this article, which among other things gives a good explanation of the role of interfaces vs. inheritance.

Thanks beetle, i think i might be finally getting my head around this.

I've been thinking and I think it might be best to get a book on this. Can anyone recommend any decent OO books for PHP; I know the basics but I get a little lost on things like interfaces, abstract classes and the more advanced bits of it.

I'm in charge of creating a "framework" of sorts that let other application developers plug into and use parts of our system. Being able to define protected and private variables allows me to have tighter code because I know some lazy app developer isn't going to try and use my members directly but actually have to use the public API call I provide them

Looks almost the same - but this time DomainObject::logError expects config to use the interface iConfig. This means ANY object can be passed in as long as it implements the interface, so we're no longer forcing the user (code) to extend the Config class. Try to pass in anything else, and PHP will trigger a fatal error.

Which, of course, doesn't make much sense in a dynamic language like PHP anyway.

Let me rewrite the above paragraph for the situation where you don't use the interface:

This means ANY object can be passed in, so we're no longer forcing the user (code) to extend the Config class. Try to call isDev() method, and PHP will trigger a fatal error.

That's called duck typing, and is much more appropriate for a dynamic language. Interfaces have their value, as documentation.

Which, of course, doesn't make much sense in a dynamic language like PHP anyway.

Why not?

I don't ask that to be frictional, I really mean it. I'd rather make sure the user (coder) passed in an object with the correct interface than likely have an error anywhere else past that. Or, god forbid, they incidentally pass in an object that shares a method name but does something completely different.

If an object was coded to an interface, it's much more likely the developer designed it as you intended. Documentation, indeed, but that's not all their good for IMO.

Interfaces have other uses, and more to the point (the point that you so elegantly forget) have their purposes, and value, regardless of the language.

> If an object was coded to an interface, it's much more likely the developer designed
> it as you intended.

That is how I see it; If I've spent a number of hours over a period of time designing an Interface(s) then that is how I would want the script to be implemented, not only by myself, but other developers that I employ and use my code base.

Beris., if you have such as issue with PHP5, then go back to PHP4 where you won't have to face the use of Interfaces

Beris., if you have such as issue with PHP5, then go back to PHP4 where you won't have to face the use of Interfaces

OK, I've noticed the smiley, but I don't know how you dediced that I have an issue with PHP5. I certainly have issues with some bad practices in some "modern" languages, which were for some reason taken by PHP5.

1. Static-typing (and interfaces as its spawn): In static languages like Java, interfaces are a way to make variables "dynamic", i.e. to be able to put completely unrelated objects (in the sense of inheritance) to a same variable; in dynamic languages that need doesn't exist. I mean, interfaces always exist, simply as a collection of an object's public members, and if an object doesn't comply with the interface you need it will show up as soon as you try using it.

2. Confusion of classes and objects: as I mentioned in another thread, the whole private/protected/public (and package in Java) mess came up because of confusion between classes and objects. Visibility of a property should not affect its extendability, and especially the idea that a private (or any for that matter) property cannot be inherited is an utter nonsense. The OO principles call for a) all properties must be inherited, as they define a type, and b) properties should be either private, which means that only their own instance can access them, and public, which means that any other instance of any class can access them (of course, private should be the default and public should be explicitely announced).

I don't ask that to be frictional, I really mean it. I'd rather make sure the user (coder) passed in an object with the correct interface than likely have an error anywhere else past that.

Let me return the favor by asking: why? What advantages do you have with that?

In programming, more freedom is always better than more restrictions. Of course, we have all met bad programmers, but in the long run it much more pays off to educate (or fire if all else fails) bad developers than restrict everyone.

I suppose the reasoning is that it prevents action at a distance, since the program would fail early. I agree with you about dynamic languages vs. interfaces. I think a sort of weak interfaces would be much more useful.

Of course it is. But, that statement for one, doesn't change anything I said, and two, doesn't mean restrictions are never desirable.

For example, tak using the SPL Iterator interface. You can't go in and change the methods names of a class that implements it from Object::current() to say... Object::currentElement() and still use Object in a foreach() loop.

For the point I'm arguing, interfaces are a guide to achieveing the desired result by the programmer. I want x-object to work in a foreach() loop, so I implement Iterator. If ProgrammerB wants an object to behave in a system designed by ProgrammerA, ProgrammerB will implement InterfaceX because that's how ProgrammerA set it up.

Back to your counterpoint. Yes, freedom is programming is good. But when working with something as part of a system, restrictions can be necessary. Unless you think you should have so much freedom that you could change Object::current() to Object::someThingElse() and still get the desired result.

Unless you think you should have so much freedom that you could change Object::current() to Object::someThingElse() and still get the desired result.

I have no idea where you got that notion and what does it have to do with what I'm saying.

You need to understand the difference with interfaces (as in collections of public members of an object) and Interfaces (as in formal language entity). The first is something that exists whether we want it or not; that's just a property of OOP. The latter, OTOH, are unnecesary and misleading in dynamic language like PHP.

If you use an object, of course you'll need to know its interface and of course you wouldn't want it to suddenly change.

You need to understand the difference with interfaces (as in collections of public members of an object) and Interfaces (as in formal language entity).

I do. I just see it as the latter is a way of enforcing the former. I don't think you're insinuating that they're unrelated, but I'm perhaps just emphasizing the fact that they are.

But hey, I don't have any context to discuss the dynamic nature of PHP and Interfaces with you - aside from knowing javascript, I fiddle with Ruby and have a layman's knowledge of C++. I openly admit that's the breadth of my experience (ok, I took TurboPascal in high school and BASIC in grade school :P).

Perhaps you could help me understand why interfaces (proper) are, to use your word, "misleading" in a dynamic language? Because, as the framework developer for a team of four, I find them rather useful.

In a truly dynamic language, you can add, remove and rename methods at will, which renders Interfaces completely useless. In a truly dynamic language, it doesn't matter what type an object is, the only thing that matters is, does it contain a given method?

Now, I wouldn't use the word "misleading" to describe them, but they are definitely unneccesary.

I do. I just see it as the latter is a way of enforcing the former. I don't think you're insinuating that they're unrelated, but I'm perhaps just emphasizing the fact that they are.

That they are unrelated? Watch out for those multiple negations.

Originally Posted by beetle

But hey, I don't have any context to discuss the dynamic nature of PHP and Interfaces with you - aside from knowing javascript, I fiddle with Ruby and have a layman's knowledge of C++.

To be honest, this is a background that I would expect to lead to same conclusions as mine. I haven't (yet) worked with Ruby, but my experiences with Javascript, PHP, Java, C, C++ and Python have allowed me to understand the issues.

Originally Posted by beetle

Perhaps you could help me understand why interfaces (proper) are, to use your word, "misleading" in a dynamic language? Because, as the framework developer for a team of four, I find them rather useful.

Specifically, consider Javascript: it is in many ways a "perfect" dynamic languages, without classes, interfaces and any similar ballast. The whole point behind class-based OOP is to enforce types, i.e. to make sure what types are put into which variables. Statically-typed languages -- any by statically-typed I refer to the fact that a variable must have declared a type, like in Java or C(++); dynamically-typed languages allow any value of any type to be associated with any variable, like in Javascript, Python or PHP (and AFAIK Ruby) -- need this enforcing due to limitations of the language; they are not needed for proper OOP to work, as proven by things like duck typing.

PHP5 has introduced some great dynamic OOP features such as overloading methods (__set, __get, __call...), but at the same time has introduced the static features like interfaces and type hinting. Specifically, type hinting in itself isn't of much value without interfaces (which is why the latter were introduced in, say, Java), which means that the two make sense only if they're used together (which is of course not needed).

Specifically, the issue here is not that much with the interfaces in PHP than in type hinting. It introduces a whole new set of rules into programming practice here. Someone said that if you wanted the users of your class to use it as you intended, you'll design an interface they must abide with. But what if you made a mistake, or if you simply didn't consider all the facts?

Imagine that you write a Fish interface that has several propertires, including a swimDeep() method. But later you want to expand your aquarium simulation application to support both tiny human divers and tiny submarines, that have the swimDeep() but none of the other properties of Fish.

So if you implement that interface by both submarines and divers, you'll also have to implement a bunch of methods they shouldn't have (breatheWater(), hatchEggs() etc). The alternative is to create a new interface, Swimmer, and give it just the swimDeep() method (and perhaps any others that might be appropriate, such as surface()); but now you not only have to change your old classes to implement two interfaces, but also change all type hints from Fish to Swimmer. (Of course, you could also use some kind of Decorator pattern, but that's a whole 'nother issue.)

In static languages this is pretty normal and there are tools that assist you in that kind of refactoring; but dynamic languages have a much simpler way of dealing with that. This specific issue is easily resolved by duck typing, and if an object doesn't have a required method, and error is thrown; as simple as that.