13

I was casually walking through source code of Java core classes. I found that Process.java file is an public abstract class. When I went through code No function have definition. Does that mean that it should have been declared an Interface. Is there any deliberate reason behind it. Can some one help me understand need of such design.

Link to code

Aman J
  • 1,825
  • 1
  • 16
  • 30
  • Some say that an interface represents a "has-a" relationship and inheritance represents an "is-a" relationship. The original author of Process.java may have believed that implementers of Process would *be* a process, rather than simply _having_ a process. – Eric Apr 22 '13 at 15:41
  • 2
    This related [question](http://stackoverflow.com/q/761194/1225328) has an interesting [answer](http://stackoverflow.com/a/10026391/1225328). – sp00m Apr 22 '13 at 15:49
  • It is because it is. Not constructive. – user207421 Apr 22 '13 at 23:26
  • @EJP Well I think there are thoughts of great people behind Java design, so there has to be a very good reason, which **ordinary **people like me never get(I mean it). :-) – Aman J Apr 23 '13 at 08:36
  • @AmandeepJiddewar There almost certainly is a very good reason, and if you asked the 'great people' you would probably discover it. However you aren't asking them, you're asking on StackOverflow, and there is zero evidence that those 'great people' are even in attendance here. Ergo, all you are going to get here is uninformed opinion: ergo, not contsructive. – user207421 Apr 24 '13 at 10:30

4 Answers4

3

Process is abstract because it is likely to have a different implementation on each operating system. Application developers don't implement this abstract class; it's implemented as part of the Java runtime.

Since all methods are abstract, it could have been declared as an interface, but that would make the class unable to evolve in the future. For example, new methods should not be added to an interface once it's been declared in a public API, because then any existing implementations will be incompatible. In contrast, a new (concrete) method can be easily added to an abstract class.

Instances of Process are created by the runtime, either through the Runtime class methods, or from a ProcessBuilder instance. Applications generally wouldn't use the new operator to create an instance (of the concrete subclass) directly.

erickson
  • 265,237
  • 58
  • 395
  • 493
  • +1, I just do not understand the reason of adding a concrete method to Process. Everyone extending process is still going to implement the same abstract methods, they might not even realize there is a concrete one. – Eugene Apr 22 '13 at 16:23
  • @Eugene If you define an interface, and someone implements it, then you change the interface, their implementation is broken. They can't recompile, because it's a source incompatibility, and if someone uses an old version previously compiled, they'll get an `IncompatibleClassChangeError` or a `NoSuchMethodError`. On the other hand, if you use an abstract class, and later add a concrete method, people who extended the class don't have to do anything. Their old code continues to work fine. – erickson Apr 22 '13 at 17:25
  • Yep, after checking the source I see that you're right -- there is a separate (final) ProcessImpl class for each platform. – Hot Licks Apr 22 '13 at 20:36
  • @erickson that is still a vague reason to me. Don't get me wrong, this is probably the best answer here(should be accepted). – Eugene Apr 23 '13 at 06:56
  • I see a few functions implemented in Java 8. – Aman J Oct 27 '20 at 13:01
  • Yes, shortly after the original question, some concrete methods were added in Java 8. However, Java 8 also added support for `default` methods in interfaces, so the reasoning against using an `interface` would not hold if `Process` were invented today; it's an `abstract class` because of when it was created. – erickson Oct 27 '20 at 16:28
2

I suspect the critical difference arises from the fact that you can implement as many interfaces as you wish but you can only extend one class, be it abstract or otherwise.

Making Process abstract therefore ensures that if you actually decide to create one from scratch (i.e. not from a system-supplied factory, which is the normal route) you would not be able to put functionality in a parent class of it. How that helps I'm not sure.

Maybe it's a security thing since processes are supposed to be created and owned by the operating system. It is doing it's best to discourage you from making them yourself.

Added

Deep down I think the reason it's not an interface is historical. Remember Process has been in java.lang since the year dot and back then an interface was something you implement, not a definition of a facet of an object's personality. That concept grew up much later.

