Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I was wondering if there was a valid use case for being able to properly define the specific internal properties and functions of a class in a way similar to how an interface defines the public properties and functions of a class.

Imagine the task that you have to build a class that describes a human being.

Obviously, each human is a humanoid creature but not every humanoid creature is a human so you'd probably have an interface IHumanoid with functions like these (since it isn't useful to hardcode the body plan into the class):

public interface IHumanoid {
    function get head():IHead;
    function get torso():ITorso;
    function get leftArm():IArm;
    function get rightArm():IArm;
    function get leftLeg():ILeg;
    function get rightLeg():ILeg;
}

Further and also obviously, each human is a mammal but not every mammal is a human, so there's probably another interface IMammal with two definitions for males and females floating around somewhere:

public interface IMammal {
    function procreate(partner:IMammal):void;
}

public interface IMaleMammal extends IMammal {
    function inseminate(female:IFemaleMammal):void;
}

public interface IFemaleMammal extends IMammal {
    function conceive(partner:IMaleMammal):Boolean;
    function giveBirth():IMammal;
    function nurse(offspring:IMammal):void;
}

Thus our class probably looks something like this now:

public class Human implements IHumanoid, IMammal {
    private var _head:IHead;
    private var _torso:ITorso;
    private var _leftArm:IArm;
    private var _rightArm:IArm;
    private var _leftLeg:ILeg;
    private var _rightLeg:ILeg;

    public function Human() {
        // ctor...
    }

    public function get head():IHead {
        return _head;
    }

    public function get torso():ITorso {
        return _torso;
    }

    public function get leftArm():IArm {
        return _leftArm;
    }

    public function get rightArm():IArm {
        return _rightArm;
    }

    public function get leftLeg():ILeg {
        return _leftLeg;
    }

    public function get rightLeg():ILeg {
        return _rightLeg;
    }

    public function procreate(partner:IMammal):void {
        // "abstract" function
    }
}

public class MaleHuman extends Human implements IMaleMammal {
    override public function procreate(partner:IMammal):void {
        if (partner is IFemaleMammal) {
            inseminate(partner);
        }
    }

    public function inseminate(female:IFemaleMammal):void {
        female.conceive(this);
    }
}

public class FemaleHuman extends Human implements IFemaleMammal {
    override public function procreate(partner:IMammal):void {
        if (partner is IMaleMammal) {
            conceive(partner);
        }
    }

    public function conceive(partner:IMaleMammal):Boolean {
        // ...
    }

    public function giveBirth():IMammal {
        // ...
    }

    public function nurse(offspring:IMammal):void {
        // ...
    }
}

From this we can implement our classes further and everything's working nice and fine until we get the task to use the existing interfaces to implement some other classes. Perhaps a gorilla, an orca and a platypus.

Ignoring the massive issue the platypus will pose to our current interface structure (*cough* egg laying mammal *cough*), we have the "problem" that nothing prevents us from giving the gorilla 2 brains, the orca 8 lungs and the platypus half a dozen livers. And while we might be disciplined enough to follow the structure mammals typically have we cannot guarantee the same if we open the API for other developers who might code some seriously screwed up things which still look okay to the outside world.

Therefore I was wondering if there was a valid use case to create something like a "private interface" which defines non-public functions and properties. Perhaps something along these lines:

public structure SMammal {
    function get brain():IBrain;
    function get liver():ILiver;
    function get leftLung():ILung;
    function get rightLung():ILung;
    function get leftKidney():IKidney;
    function get rightKidney():IKidney;
}

public class Human implements IHumanoid, IMammal follows SMammal {
    private function get brain():IBrain {
        // ...
    }

    private function get liver():ILiver {
        // ...
    }

    // etc. etc.
}

Does such a feature exist in any programming language? Can abstract classes be used to solve this? Or shouldn't we care about this at all as long as the public interface somehow works as expected?

share|improve this question
    
The "IMumle" way of denoting an interface is a bad habit, in my opinion –  user1249 Aug 18 '12 at 22:32
    
