6

In many other languages like C++ and Javascript, OOP is optional. Procedural code is ok. But in languages like Java and C#, OOP is somewhat enforced. Everything is to be a part of a class or an object. What are the benefits?

20
  • 13
    What do you mean it's enforced? How so? Feb 21, 2011 at 16:09
  • 57
    The class idiom is enforced, but don't worry, you can still produce crap-code that won't be OO in any way, if that floats your boat.
    – haylem
    Feb 21, 2011 at 16:14
  • 9
    If you're fond of the "static" keyword, C# can be just as procedural as javascript.
    – James Love
    Feb 21, 2011 at 16:39
  • 7
    @haylem nails it. You're not forced to do OOP, you're forced to organize code in classes and methods. And that, I'd say, is a pretty annoying restriction.
    – user7043
    Feb 21, 2011 at 16:48
  • 5
    Gotta love how OOP is the scapegoat for every programmer's woes these days. I'm gung-ho functional these days myself, but the passionate hate of OOP is even more of a blind trend than OOP itself. I highly doubt that most people who rag on OOP lately can even explain its demerits with any confidence. Mar 30, 2011 at 11:04

15 Answers 15

14
+50

Both C# and Java are marked as languages known not for what they enable, but what they disable, in terms of the feature set they use. (C# less so these days with LINQ but that's a whole different can of worms) Both of these languages are designed such that it's more difficult to create bad designs, at the expense of some freedom to the programmer. Generally speaking, object oriented design produces more reusable and maintainable designs than non object oriented design. (Note: I say "generally" here -- some designs are of course more easily expressed using (for example) functional programming primitives) Therefore, OO is the default paradigm supported in these languages.

