8

...As this forces us to create getters and setters, which in practice are often totally extraneous? Is there any good language-design reason why interfaces in most (all?) languages do not allow member fields to help fulfill the interface spec?

In most extant languages, members are treated fundamentally differently from methods, but does this HAVE to be the case? In a theoretical language, couldn't we have an interface that (a) specified a zero-args method as getter, but accepted a readable member as its implementor, and (b) specified a single-arg method as a setter, but accepted a writable member field as its implementor, given a language that supported specifying direct access control on variables when they are declared? A prototypal language allowing multiple inheritance (to address the very valid point some respondents have made), would be ideal for something like this.

Please inform me if something like this already exists.

3
  • 2
    Uh... methods are members. I presume you mean "member fields"?
    – Aaronaught
    Commented Aug 6, 2011 at 14:01
  • OK to use the proper Java terminology, yes, "member fields". Thanks for pointing that out.
    – Engineer
    Commented Aug 6, 2011 at 14:05
  • 1
    OOP sucks, but do try C# if you must.
    – Job
    Commented Aug 6, 2011 at 16:00

11 Answers 11

10

In most extant languages, member [fields?] are treated fundamentally differently from methods, but does this HAVE to be the case?

Yes, it does.

Member fields are per-instance data. Data must actually exist somewhere in memory for every instance - there must be an address or sequence of addresses reserved for it. In Java, .NET, and many other OO languages, this data goes on the heap.

Methods are per-class data. They are pointers to a vtable. That's how methods get virtual dispatch. There is only actually one instance allocated, per class.

An interface is essentially a special type of class that only contains methods, no instance data. That's part of the definition of interface. If it contained any data, it wouldn't be an interface anymore, it would be an abstract class. Both of those choices are fine, of course, depending on what kind of design pattern you're trying to implement. But if you added instance data to interfaces, you'd take away everything that makes them interfaces.

OK, so why can't an interface method point to a member field? Because there's nothing at the class level to point to. Again, an interface is nothing but a method table. The compiler can only generate one table, and every method in it has to point to the same memory address. Thus it's impossible for interface methods to point to class fields, because the class field is a different address for every instance.

Perhaps the compiler could accept this anyway and generate a getter method for the interface to point to - but then that essentially becomes a property. If you want to know why Java doesn't have properties, well... that's a really long and tedious story that I'd rather not get into here. But if you're interested, you might want to have a look at other OO languages which do implement properties, such as C# or Delphi. The syntax is really easy:

public interface IFoo
{
    int Bar { get; }
}

public class Foo : IFoo
{
    public int Bar { get; set; }
}

Yep, that's all there is to it. Important: These are not fields, the "int Bar" in the Foo class is an Auto Property, and the compiler is doing exactly what I just described above: automatically generating getters and setters (as well as the backing member field).

So to recap the answer to your question:

  • Interfaces require methods because their entire purpose is not to contain any data;
  • The reason that there is no syntactic sugar to make it easier for a class to implement an interface is simply that the Java designers do not will it - and by this point in time, backward compatibility is an issue. Language designers make these kinds of choices; you'll just have to deal with it, or switch.
1
  • This is a good answer, in particular I found the information about function lookup informative. Thanks.
    – Engineer
    Commented Aug 6, 2011 at 21:46
9

this is a result of information hiding, i.e. those members shouldn't be visible as fields but as properties that may or may not be stored/cached locally

one example is a the hash code it changes when the object changes so it is better to calculate it when it is asked for and not each time the object changes

besides most languages are single-inheritance + multi-implements and allowing fields to be part of interfaces puts you into multi-inheritance territory (only thing missing is default implementation of functions) which is a minefield of edge cases to get right

3
  • multi-implementing fields is the issue here.
    – DeadMG
    Commented Aug 6, 2011 at 15:21
  • I must say, thinking about this further, I don't really agree about multiple inheritance. Because what I'm really asking about is whether a representation of data members in interfaces is possible, not whether you can use data members to construct interfaces (which is essentially a C++ abstract class). There is a key difference there.
    – Engineer
    Commented Aug 6, 2011 at 21:35
  • There's really no problem with MI; a language would just have to balk at implementing two interfaces with conflicting types for the same member.
    – Blrfl
    Commented Aug 7, 2011 at 19:38
6

Member variables are the implementation of the class, not the interface. You may want to change the implementation, so other classes shouldn't be permitted to refer to that implementation directly.

Consider a class with the following methods - C++ syntax, but that isn't important...

