I know that this question could go in the OO section, but its really a simple question. I am trying to see if I am on the right track with how Java and OO works. So I thought I'd post my view of how it works and see if you guys can tell me where I am going wrong. I know classes are "blueprints" for objects, but can objects be seen as large methods. By this I mean you pass in some values into an object, the object carries out some work on the values submitted, either by calling the one or many methods defined in the object. Then the object either returns a value to the calling object or it runs some other action. Is this similar to how a large method works. Also polymorphism, I know that instead of re-writing methods or functions (what is the best term, methods or functions) you can import another class that has a method that you want to use and then, if the access is ok, you can use or expand that method. I am sort of correct, or going totally the wrong way?
The correct term is method. You don't get it right, object aren't just large methods. They hold data, and encapsulate them. You want to read Thinking in Java, you can get it for free at the site of the author, Bruce Eckel. The first chapter is small and nice and explains the basics very well, at least more nicely than I can. ;-)
I know classes are "blueprints" for objects, but can objects be seen as large methods. By this I mean you pass in some values into an object, the object carries out some work on the values submitted, either by calling the one or many methods defined in the object. Then the object either returns a value to the calling object or it runs some other action. There is a well known trap where some programmers with a procedural programming background fall when they move to OO languages. The trap is to use objects to perform procedures. Yes, you can use objects as units of work, but then all the benefits of OOP (such as reusability and extendibility) may be lost. The OOP topic is rather large, but it all comes down to transparent and easily understood design where things can be changed easily and cost-effectively. How do you do that? Here are some well known guidelines:
Cohesiveness. Design your objects so that they have a narrow and well defined set of responsibilities. That means that if you have a class BankAccount, the method connectToDatabase() probably doesn't belong there. At the risk of oversimplifying and ignoring the depth of the concept, you can think of objects as the nouns in your business specification. Extract all the nouns, and you have your initial shot at your design.
Loose coupling. That means minimizing the dependencies between the classes. The fewer dependencies, the easier it is to reuse the class somewhere in your program. This is accomplished by tight encapsulation and generic interface. Tight encapsulation means that you want to hide the internal workings of the class so that it can change without affecting other classes and the code where this object is used. Generic interface means the public assess methods that are as vague as possible in their declaration, so that the implementation of that interface can be easily swapped. This is the essense of polymorphism, and I probably didn't explained it clearly enough, -- for that, you can to read a book or two.
It's unlikely that a topic as broad and complex as OOP can be understood from reading the responses from this thread alone, but I hope that you can use some ideas that I identified above as your research items.
Stephen, You've got some good ideas, but it's best we try to clarify some things before we get too far along. An object is really quite different from a method. A method does something. A class is really a container - it contains both methods and data. In theory, a class is designed to replicate some "real world" entity. For example, you might have a Student class that would encapsulate the data and behaviors of a real life student. That student class would probably contain instance members such as name and GPA. Meanwhile, it might also contain behaviors (methods) such as eat, sleep, and goToClass. You see, a method is just a small piece of a class. Saying that a class is like a method because it does something is similar to saying that a car is like a tire because they both move down the road. One piece is simply a building-block of another. Try not to get too caught up in polymorphism until you've got the basic ideas down. However, here's the bit about polymorphism (I'll use an example from my college days). A key point to remember when dealing with inheritance is the notion of the "is a" relationship. Any subclass "is a" type of the superclass. For my example, we made a little video game that had various bots moving about the screen - each type of bot could move differently. In order to implement this, we had an abstract Bot class and a number of subclasses of that class. In such a scenario, we might have 3 subclasses - a LinearBot, a SinusoidalBot, and a BouncingBot. All of those classes extend Bot so each one of them "is a" type of Bot - a BouncingBot "is a" Bot and a LinearBot "is a" Bot. Here's a quick example of what the code behind these might look like:
Now, the real beauty of polymorphism comes from the knowledge of the "is a" relationship. Because any subclass of Bot "is a" bot, that means you can safely use an instance of a subclass of Bot anywhere a Bot object is expected. For example, this is perfectly legal:
b is a reference variable of type Bot. However, LinearBot "is a" Bot so it is safe to use such an object in its place. The great thing about polymorphism is that we don't have to worry about what type of Bot we really have - rather, we let Java do that work for us. For this project, we produced random bots and then made them all move in their own fashion by doing something like this:
In this case, we use the createNewRandomBot() method to generate a new instance of one of our Bot subclasses, such as LinearBot or BouncingBot. When we're done with that first loop, we have an array of 10 objects - all of which are subclasses of Bot, but we don't know exactly what any of them are - we only know that they are subclasses of Bot. So, when it comes time to make our bots move, we can use polymorphism. We simply grab each object from the array and invoke the move method. Java will determine what type of object we really have (whether that is a BouncingBot, a SinusoidalBot, or a LinearBot) and invoke the proper move method. For example, if the first object in the array is a LinearBot, Java will invoke LinearBot.move() and if the second object is a BouncingBot, Java will invoke BouncingBot.move() - all of this is done automatically. That's the power of polymorphism. I realize that this was a rather drawn out explanation - I hope it helped. Corey
One of my favorite images from an intro to OO book was an object looking like a donut, a ring around a center. The public methods, the things you can see from the outside, are the ring. The data, nicely hidden and protected is the center. The best objects are data plus behavior, and good ones won't let you get your mits on their data. They control access to the data and provide all the behavior you could ever need on the data. It is certainly possible to make an object that is all methods and no data. As mentioned before, that sets you on the path to missing object goodness entirely and doing procedural programming in Java, but you will find "utility" type objects done this way. It's also possible to make an object that is just a data holder with no behavior. We try to use these only in specific situations to transport data from one place to another, like between a database and a richer object model. One reason I've seen people fail in learning objects was instructors who started out saying "everything you ever learned about procedural programming is WRONG and I will now show you the only good, true and right way to do anything." They were jerks and some of my peers just stopped listening to them and gave up. The OO people didn't invent "goodness" but OO is one neat way to get there. Don't give up. This is great fun! Come back and ask about anything!
A good question is never answered. It is not a bolt to be tightened into place but a seed to be planted and to bear more seed toward the hope of greening the landscape of the idea. John Ciardi
You've gotten a lot of good feedback on your question so far, I'd heed all the warnings other posters have already written about the difference between methods and objects. I'll even make my own contribution. A method is simply a sequence of steps that are carried out, usually on data that is passed into the method (or worse, on globally accessible data). An object is really a different kind of animal. An object does have methods, but if that's all your objects are, collections of methods, you're basically doing procedural programming. The really important parts of an object are its state and its structure--that is, the state of all the data comprising the object and the relationships between that data. The methods are really of secondary importance. For instance, here's a few examples that will illustrate the difference between POP (procedural-oriented programming) and OOP (object-oriented programming). In OOP, I can create an object that is immutable...that is, it represents a certain state that is unalterable by any other code in the entire system. For instance, a String in Java is like this. If I create a String:
the object that s references will always be "hello". The reference itself, s, may at some point be reassigned to point to a different object altogether:
But that does not alter the "hello" String that t now points to. You cannot do this in POP, and it's one of many things that allows more power and flexibility with OOP. If I'm writing a software application, that means I'm trying to provide some solutions to end users over some problem space, or problem domain. By using OOP, I can set up a correspondence in my software application with the state of things in the problem domain. For example, I might decide I want to write a contact list, like Outlook has. I can write a Company class that represents a company in the real world, and every instance represents a specific company. When a company gets put in the contact list, I create a new Company instance with that company's information. If that company goes out of business or the user removes it from the list, that instance gets destroyed. The state of the software application mirrors the users view of the world--for the user, a company doesn't exist as far as the contact list is concerned once it's removed. Now think about the kind of information that might be useful to keep about a company in your Company objects. A name, a location, etc. Can a company change its location? Sure, it can move. Does this mean that the company was destroyed and reborn? No, it simply means it changed its address. So if I were writing this Company class, I'd make sure that it had a setLocation(Address) method I could use to set the location of that company at any time. Now I need to write an Address class to keep that information. It should have a bunch of Strings: city, street, zip, state, etc. What about an address object? Can it change it street? Does this make sense? No, it doesn't...for this application, Address objects should be immutable. If a construction crew comes and tears up a road, the addresses along that road no longer exist, hence the objects that correspond to those addresses in our system should be destroyed. But there's no case where it would make sense to allow users to change the street of a previously valid address. So, I hope that kind of gives you a way of thinking about OOP. OOP allows you to set up a correspondence between the real world you're trying to model and your software application. This makes for a natural approach to solving problems specifically because each object has total control over its information, and you have total control over how that information is structured (for instance, a mutable Company object "has-a" immutable Address object). If you get these relationships right and you don't overcomplicate your design with things that are unnecessary to the problem domain that your application addresses, you'll find it very natural and easy to keep adding functionality to the software as the product evolves. If you get these elemental pieces wrong, though, you'll find it's no better, and often more complicated to solve the same problem than if you'd used POP. So you really have to learn and understand the basics of OOP to leverage its full power. Another characteristic of OOP that you should be aware of is this: in POP, functions are not associated with any particular data in general. If I write a function that takes an int as an argument, does something to it, and returns it, that function doesn't care which int gets passed to it, as long as it's an int it'll do its thing. In OOP, you should find yourself writing a lot of methods that care about the specific int they're operating on. In other words, if I write my Company object, and that object contains an Address object, I might have a method on Company that operates on that data. But it will not take as an argument an Address, because I don't want it to operate on just any old Address object...I want it to operate on the one contained by this particular Company instance, and not some other company's address. Here's the source for these two example classes since I've talked about them so much:
Notice that the setters on Address are all private--that means no other class can call those methods, and only Address instances control their private data. Once you instantiate an Address object:
That object has those values forever--they cannot be changed. Furthermore, only the non-private methods defined on the Address class can be called on an Address object's data. In POP, any data can be passed to any method, or any method can operate on any data it chooses, at any time. There are no restrictions, which means there's no way to control things such that the correspondence between the way things behave in your app mirrors how they unfold in reality. That's a quick primer on the most important differences between POP and OOP as I see them. sev
Joined: Mar 18, 2002
Thanks for all the great responses guys, but the problem I seem to get when trying to think of how to write a program using OO is that I can't seem to translate what the program should do into Objects. For example I am working on a coursework project, which I have discussed in another thread http://www.coderanch.com/t/98835/patterns/project-design This program is a login screen that checks a submitted username and password. Now when I originally read the project spec, I thought "OK, got to create a login screen, submit the username and password to another object that checks the submitted details and returns true or false depending on the correct details submitted". I so easily slip into the procedural way of working, Stan you said it best that I use objects to write procedural code. So how do you get a project spec and then translate that into objects that represent real-world things? A login screen to me in not a real world thing, a door is yes, but a login screen. (Objects make my head hurt)
Originally posted by Stephen Adams: Thanks for all the great responses guys, but the problem I seem to get when trying to think of how to write a program using OO is that I can't seem to translate what the program should do into Objects.
Yeah, I remember when I first stepped into OO programming and that's exactly how I felt. Just keep thinking about what "things" are in your system - a Login Screen is probably a perfect example of a "thing" that you can then turn into a class. I haven't read your linked thread, but the Login Screen might be one class, perhaps there could be another class to talk to a database in order to authenticate the user, maybe there could be a User class that contains information and operations related to the User. The list just goes on... Just keep at it. Like I said, I remember my first OO program and it just killed me - I just couldn't seem to get it. Then, one weekend, I was in the shower and EUREKA! I suddenly got it - OO programming has been like second nature ever since. Just hang in there. But I'd heed the previous advice and consult the OO forum with some more speicific questions. Corey
Originally posted by Stephen Adams: I so easily slip into the procedural way of working, Stan you said it best that I use objects to write procedural code.
I came to object oriented programming from a procedural background, and here's what did the trick for me - maybe it will do the same for you. In a procedural language, the procedures (functions) do things with data in data structures. In c, for example, you'll often agglomerate some basic data types into a data structure, and have functions that manipulate those data structures:
Now, the trick for me was realizing that 'objects' really have nothing to do with the functions - in fact, they are just glorified data structures. In this example, instead of focusing on the 'add' function, you focus on the 'complex' data structure. So, you'd start turning this example into object oriented code by simply changing the syntax for the data structure:
There, you have an object class! It's not very useful yet, though, without some functions. Instead of writing functions that manipulate objects from the outside, though, you put functions that are associated with the class inside the class:
The biggest advantage of object oriented programming, in my opinion, is that it tends to result in better code organization. Inheritance and polymorphism are also nice, but you can get to that later.
(from another poster): One reason I've seen people fail in learning objects was instructors who started out saying "everything you ever learned about procedural programming is WRONG and I will now show you the only good, true and right way to do anything."
No kidding. I've also seen people who were very good at OO, but terrible at procedural programming; because they didn't understand how to do functional decomposition, their methods were always spaghetti code. In my opinion, one really needs to learn both.
Joined: Mar 18, 2002
OK, thanks for all the replys, but I think I'd better move this to the OO,UML forum, before I'm rounded up and shot !!