OO / Private verse Protected


#1

Can someone give me an example of when a private method would be more
appropaiate then a protected one?

I understand the definition of the two but I don’t quit understand the
uses.

A protected method is only accessible from other objects derived from
the
same class.
A private method is basically the same thing but can only be called by
the
current object.

shrug how are those two things different.
When would you ever have an instance that is going to call a method from
another instance?


#2

On Thu, Jun 01, 2006 at 03:35:19AM +0900, Paul D. Kraus wrote:

shrug how are those two things different.
When would you ever have an instance that is going to call a method from
another instance?

Personally, I think protected methods are completely useless, except
maybe
if you want to allow some “dirty” access to improve performance in very
specific cases.

If your methods are supposed to be called from other instances
you’re almost always better off making the methods public - if that
makes
your API ugly, you’ve usually got a bad design.

Joost.


#3

On May 31, 2006, at 1:35 PM, Paul D. Kraus wrote:

by the
current object.

shrug how are those two things different.
When would you ever have an instance that is going to call a method
from
another instance?

Maybe in a situation like:

class MyClass
def initialize
@secret_data = 5
end
def ==( other )
secret_data == other.secret_data
end
protected
attr_reader :secret_data
end
=> nil

James Edward G. II


#4

At least in Java these modifiers are quite usefull: a protected method
is one that offers extensibility/polymorphic behavior for hierarchies,
without exposing it as public API. So the behavior may vary according
to the implementation, and the exposed API/public methods are a
completely different thing.

./alex

.w( the_mindstorm )p.


#5

I think you are looking at the problem from the wrong perspective: is
not calling a method from another instance, but is about were the
method is defined. The protected/private access modifiers are quite
usefull when dealing with class hierarchies.

./alex

.w( the_mindstorm )p.


#6

On 5/31/06, Joost D. removed_email_address@domain.invalid wrote:

Protected methods are part of the public API anyway - might as
well admit it and make them public and put a big disclaimer in the
docs.

Joost.

Not sure I am getting your argument. For inheritance this is the exact
needed behavior. Any external object will still be not able to call
these methods. So they are providing a way to customize your internal
implementation when working with hierarchies, but not offer it as an
API method.

./alex

.w( the_mindstorm )p.


#7

On Thu, Jun 01, 2006 at 04:29:59AM +0900, Alexandru P. wrote:

that allows you to do that.
these methods. So they are providing a way to customize your internal
implementation when working with hierarchies, but not offer it as an
API method.

My argument was that you then have to disallow people from implementing
their own classes based on your classes, because if they do, they still
can call the protected methods you just worked so hard to “protect”.

My main point though, is that if you think you need protected methods
you
should think really hard about wether other classes might find those
methods useful too (i.e. just make them public instead).

I’ve ran into too many problems with libraries where you just can’t call
very handy methods because the designer decided you shouldn’t and then
it
takes hours to work around that. My gut feeling is that protected
methods
are usually either badly designed, or made so the designer can feel good
about not binding the API to the implementation. If your implementation
is
so bad you don’t want other people relying on it, but you still need
access to it to make your code work, you’re doing something wrong.

I’m open to the idea that protected methods can be useful, it’s just
that
I don’t like most uses of them that I’ve seen.

I feel the same about “friend” functions & classes in C++ (harcore
performance reasons only, I’d say)

YMMV,

Joost.


#8

On Thu, Jun 01, 2006 at 03:57:08AM +0900, Alexandru P. wrote:

At least in Java these modifiers are quite usefull: a protected method
is one that offers extensibility/polymorphic behavior for hierarchies,
without exposing it as public API. So the behavior may vary according
to the implementation, and the exposed API/public methods are a
completely different thing.

That’s only true if you also find some way to stop the “public” from
inheriting from your base classes too, and I cann’t think of any
language
that allows you to do that.

Protected methods are part of the public API anyway - might as
well admit it and make them public and put a big disclaimer in the
docs.

Joost.


#9

On 6/1/06, Joost D. removed_email_address@domain.invalid wrote:

inheriting from your base classes too, and I cann’t think of any language
needed behavior. Any external object will still be not able to call
these methods. So they are providing a way to customize your internal
implementation when working with hierarchies, but not offer it as an
API method.