(Again C# is a bit of an oddball here because it supports functional programming style)

10
  • 3
    "more difficult to create bad designs"? Not enough more difficult to make a difference. Actually, I think they encourage bad designs, by preventing bad designs from doing anything obviously bad (like crashing), the naive programmer never knows that improvement is needed or possible.
    – Ben Voigt
    Mar 29, 2011 at 19:12
  • @Ben: I'm not saying I think Java/C# have the right answer -- I'm saying that's what their design goals were. (I like working in C++ more than those languages, and it has very different design goals) Mar 29, 2011 at 19:51
  • @Ben -- The languages are decidedly strongly typed so that they crash upon compilation on as many obvious errors as possible (e.g. function paths not returning values, switches without breaks etc.). They'll also crash upon array bounds being broken rather than just roll on the way C/C++ does. While there are obviously languages that are even more strict, I have no idea where you get the idea that these languages are designed not to make problems obvious -- because the exact opposite is true. Apr 2, 2011 at 11:47
  • 1
    @Rei: Funny that you mention arrays, which are by design not type-safe in either Java or C#. But I'm not saying that these languages aren't designed to catch some errors that are possible in C++. I'm saying that they are advertised as "safe", "no possibility of memory leaks", etc. and many programmers have bought into these lies and not learned how to deal with critical low-level issues.
    – Ben Voigt
    Apr 2, 2011 at 14:56
  • 2
    @Ben Like I said, there are obviously languages that are more strict (e.g. Haskell), but saying covariance/contravariance makes the language (or even arrays) not type-safe is a polarized overstatement. C# and Java do in many ways encourage beginners, and whether or not beginners should be encouraged is a philosophical question that I don't have an answer for -- but there's a difference between encouraging beginners and encouraging bad designs. Languages are supposed to prevent good programmers from making clumsy mistakes; they're not supposed to weed out bad programmers. That's HR's job. Apr 3, 2011 at 8:46
12

It isn't so much that OOP is enforced, as that an OOP framework is enforced. It's possible to write procedural programs in Java, although it's easier if they're only one file.

The advantage is uniformity. There are several different types of functions and data in C++, and this does cause some problems and confusion sometimes, and at the very least is more to learn. With Java, you've got member functions (class or object based) and similar data, and that's it.

This is intended to make Java easier to read and write, by specializing the language somewhat.

6
  • 3
    If that's the motivation, perhaps the language shouldn't have static methods. What's easier to read, class XyzUtil { static T doStuff(...) { ... } } and then XyzUtil.doStuff or simply T doStuff(...) { ... } and then doStuff()? If you want to write procedural code (and sometimes that's really the best way, and more often than you'd think it's a valid approach), Java etc. only add cruft, not simplicity.
    – user7043
    Feb 21, 2011 at 16:47
  • @delnan: It's not about how easy it is to read a single function. It's about how easy it is to understand your overall design. Feb 21, 2011 at 17:11
  • @Billy: In which case the language is out of play - as already noted, even Java and C# can do little more than enfore classes-based code organization, not decent - let alone sound, OOPy - design.
    – user7043
    Feb 21, 2011 at 17:16
  • 2
    @delnan: You can write garbage code in any language. However, with some language features are easy to shoot yourself in the foot. (I'm not defending the decision, I'm saying that David's answer is correct; that is the thinking behind the language design in that manner. Whether or not you agree with the language designers is a whole different matter.) Feb 21, 2011 at 17:18
  • But if it's under a meaningful package namespace, part of a class with a meaningful name, with a meaningful name for the static class method itself--it can be quite elegant and self-explanatory. It's when you take a look around how badly types and utility classes are designed and organized that you think almost any rubbish can pass, as long as it's legal. Feb 21, 2011 at 17:20
9

Could be "they thought it was a good idea at the time", i.e. having no free functions. 10-15 years ago the development world was excited by "Object Oriented" (just as they all seem to be excited by "Agile" right now).

Even so, I am not sure if every class should derive from Object, but without generics where you need to cast all the time, it does help and it might be the practicality that the VM they built at the time was able to handle it better.

Microsoft's MFC had a concept of CObject too at the top of a big hierarchy.

4
  • 9
    The CLR supports non class methods. (They're not accessible in C# except through delegates, but they're first class in C++/CLI) Feb 21, 2011 at 17:12
  • @ Billy ONeal: Right - in fact the only language shipped with VS that does not support free fuctions is C#. The others (VB, F#, C++/CLI) do. Feb 21, 2011 at 18:11
  • It still is a pretty good idea, it's just not omnipotent.
    – biziclop
    Feb 21, 2011 at 22:14
  • Anything more complex than a hello world benefits from OO design. Jun 9, 2011 at 17:55
6

In my experience, the most horrible examples of crappy code I've seen is written in Java or C#. I've seen some bad stuff in less strict languages, but it's nothing compared to the absolute horrors of staring into the abyss of 1.000.000 lines of copy-pasted static ball-of-mud C# code.

I don't know why that is, but my guess is because it's easier, even possible, to just keep adding more and more (and more...) code in Java/C#, safe in the knowledge that the compiler will tell you when your syntax is wrong. Unfortunately it doesn't tell you when your design is wrong.

I'm not saying Java/C# is bad or anything, quite the opposite. It's just that all this helping, enforcing type-safety makes it possible to mess things up far more than in more flexible, non-enforcing languages.

So I can't really say this "enforcing" policy has improved code quality overall. It has improved the amount of code though, that's for sure.

11
  • 6
    Unfortunately a by-product of Java's commendable aim of simplicity in their design and syntax made it very easy to learn at a level where you can wreak havoc without the tinyest ounce of understanding. Nobody would do such a thing in assembly for example, because you wouldn't get anywhere without understanding the ins and outs of it.
    – biziclop
    Feb 21, 2011 at 22:18
  • 3
    @biziclop: Are you suggesting that there's no such thing as badly written assembly? You can write bad code in any language.
    – Ant
    Feb 22, 2011 at 8:20
  • 2
    no, he (if I understand him correctly) states that it's easier to write bad code in Java that actually compiles and is functionally correct compared to doing the same in Assembler. Thus bad Assembler code is less likely to end up in the maintenance queue, as it never reaches production.
    – jwenting
    Feb 22, 2011 at 9:48
  • 2
    There's lots of poor Java about. But compared to C it is absolute bliss. Mar 29, 2011 at 12:22
  • 6
    Employer: "I have some very poorly written C++ and some very poorly written C#. Which do you want to work on?". No brainer, give me the C# Mar 29, 2011 at 15:09
4

C# 2.0 added support for static classes when it came out 6-7 years ago. That turns a class into a "module" (or "namespace" depending on your choice of jargon) containing nothing but static methods and fields, effectively allowing you to enforce non-OOP style type definition and consumption.

OOP is often encouraged, but it's certainly not enforced. You'd be surprised how much of the .NET libraries are implemented as static classes.

3

A lot of people think that OOP is the best way to write code. They're either right, wrong, or its open for opinion/debate...doesn't matter. Those that wrote Java/C# obviously believe the first.

It's easier to enforce OOP as a coding standard if the language itself imposes it. This is also why languages like Java force you to do other things too, like one public class per file.

They do have somewhat of a point there. It's hard to get people to do things the way you want. Give them too much freedom and they do it their way and hope it makes it through review. If the tools themselves force them into a certain way of doing things then you don't have to argue and/or get team consensus (which everyone promptly ignores anyway).

On the other hand, I never really agreed with anything Java enforced. For one, there are exceptions to every rule and Java simply doesn't provide for that.

3

It isn't enforced, after all, as the saying goes: a real developer can write FORTRAN code in any language.

But I have to admit, I don't understand the gist of the question. Well, why not? There are so many languages out there, so Gosling and his friends set out to create one that is based on classes and objects only (okay, and a few primitive types). The idea wasn't entirely groundbreaking, but they also wanted readability, C-like syntax and solid, abstract foundations.

Every lagnuage represents a trade-off between freedom and strict enforcement of a set of principles that help avoid errors. Assembly gives you total freedom and also every possible opportunity to shoot yourself in the foot. Ada was designed to give you very little freedom but fewer opportunities of self-destruction too. One isn't intrinsically better than the other.

Java is just a language leaning towards the stricter end of the spectrum, stricter than C++ but not plunging into the true depths of strong typisation.

C# is somewhat easier to explain, it was Microsoft's reply to the popularity of Java (and their failed attempts to sneak proprietary classes into their implementation of the applet framework :)).

3

To fulfill the buzzword-compliance requirement.

(This is only partly meant as a joke, but it's true).

These languages are aimed at businesses, and the average decision maker in BigCorporation has no understanding of programming techniques, but he reads everywhere that OOP is the future.

At least, this used to be true 5-15 years ago.

Nowadays, a lot more products are being produced by startups rather than big corporations, so Java and C# ended up losing (in a way). Because they aimed to please the clueless middle manager, the more technical and hackery types of people went on to use different technologies (php, ruby, python, and more recently: node.js).

2
  • It's certainly how it felt at the time with Java. C# on the other hand seemed a legitimate replacement for the old COM system moving to .NET and replacing VB as the "native" language of the system, albeit it was somewhat aimed at being Java-like as Microsoft were prevented from adding their own specifics to Java.
    – CashCow
    Feb 22, 2011 at 10:08
  • 1
    Honestly, if you've looked at the history of Java, it's all about being a great little language. It is clearly a success in many, many domains. Mar 29, 2011 at 12:24
3

C++ was built (originally) on top of C, which is procedural. C++ programs still have a 'main' function as the entry-point of a program, which is a procedural legacy.

JavaScript is object-oriented, but is based on the prototype-and-delegation model rather than a class-and-inheritance model (these models are functionally equivalent and equally valid). The OO framework within JavaScript is implicit. Just because you can write

<script> var i=21*15; </script>

does not mean you are actually using procedural code; under the hood you have implicitly created an anonymous method belonging to the Document object [caveat: I'm guessing based on debugging the DOM; JavaScript experts please correct]

Java and C# were design to be object-oriented using the class-and-inheritance model, hence every program must have a (static) class and Main entry point. Beyond that, though, you are free to be as procedural as you like.

2

Your question isn't why do these languages support OOP so much as why they disallow OOP. In particular, I guess that means why they don't allow bare functions that aren't a member of any class.

It seems like the simplest answer is that supporting that would make those languages more complex (consider that things like namespaces and overload resolution would have to be able to handle bare functions and those features are already complex) in return for little benefit: you can always just do procedural programming using static functions. What real benefit would non-class functions give you?

1
  • Take a look at Python which is way simpler than C#, object-oriented top to bottom, and still allows bare functions and everything (e.g. methods) is first-class. Of course, it's easier to achieve in a fully dynamic language.
    – 9000
    Mar 29, 2011 at 11:00
2

It isn't about "forcing" things. It's merely that some solutions can be expressed purely in OO concepts, so the language provides only OO concepts.

2

This is a wild guess, but one reason might be that it makes IDE magic like IntelliSense easier/more helpful. In C++ every function of the C standard library is in the global namespace. Every C++ standard library class and function is in the std namespace. And many C++ programs I've worked on also put everything in the global namespace (or used using namespace XYZ at the beginning of every file). So if you press Ctrl-Space somewhere in a file, you get a very long list of every global function. In C#, all static functions like Math.Sin or Buffer.BlockCopy are contained in a namespace. So all you get when you press Ctrl-Space are a few classes like Math, Buffer, ...

1
  • C++ intellisense has its problems because of header files which is different from import package in Java and whatever the C# version is, because import package gives you access to the class but does not bring in any other baggage in with it.
    – CashCow
    Feb 22, 2011 at 10:10
1

A language is just an abstraction above the assembly code. The choice of abstraction is simply there to help you solve a problem ( making targeted tasks easier to get right, and certain problems harder to get wrong ).

They had to pick an abstraction. And as I see it ( ignoring all the business reasons ) C# was the conceptual abstraction over C++ which was the abstraction over C except with classes ( OO ). C# simply tried to re-enforce the OO model, and solve problems like memory leaking and abstracting away some of the low level complexities.

If it is not suitable for your problem domain, then simply pick the appropriate language with the best abstraction for you problem domain.

1

As stated by others. It isn't!

If you want to know why it is (or nearly is), then look at Eiffel. It is well worth a look at; you can learn Eiffel quicker than C# or Java.

You will finally understand OO, Design by contract, Inheritance, C# properties, and much more.

0

One point which hasn't been mentioned is that in many garbage-collection-based object-oriented framework, it is absolutely 100% imperative that the system know the whereabouts of every single object reference--not just every object, but every reference as well--at any time when garbage collection may occur; if there is any thread Th in which the system doesn't know the whereabouts of every single object reference and garbage-collection becomes necessary, all other threads must wait for thread Th to reach a point where the system knows where all its object references are.

The above requirement is much stricter than anything which exists for C or C++. In C or C++, one can construct a union which combines an integer numeric type with a pointer, and provided the code keeps track of whether the thing holds an integer or a pointer, it won't matter whether the runtime framework can tell what type the thing is. Such an approach wouldn't work in a garbage-collected language. If interpreting the content of a union as a pointer would reference an object which is being relocated, then it's absolutely imperative that the content of the union be updated to hold the new address if the last thing stored there was a pointer, but it's equally imperative that it be left alone if it's supposed to be holding an integer. There's simply nothing the runtime can do safely if it can't require object-references be stored in storage locations of object-reference type and nowhere else.

3
  • Actually, there are conservative approaches to GC where everything that “looks like” a pointer is considered one. Note that there are working GCs for C++ and similar languages. Furthermore, C# actually allows you to lay out structures in such a way that references are aliased, via StructLayout, so the same applies here. Furthermore, I don’t see how this addresses the (admittedly, misguided) question. Jul 11, 2012 at 10:47
  • @KonradRudolph: A major advantage of using managed garbage-collected storage as the primary persistent storage medium is that allocating things from a contiguous block of free space is much cheaper than allocating from a fragmented collection of free spaces. Such an advantage is only available, however, if every heap block is relocatable. One could allow heap blocks to be relocatable in a non-reference-tracking system by using memory handles rather than pointers; such an approach was used in the 68000-based Macintosh system. I guess a pessimistic GC could work with something like that.
    – supercat
    Jul 11, 2012 at 14:30
  • As for StructLayout, I thought overlapping reference types and value types types was forbidden. Was I mistaken? With regard to answering your question, the requirement that the framework know about all heap object references imposes significant constraints upon the language design which are not present in other languages like "raw" C++; I would aver that many of the "OO-enforcing" characteristics of C# and Java result from those constraints.
    – supercat
    Jul 11, 2012 at 14:38

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