Two comments. Firstly, it seems as though we can base the entire discussion on XML Schema, rather than specifics of language interfaces. Secondly, "validation" is sometimes (but not always) best separated from the "structure". –  rwong Aug 19 '12 at 17:45

3 Answers 3

up vote 0 down vote accepted

And while we might be disciplined enough to follow the structure mammals typically have we cannot guarantee the same if we open the API for other developers who might code some seriously screwed up things which still look okay to the outside world.

What exactly do you gain by forcing them to follow your structure? You possibly break some advanced usages, maybe there is a case for an animal with multiple brains. And the client programmer can mess up the implementation of a class in so many crazy ways that trying to prevent this feels like trying to a close window in an attempt to keep a horse in a barn.

Don't treat your client programmers like prisoners. If they follow the public interface, let the code run.

share|improve this answer
    
I don't want to treat those using an API like prisoners, but I was thinking about something along the lines of providing guidelines on how to structure e.g. a plugin to an existing framework. The plugin interface only tells you how your extension will be used by the framework, but it tells you nothing about how the plugins are supposed to behave internally. –  arotter Aug 19 '12 at 19:20
    
You have a point about advanced usages that aren't covered by some cookie-cutter approach, but you can easily run into those with the public interface as well (e.g. in C# you need/want to return an IList<T> but the interface demands you to return an IEnumerable<T>). And last but not least, there is afaik no known animal with multiple (redundant, like all of our duplicated organs) brains. So while there may be a case for something like this (e.g. spiders) it will almost certainly not be a mammal, so it would be a completely different interface/structure anyway. –  arotter Aug 19 '12 at 19:26
    
@arotter, I'm all for providing guidelines as to the best way to internally structure things. But I'm not seeing any reason to require a particular internal structure. The whole point of interface is to define the public interface, not the implementation. –  Winston Ewert Aug 19 '12 at 20:13

As an interface type is by default a public member everything within it should be public but I have seen this:

http://stackoverflow.com/questions/792908/what-is-a-private-interface

from msdn:

Interfaces consist of methods, properties, events, indexers, or any combination of those four member types. An interface cannot contain constants, fields, operators, instance constructors, destructors, or types. It cannot contain static members. Interfaces members are automatically public, and they cannot include any access modifiers.

http://msdn.microsoft.com/en-us/library/ms173156.aspx

share|improve this answer
    
Yes, the members of an interface are public. That doesn't mean that you can't have a private member of some interface type which you do not expose in your own interface. Implementing an interface is public. Using an interface can be as private as you like. OP is essentially asking how (s)he can declare a class to use specific interfaces privately, thus ensuring that any implementing class actually implements those methods. –  Marjan Venema Aug 19 '12 at 5:49
    
Yes i do agree with you hence why I posted a link that shows an interface with private members. –  almostSharepointMaster Aug 19 '12 at 11:57
    
Ah, ok. Well hidden... :) –  Marjan Venema Aug 19 '12 at 12:41
    
The question wasn't about interfaces in C# (or in any other existing language) but about the fundamental concept. This post doesn't address it at all. –  Peter Taylor Aug 19 '12 at 19:39

Does such a feature exist in any programming language? Can abstract classes be used to solve this? Or shouldn't we care about this at all as long as the public interface somehow works as expected?

It sure does. Pretty much any feature exists in some language.

For example, in Objective-C++ (iOS/Mac programming) it's standard procedure for a class to have at least two interfaces. On that is public, and one that is private. Sometimes they'll also have extra interfaces that are defined elsewhere (eg, the low level string class has an interface for performing GUI screen drawing operations on the string, which is defined in a completely separate framework/library from the one that defines the string class).

Basically the way I treat public/private is simple:

Public interface elements can never be changed. Whenever you refactor or improve your code, the public interface still needs to behave exactly the same as before.

Private interfaces on the other hand, can be changed or completely removed whenever you want. As long as you update all the code in the class to understand the new behaviour, you're fine. Often the public interface will be full of one or two line methods that hand the actual work over to the private interface.

Objective-C++ also has the concept of "protected" in the interface, where something is available to subclasses but not external classes.

Usually my code is split about half and half between public and private. I don't use protected much at all, though it does come in handy once in a while.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.