My argument was that you then have to disallow people from implementing
their own classes based on your classes, because if they do, they still
can call the protected methods you just worked so hard to “protect”.

But I haven’t worked on protecting them against overridding, but
against direct calls. Big difference.

My main point though, is that if you think you need protected methods you
should think really hard about wether other classes might find those
methods useful too (i.e. just make them public instead).

This is a matter of the API designer skills. However making everything
public, for the sake that somebody may find one of the methods usefull
is imo worse than having to evolve your initial API.

I’ve ran into too many problems with libraries where you just can’t call
very handy methods because the designer decided you shouldn’t and then it
takes hours to work around that. My gut feeling is that protected methods
are usually either badly designed, or made so the designer can feel good
about not binding the API to the implementation. If your implementation is
so bad you don’t want other people relying on it, but you still need
access to it to make your code work, you’re doing something wrong.

It’s sad to hear this, but unfortunately I would say that it was your
bad luck to work with bad designed APIs. Agreed, some projects get it
right from the 1st version, other are learning how to do it.

./alex

.w( the_mindstorm )p.

PS: probably we just have to agree to disagree :-). For me protected
is usefull and has been. Bad APIs is another topic and in some of the
companies I have worked for there were specific people for designing
the APIs for the frameworks used by hundred of other developers (I was
one of them :slight_smile: and frankly speaking, so far, I haven’t had such a
bad feedback as you describe).


#10

I believe the purpose of privatising methods is to avoid exposing
internal
implementation details that may change in future revisions of the code.
You
don’t want people depending on methods you created internally to support
your public API, especially since those methods may be tied to
implementation details that should not be exposed.

Also, protected methods are not public…they are simply callable or
extensible within that branch of a class hierarchy. When a class extends
your base, it implicitly accepts responsibility for fulfilling the
contract
of your public API. If it chooses to use your protected methods, or even
expose them, it may do so at its own peril. Your base implementation
could
change in the future rendering that class nonfunctional and in violation
of
the base class’s explicit contract. However, protected methods have the
option of being overridden; the extending class can (and often should)
provide its own internalized version of a protected method and have the
parent’s methods then behave according to that new implementation.

The reason for protected versus private is this:

  • protected methods define behavior that could logically differ between
    classes in a hierarchy, but should generally not be exposed for direct
    calls
    to clients of the classes in that hierarchy. These are class-specific
    methods that alter behavior between parent and child, allowing child
    classes
    to literally “extend” the behavior of the parent by providing a new
    implementation without altering the public API.
  • private methods are dependent enough on your specific implementation
    or
    localizable enough to a single level in the class hierarchy that they
    should
    not be exposed or overridden in any way. The behavior of a class or its
    public API may be wholely dependent on that one implementation of an
    algorithm, and child classes should not be allowed to replace it. By the
    same token, that algorithm may have to change or go away in the future,
    and
    clients of the class or its subclasses should not call it directly.

#11

Alexandru P. wrote:

At least in Java these modifiers are quite usefull: a protected method
is one that offers extensibility/polymorphic behavior for hierarchies,
without exposing it as public API. So the behavior may vary according
to the implementation, and the exposed API/public methods are a
completely different thing.

But Java != Ruby. In ruby, even private methods can be called from
instance methods of a subclass.