Notice that Process has been around since JDK 1.0 while many of the more useful interfaces arrived much later, the CharSequence interface for example did not appear until JDK 1.4. I think there was a paradigm shift from objects being primary and interfaces being really useful to interfaces being the be all and end all while objects merely implement.

Process would therefore be one of the old classes that were created at the time when a Process was a real object and probably drove an Audi Quattro, not some vague notional namby-pamby miasmic thing that has some methods in it and looks a bit like this.

OldCurmudgeon
  • 64,482
  • 16
  • 119
  • 213
1

The class Process clearly does have internal functionality that we can't see and this must be dependent on the operating system, for obvious reasons.

My guess is that they don't want you implementing your own classes conforming to the API that don't inherit the hidden functionality of the Java library defined Process class.

JeremyP
  • 84,577
  • 15
  • 123
  • 161
  • Bingo! `Process` must be a class since there is internal functionality associated with it, and with an interface there would be not be anything "real" beneath it. – Hot Licks Apr 22 '13 at 16:50
  • How is it clear that the class `Process` has internal functionality? Could this internal functionality not be implemented in the derived class? – Oswald Apr 22 '13 at 17:18
  • @Oswald - How does the coder of the derived class know what to implement, and how can he access the internal interfaces necessary to do it? – Hot Licks Apr 22 '13 at 18:06
  • @HotLicks I don't know. That's why I asked. Note that "ProcessBuilder.start() and Runtime.exec methods ... return an instance of a *subclass of Process*" (from the JDK docs). Why should `Process` provide this *internal functionality*? Why not the subclass? – Oswald Apr 22 '13 at 20:13
  • @Oswald - Yeah, actually I looked into it -- checked the source -- and you're right that there is no function per se in Process the abstract class (including the private natives I was expecting). Instead, each platform implements ProcessImpl as a final subclass of Process, and that's where the logic is. There's no benefit to having Process an Interface since you can't subclass it. – Hot Licks Apr 22 '13 at 20:35
0

According to the documentation of java.lang.Process, that class provides a constructor that can be called without arguments. Interfaces cannot do that.

Oswald
  • 31,254
  • 3
  • 43
  • 68
  • It only does have a default constructor. How is that helpful? – Eugene Apr 22 '13 at 15:51
  • And this default constructor must exist, either generated by the java compiler or coded by the developer. If `java.lang.Process` were an interface, no default constructor might exist. – Oswald Apr 22 '13 at 15:56
  • 1
    @Oswald Whatever, this is the default constructor which isn't even implemented in the class (thanks to the OP's link). I guess the JavaDoc creation automatically added it without having specified it explicitly. I'm not sure this is the point. – sp00m Apr 22 '13 at 15:56
  • There are two things involved here. 1. The specification. It requires that a `java.lang.Process` has a constructor that can be called without arguments. 2. The implementation. It does not have private variables that need to be initialized, so the constructor that is generated by the Java compiler is fine. Other implementations might have private variables that need to be initialized. – Oswald Apr 22 '13 at 15:59
  • Yes, all objects have a default zero-parm constructor, but that would be the case with any class that implemented a Process interface. And subclasses can add their own constructors (with parms) and if they do then the default constructor gets blocked. So the definition of constructors has nothing to do with it. – Hot Licks Apr 22 '13 at 16:54
  • @HotLicks You are wrong. Objects do not necessarily have a zero-parm constructor. They only have one, if the class *implements* one explicitly or the class *does *not* *implement* a different constructor. – Oswald Apr 22 '13 at 17:16
  • @Oswald - That's what I was saying. The zero-parm constructor is inherited from Object. But if you define any other constructors then the constructors of your superclass are hidden. – Hot Licks Apr 22 '13 at 18:05
  • @HotLicks No, you were saying that "all objects have a default zero-parm constructor". I was saying that this is not the case. And in your recent comment, you are wrong again. Constructors are not inherited. – Oswald Apr 22 '13 at 20:01