class example
{
  public:
    virtual void Set_Mode (int p_mode);
    virtual int  Mode () const;
};

It seems pretty obvious that there's going to be a member variable called mode or m_mode or similar that directly stores that mode value, doing pretty much what a "property" would do in some languages - but that's not necessarily true. There's a lot of different ways this could be handled. For example, the Set_Mode method might...

  1. Identify the mode using a switch statement.
  2. Instantiate a subclass of some internals class, depending on that mode value.
  3. Store a pointer to that instance as a member variable.

Having done that, many other methods of the example class might then call appropriate methods of that internals class through the pointer, getting mode-specific behaviour without needing to check what the current mode is.

The point here is less that there's more than one possible way to implement this kind of thing, and much more that at some time you may change your mind. Maybe you started with a simple variable, but all the switch statements to identify the mode in every method are getting a pain. Or maybe you started out with the instance-pointer thing, but that turned out to be too heavyweight for your situation.

It turns out that things like this can happen for any member data. You may need to change the units that a value is stored in from miles to kilometers, or you may find that your uniquely-identify-the-case enumerate can no longer uniquely identify all the cases without considering some extra information, or whatever.

This can happen for methods too - some methods are purely for internal use, depend on the implementation, and should be private. But many methods are part of the interface, and won't need to be renamed or whatever just because the internal implementation of the class has been replaced.

Anyway, if your implementation is exposed, other code will inevitably start to depend on it, and you'll be locked into keeping that implementation. If your implementation is hidden from other code, that situation cannot happen.

Blocking access to implementation details is called "data hiding".

4
  • "Code to an interface, not an implementation"... Right. Sometimes we know these things latently but it takes someone to reason them out as you have done, to really solidify the concepts once again.
    – Engineer
    Commented Aug 6, 2011 at 12:13
  • OK -- wait a minute. After further thought, please see my edit to the question.
    – Engineer
    Commented Aug 6, 2011 at 12:19
  • It's a little difficult to figure out what your edit was - for some reason, diffs for some of the older edits aren't shown. What I think your saying, though, is "why can't a property have a member variable as a default implementation?" A property looks (interface) like a member variable, but is implemented via getter/setter methods. And IMO there's no reason why, by default, those getter/setter methods shouldn't implement a read/write to a member variable - or why the getter and setter call shouldn't be optimised away when it's safe - allowing for inheritance, separate compilation etc.
    – user8709
    Commented Aug 7, 2011 at 18:55
  • @Nick - So yes, as long as it's possible to say "the getter and/or setter for this property should be pure" or "should not be the default ones" I think that's a good idea - eliminating some of the clutter for a common case with properties. I don't know if there's a language that does it already - haven't used properties much even in languages where they exist - but I'd be surprised if this isn't already supported.
    – user8709
    Commented Aug 7, 2011 at 18:58
3

As others have noted, an interface describes what a class does, not how it does it. It's essentially a contract that inheriting classes must conform to.

What you describe is slightly different - a class that provides some implementation but perhaps not all, as a form of reuse. These are generally known as abstract classes and are supported in a number of languages (e.g. C++ and Java). These classes cannot be instantiated in their own right, they can only be inherited by concrete (or further abstract) classes.

Again as noted already, abstract classes tend to be of most value in languages that support multiple-inheritance as they can be used to provide pieces of additional functionality to a larger class. This is often considered bad style, however, as generally an aggregation ("has-a") relationship would be more appropriate

2
  • Good answer. I tend to favour composition almost entirely in the sort of tasks I undertake these days. I personally don't believe in the separate treatment of abstract classes and interfaces in certain languages, as others on this board have stated, although there are reasons for this, generally these reasons are due to fundamental language limitations (such as mentioned in my comment on ratchet freak's answer).
    – Engineer
    Commented Aug 6, 2011 at 12:08
  • 1
    I tend to agree with your comment re: abstract/interfaces. When I look back at old code where I used a lot of abstract classes, it's clear to me with 10-15 years' more experience that I was using language features to code around bad design Commented Aug 6, 2011 at 12:39
3

Obviously in most extant languages, members are treated fundamentally differently from methods, but does this HAVE to be the case?

Not for any theoretically-grounded reason. I think the reasons you don't see it often are practical:

The first is how you deal with these things at runtime. In Java or C++, an assignment to a primitive-typed public member like foo.x = 5 is easy to deal with: stuff 5 into some register, figure out where in memory the x member of foo lives and dump the register there. In a language like C# where classes can encapsulate intercepting assignments to members or pre-calculate how those members will evaluate, the compiler will have no a priori knowledge of whether the implementation of a class made available at runtime uses that feature. That means all public member assignments and evaluations of public members have to be deferred to the implementation.* Operations involving a lot of access to those members end up taking a performance hit because they're constantly doing subroutine calls that could be handled faster with regular in-line assignments. Leaving evaluation and assignment separate from getters and setters gives the developer some control over how they're handled in a given situation.

The second is age. With the possible exception of F#, none of the languages in very wide use today is any younger than a decade, and even as recently as back then, the additional cycles required to make intercepted evaluation and assignment possible may not have been acceptable.

Third is inertia. I think to some degree, there's still some stigma associated with doing direct assignment to public members even if the language does allow the class to manipulate them and people still think in terms of getters and setters being better. That will wear off with time, just as it did with all of the people who had their noses in the air over people who wrote programs in higher-level languages instead of assembly.


*There's a tradeoff that comes with this: a language has to go whole hog with deferring evals/assignments to the class or balk at runtime if code using in-line evals/assignments for a given class tries to link with an implementation that intercepts them. Personally, I think the latter is a bad idea because it forces recompilation of code that uses an API that's unchanged.

5
  • Thank you, you've understood the thrust of my question and gotten into the gritty details of WHY. I had a hunch that speed would be one of the reasons -- as it always does when you head down the road of "more dynamic". As we are seeing now with languages like JS and Python, flexibility often trumps speed, so the "inertia" you mention towards certain language design trends based on (what was once necessary) optimisation slowly dissolves.
    – Engineer
    Commented Aug 6, 2011 at 21:40
  • F# is heavily based on Objective CAML - it may be younger than a decade, but most (probably all) of the ideas are older.
    – user8709
    Commented Aug 7, 2011 at 19:02
  • 1
    I'm kinda curious why the two downvoters pressed the red button.
    – Blrfl
    Commented Aug 8, 2011 at 15:37
  • @Blrfl: My point of criticism would be that your answer focuses too much on implementation details, rather than looking at it from a language design point of view. I didn't downvote you for it though, but perhaps others have. Commented Aug 10, 2011 at 14:15
  • Scala is also relatively young and it's widely used Commented May 8, 2015 at 8:33
1

Please inform me if something like this already exists.

Objective-C properties provide this sort of functionality with its synthesized property accessors. An Objective-C property is essentially just a promise that a class provides accessors, typically of the form foo for the getter and setFoo: for the setter. The property declaration specifies certain attributes of the accessors related to memory management and threading behaviors. There's also a @synthesize directive which tells the compiler to generate accessors and even the corresponding instance variable, so you don't have to bother writing getters and setters or declaring an ivar for each property. There's also some syntactic sugar that makes property access look like accessing the fields of a struct, but actually results in calling the property accessors.

The result of all that is that I can declare a class with properties:

@interface MyClass : NSObject
{}
@property (assign) int foo;
@property (copy) NSString *bar;
@end

and then I can write code that looks like it accesses ivars directly, but in fact uses accessor methods:

MyClass *myObject = [[MyClass alloc] init];  // create myObject

// setters
myObject.foo = 127;                 // same as [myObject setFoo:127];
myObject.bar = @"Hello, world!";    // same as [myObject setBar:@"Hello, world!"];

// getters
int i = myObject.foo                // same as [myObject foo];
NSString *s = myObject.bar          // same as [myObject bar];

It's been said already that accessors let you separate interface from implementation, and the reason that you want to do that is to preserve your ability to change the implementation in the future without affecting client code. The drawback is that you have to be disciplined enough to write and use accessors just to keep your future options open. Objective-C makes generating and using accessors as easy as using ivars directly. In fact, because they take care of much of the work of memory management, using properties is actually a lot easier than accessing ivars directly. And when the time comes that you want to change you implementation, you can always provide your own accessors instead of letting the compiler generate them for you.

0
1

Why do interfaces require methods over members?

...As this forces us to create getters and setters, which in practice are often totally extraneous? Is there any good language-design reason why interfaces in most (all?) languages do not allow members to help fulfill the interface spec?

"Most" languages? Which languages have you investigated? In dynamic languages there are no interfaces. There are only three or four statically typed OO languages with any popularity: Java, C#, Objective-C, and C++. C++ doesn't have interfaces; instead we use abstract classes, and an abstract class can contain a public data member. C# and Objective-C both support properties, so there is no need for getters and setters in those languages. That leaves only Java. Presumably the only reason Java does not support properties is that it has been difficult to introduce them in a backward-compatible fashion.