irb(main):001:0> class A; private; def foo; end; end
=> nil
irb(main):002:0> class B<A; def bar; foo; end; end
=> nil
irb(main):003:0> B.new.foo
NoMethodError: private method `foo’ called for #<B:0xb7b36834>
from (irb):3
irb(main):004:0> B.new.bar
=> nil

Protected is different from what you expect:

class A
protected

private

def foo
puts “foo!”
end

public
def call_foo_on_dup
dup.foo
end
end

A.new.call_foo_on_dup # ==> foo!

Now try it with private…


#12

On Thu, Jun 01, 2006 at 06:36:11AM +0900, Alexandru P. wrote:

My argument was that you then have to disallow people from implementing
their own classes based on your classes, because if they do, they still
can call the protected methods you just worked so hard to “protect”.

But I haven’t worked on protecting them against overridding, but
against direct calls. Big difference.

Ofcourse.

My main point though, is that if you think you need protected methods you
should think really hard about wether other classes might find those
methods useful too (i.e. just make them public instead).

This is a matter of the API designer skills. However making everything
public, for the sake that somebody may find one of the methods usefull
is imo worse than having to evolve your initial API.

That’s not what I meant. You can still make methods private. But if
methods
are useful enough to make protected / need to be accessible from
subclasses
or other instances, you should really stop and think if you have to
deny
access from the rest of the code. If your classes are only going to be
used
in one project, knock yourself out - you can always change it later. But
if
you are writing reusable components… well, I think I’ve made my point
:slight_smile:

bad luck to work with bad designed APIs. Agreed, some projects get it
right from the 1st version, other are learning how to do it.

True enough.

Cheers,
Joost.


#13

Sorry to send to the whole group, but I subscribed ages ago, and I’ve
completely forgotten where to unsubscribe from the list!
Thanks!


#14

Seen in the headers of EVERY message to ruby-talk:

List-Unsubscribe: mailto:removed_email_address@domain.invalid?body=unsubscribe

Ryan


#15

Alexandru P. wrote:

At least in Java these modifiers are quite usefull: a protected method
is one that offers extensibility/polymorphic behavior for hierarchies,
without exposing it as public API. So the behavior may vary according
to the implementation, and the exposed API/public methods are a
completely different thing.

Keep in mind that Ruby protected and private have slightly different
meanings than in Java. Private protection in Ruby is instance based.
That means that private methods are callable only within the object
instance, but (unlike Java) that instance need not be a direct instance
of the class.

Ruby protected seems to be pretty close to the Java concept of
protected, AFAICT (minus the package exposure in Java). However, I
almost never use Ruby protected so I am probably missing some
subtleties.

– Jim W.


#16

On 6/1/06, Travis D. removed_email_address@domain.invalid wrote:

Sorry to send to the whole group, but I subscribed ages ago, and I’ve
completely forgotten where to unsubscribe from the list!
Thanks!

List-Unsubscribe: mailto:removed_email_address@domain.invalid?body=unsubscribe


#17

Thanks Joel and Jim. I was aware that there are differences between
Ruby private/protected and Java private/protected, that’s the reason
why I have said it load: “at least in Java these modifiers…”. I
know how these are working for Java and I was commenting about their
usability. Indeed, considering that I am on the Ruby ML, I should have
probably prefix my messages with a little offtopic, so I apologize for
this.

BR,

./alex

.w( the_mindstorm )p.


#18

2006/6/1, Joost D. removed_email_address@domain.invalid:

That’s not what I meant. You can still make methods private. But if methods
are useful enough to make protected / need to be accessible from subclasses
or other instances, you should really stop and think if you have to deny
access from the rest of the code. If your classes are only going to be used
in one project, knock yourself out - you can always change it later. But if
you are writing reusable components… well, I think I’ve made my point :slight_smile:

Note though that it’s usually harder to remove functionality than to
add it, i.e. it’s better to start with the more restricted version
(protected) and make methods public later if you see the need for
this. Nevertheless all sorts of problems arise if library code that is
inherited from is changed (e.g. if you make a protected method public
sub classes will break in Java because you cannot reduce visibility in
an overridden method).

An idiom I use from time to time makes explicit use of “protected”: I
have an abstract base class that implements algorithms that rely on
specific parts implemented in sub classes; often these “parts” are
just getters that return a piece of data - but it can be more complex
of course. These things do not belong into the full light of public
because they are not the methods intended for primary use. But I do
grant you that they must be viewed as part of the public interface
because they can cause dependencies - something which cannot happen
with private methods in Java.

Inheritance is an interesting but also complex field and difficult to
get right.

You said earlier: “I cann’t think of any language that allows you to
do that.” Off the top of my head Eiffel is one of the languages that
does this. Bertrand Meyer thinks that implementation inheritance is as
good as interface inheritance and that’s why sub classes can
completely change the public interface of their base classes. Of
course then there is no longer an “is a” relationship and you cannot
use sub class instances where base class instances were allowed. Btw,
even if you don’t agree with all of his positions “Object-oriented
Software Construction” is nevertheless an interesting and valuable
read.

Kind regards

robert