Java Syntax
How do you put these ideas together to make software that really works? Let's start with the basics. If you already know programming, especially old-fashioned procedural programming, coding in Java is nothing new. The only real difference here is conceptual. You still need to understand how the code works, be familiar with basic algorithms, and know how to debug. But before you even write a single line of code, you have to start thinking very differently to understand how to design a Java-based application.
NOTE
There are many general examples and publications on the Net and in print that discuss how to design and create Java classes. Subsequent articles in this series will go through the design and implementation of a stock-ordering web service; we'll explore both the internal and external properties of Java and its ability to work with other applications. This article concerns itself solely with a general understanding of Java syntax and how it differs from traditional modular languages.
In Java, a class is a blueprint for objects. Don't even think of writing a Java program until you have a concept of what at least one class should be and what it should do.
Initialization is everything in Java. Remember, we're dealing with creating and defining data objects directly in a computer's memory. We don't even need an "entry" point; that is, the traditional line of code that tells a machine where to find and execute a program loaded into memory, the traditional program declaration, the good old main statement. Java does have a main statement when it's part of a stand-alone application, but it doesn't have to be. As stated before, Java is an interpreted language, and it's up the Java interpreter (called the virtual machine) to determine whether what it's executing is a single loadable program or a series of classes defining a usable object or objects.
Whether you're a complete novice or an old hand at Java programming, you should already be very familiar with the three most important concepts of object-oriented programming:
- Encapsulation
- Polymorphism
- Inheritance
Although these are design concepts rather than actual constructs, they lay down the law for how to create and, more importantly, manage a Java application, no matter how complex or simple. I actually spent years working with Java code, without spending much time fully understanding the impact of these three concepts and just how much power they give the average Java programmer who understands them not just intuitively but in practice. This was a big mistake. By clinging to my old procedural way of thinking, I often concentrated on the methodology rather than on objects.
For example, let's say I'm writing a simple program to collect data from the keyboard and write it to a text file. Working procedurally, I would probably create a program with three distinct modules: one to collect data from the keyboard, one to create/open and write to a text file, and one to check for errors. With this in mind, when translating to Java I invariably would have created three separate classes to do each of these tasks. It wouldn't have dawned on me to simply create a single class (called MyFile) to do all three.
Clinging to old ideas is easy, but it can be just as easy to adopt new ones, once we can clearly see what those new ideas can do for us. Let's look at each of these concepts more carefully.
Encapsulation
Basically, as I've already stated, you define data objects, their properties, and what you can do with them (methods), in one fell swoop. But that's only one level. Encapsulation includes not only the defining of a data object, but who and what can use it, redefine it, add to it, etc. This is unheard-of in the procedural world. If a procedure is defined within a program, it can be used anywhere within that program, providing that it's called correctly. But in the world of Java, since we're dealing with data objects, we might not always know just what program is going to be calling it. Therefore we have to know ahead of time what this object can do in all the possible circumstances for which it can be instantiated.
Polymorphism
This is sometimes the most confusing, but (in my opinion) the most beautiful and powerful of object-oriented concepts. Simply put, within a class, a variable or method defined within that class can have more than one definition.
Huh?
It's hard to grasp how important this is when explaining it with English. So let's try computer science terms. Since objects are simply data structures in memory, the variables and methods associated with that object are also defined as data structures in memory. In fact, the object declaration becomes a big "pointer" to access the object's attributes. Depending on the context of the call to this object, that pointer can point to more than one definition of an attribute. This is the famous overloading we've all heard so much about. What this adds to a language like Java is quite significant: We have control over context.
In other words, in previous software development, if I was simply writing code, I would only need to know that Create_Object(); was the proper syntax for calling the Create_Object procedure. If that wasn't right, the compiler would let me know. I didn't need to know whether there was anything about the context in which the Create_Object procedure was called that could cause problems. If needed, perhaps the linker would catch the problem, but more often, I wouldn't know about it until something went wrong when the program executed.
But in Java, context is everything. There's a world of difference between Create_Object() and Create_Object(MyObject), although they can be defined within the same class to do the same thingcreate an object. With most procedural languages, simply having two procedures with the same name will cause a compiler error.
Inheritance
Polymorphism begins to release the power of Java; inheritance begins to show us how much fun we can having programming in Java. By defining a simple object, its attributes, and its methods, that same definition can be used again by more-complex objects or simple variations of that object, or entirely new objects with new characteristicsand by different programmers, in different places, with different applications.
You say that the concepts are cool, but you're a hardcore programmer and the proof is in the code? Okay. Without going into the details of Java syntax, let's look at programming these concepts in pseudo-code. First, let's define our first object as follows:
Public class <whatever>{ Variable Variable Method() Method() } public static void main(){ <whatever> x = new <whatever> x.variable x.method() }
What this gives us in the first part (the first Public) is a simple object (<whatever>) with two attributes and two methods; that is, two attributes and two procedures that can perform some type of operation on this object. The second part (the second public) is the part of the program that tells us this class is going to be created as a stand-alone application and not within a web browser, for example.
We then create an instance of our object, called x. We can now take a look at a default variable or execute a default method with the dot (.) notation (x.variable name). Once this class is compiled and made accessible through a variety of tools, the <whatever> object can be instantiated and accessed in this way by as many applications as can find it!
By making the conceptual leap from procedural programming thinking to object-oriented thinking, any C programmer can then leap effortlessly to Java by remembering that we're no longer writing "programs," but instead "classes" that any program can use!