3
  • Members was meant to refer to "member fields" as opposed to "member functions" which I refer to simply as methods. I'm not sure from which language (if any) I picked up this convention. So given what I'd written, I see your answer, but I guess a comment under my question to clarify would have been more constructive.
    – Engineer
    Commented Aug 6, 2011 at 18:14
  • Re C++, touché. However, actually there are interfaces in dynamic languages, JS and Python being two that immediately spring to mind. Whether a proponent of statically-typed languages would call these "interfaces", is a whole other discussion that I see no point in getting into. Personally I show little preference for either side of that fence, using as I do a broad range of languages to different purposes.
    – Engineer
    Commented Aug 6, 2011 at 19:05
  • @Nick: JS and Python have inheritance, but I would not say they have interfaces; one can call any method on any object. Commented Aug 7, 2011 at 3:02
1

Some of the answers mention 'information hiding' and 'implementation details' as the reason interface methods are preferred over fields. I think the main reason is simpler than that.

Interfaces are a language feature that allow you to swap out behavior by having multiple classes implement an interface. The behavior of a class is defined by its methods. Fields, on the other hand, only reflect the state of an object.

Of course, the fields or properties of a class may be part of the behavior, but they aren't the important part of the contract defined by the interface; they are only a result. Which is why e.g. C# allows you to define properties in an interface, and in Java you define a getter in the interface. This is where a bit of information hiding comes into play, but it's not the main point.

As I said before, interfaces allow you to swap out behavior, but let's have a look at the swapping out part. An interface allows you to change the underlying implementation by creating a new implementing class. So having an interface consisting of fields doesn't make much sense, because you can't change much about the implementation of fields.

The only reason you'd want to create a field-only interface is when you want to say that some class is a certain type of object. I've emphasized the 'is a' part, because you should be using inheritance rather than interfaces.


Side-note: I know that composition it preferred over inheritance and composition can usually only be achieved by using interfaces, but using interfaces just to 'tag' a class with some properties is just as bad. Inheritance is great when used appropriately, and as long as you stick to the Single Responsibility Principle, you shouldn't have any problems.

I mean, I've never worked with a UI control library for example, which doesn't use inheritance. The only area where interfaces come into play here is in data provisioning, e.g. an ITableDataAdapter to bind data to a table control. This is exactly the type of thing interfaces are meant for, to have interchangeable behavior.

0

In Java the reason is that interfaces only allow specifying methods.

Therefore if you want anything with a field in the interface contract, you need to do it as a getter and a setter method.

Also see this question: When are Getters and Setters Justified

2
  • 1
    Thanks for coming to reply, it was actually your response on that very topic that got me to ask this question :) But the question remains, "-WHY- did they only allow methods?" The point of interfaces is not to specify methods, that's cyclical logic. The point of interfaces is to ensure that some base degree of functionality is fulfilled. Members can make up part of that functionality. So why not allow them to participate in the interface fulfillment?
    – Engineer
    Commented Aug 6, 2011 at 10:54
  • I do not know. Perhaps if you asked Gosling or Steele directly?
    – user1249
    Commented Aug 6, 2011 at 17:23
-1

The point of an interface is to specify functions you must implement in order to claim to support this interface.

4
  • 2
    This doesn't answer the question. The question is WHY did they do it that way? Had you ever considered not writing getters and setters for every variable, and still being able to fulfill an interface? That would save time!
    – Engineer
    Commented Aug 6, 2011 at 10:55
  • You keep asking about getters and setters, and I have no idea why. Look at a simple interface: download.oracle.com/javase/6/docs/api/java/util/… Notice how there are no getters and setters? Commented Aug 6, 2011 at 13:42
  • 1
    What does that prove? Does that one example prove you will never need simple/direct access to members? No. The point is, it is silly to have wrap members in getters / setters as part of the interface, if the language itself could deal with that automatically.
    – Engineer
    Commented Aug 6, 2011 at 13:45
  • There are hundreds of other examples just like this. Can you give me an example of the situation you're talking about? Commented Aug 6, 2011 at 15:54
-1

Members aren't allowed in interfaces because then those languages would have to deal with the horrendous evil that is, multiple inheritance.

1
  • 2
    Not sure I follow. Why would allowing member variables in an interface require or imply support for multiple inheritance? Commented Aug 6, 2011 at 18:38

Your Answer

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

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