1

I am very new Java and have been messing around with a program that essentially prints a random line of characters based on random char values and array manipulation.

I am having a lot of trouble understanding the object-class relationship as my only other programming experience comes from MATLAB. Therefore, I have been treating my program essentially just like I would write a MATLAB program. Everything is done within the main method and other than the creation of the random() in order to utilize rng, I haven't created any other objects. I simply can't see the use for any in my code. Reading and watching explanations on the object-class structure is only helpful to an extent with me because they basically all relate objects to a car model under the class of the car manufacturer or other real-world metaphor. Although this helps me conceptually visualize the purpose of an object, I'm having trouble compartmentalizing my code into the generic class-object structure as it doesn't really follow any hierarchical pattern; It's just a series of switch statements and for/while loops that return a value.

Is it all right that I don't utilize new objects in my code? Maybe I just don't quite understand classes and objects yet. Could someone try to explain the purpose of creating an object other than just for organizing code. (I also created a couple of static methods before the main that I call upon throughout the program. Are these in the right place or do should methods be initialized inside of the main?)

  • While there may be a decent answer for you, I'd suggest you go out into that real-world thing and find yourself a mentor. Just someone who knows OO to discuss some modeling ideas with should help you a ton. – Frank Sep 12 '17 at 6:06
  • 3
    Unfortunately, your question is much too broad for the Stack Exchange Q&A format, since even one possible answer (and there are many) is literally a 1200 page book. – Jörg W Mittag Sep 12 '17 at 6:44
  • 2
  • 2
    If the only programs you are interested in writing are small (let's say less than 100 lines of MATLAB code), then you probably don't really need to change anything. It would probably help, but it may not be worth the effort. If, on the other hand, you want to make larger programs, then the approach you are describing is inadequate regardless of whether you use objects and classes or not. At that point you are getting into software design and architecture and as Jörg W Mittag states, that's a large field. – Derek Elkins Sep 12 '17 at 7:05
2

Should I be creating more objects in Java?

If you can create more useful classes you should. As you do other classes should be getting smaller.

...messing around with a program that essentially prints a random line of characters based on random char values and array manipulation.

Good! Experience is a good teacher. Here's a challenge: separate the code for printing the line and manipulating the array from the code that decides what your source of random is. Can you create code that could draw from a different source of random without the other code needing to change?

I am having a lot of trouble understanding the object-class relationship

Favorite metaphor for this is houses and blueprints. You live in a house but you need a blueprint (house plan) to build a house. A class is a blueprint that defines how to make an object. Classes have names. Objects don't. They have an address that they exist at. We remember that address with a reference.

House blueHouse = new House("Blue");

blueHouse is a reference that points to the object, not to the class used to build it. That class can be used to make another object:

House redHouse = new House("Red");

Same class, different object.

my only other programming experience comes from MATLAB. Therefore, I have been treating my program essentially just like I would write a MATLAB program. Everything is done within the main method

This is called procedural programming. Most peoples first programming experiences center around procedural programming. You start at the beginning, proceed through the middle, and when you get to the end you stop. Nice simple pattern. Unfortunately it means you have to look at every level of detail all mixed together.

I haven't created any other objects. I simply can't see the use for any in my code. Reading and watching explanations on the object-class structure is only helpful to an extent with me because they basically all relate objects to a car model under the class of the car manufacturer or other real-world metaphor. Although this helps me conceptually visualize the purpose of an object, I'm having trouble compartmentalizing my code into the generic class-object structure as it doesn't really follow any hierarchical pattern; It's just a series of switch statements and for/while loops that return a value.

Ugg, the dreaded car model. Car has-a engine, is-a vehicle. Blech.

Lets just start with what we need to get to the store. Well we could walk to the store but I'm lazy. So let there be engine:

Engine engine = new Engine();

Cool that was easy. Now lets look at what we have to play with

  • change oil
  • change transmission fluid
  • charge battery
  • replace fan belt
  • fill wiper fluid
  • fill gas
  • start ignition system
  • steer with rack and pinion

That is, well, a lot. All I want to do is drive to the store. Why am I looking at all that? Because we're at the wrong abstraction. Sure you could slap this engine onto a frame with tires and drive by sitting on the engine block, sticking a poll in the rack and pinion, and tying a shoe string around the throttle. But why? So you can change the oil at 50 miles an hour?

DriverControls dc = new DriverControls(new Engine());
  • start ignition system
  • steer with steering wheel

Now we have everything we did before, it's the same engine, but we only have to look at what we need to do this job. This puts us at the right abstraction.

You might be thinking I've done the same thing the "is-a vehicle" thing would do. Well I have and I haven't. I don't care if the thing I can start and steer is a vehicle or video game. I have a drive-to-the-store routine that needs something to start and steer. I don't care what that something is.

Rather than starting with an idea like a car and figuring out every construct that could have a relationship with it, start with a need. Add something that can fulfill that need.

Is it all right that I don't utilize new objects in my code? Maybe I just don't quite understand classes and objects yet. Could someone try to explain the purpose of creating an object other than just for organizing code.

Organizing code is no small thing. But programming in an object oriented way is more than that. It's meant to let you make a decision in one place. That means when you change your mind you don't have to find 50 places you spread that decision to and change them all.

Understand that you can't just make classes and a bunch of objects and call what your doing object oriented. I can write procedural code that uses tons of objects and classes. Just using them isn't enough. You have to use them correctly.

Tell, don't ask is the idea that you should design your classes to do what they're told. Don't ask them about their state with getters. Just tell them what you want done and count on them to know what to do. This keeps your way of communicating with objects polymorphic.

You can write code that looks like this:

if (pet.getType() == dog) {
  pet.bark();
} else if (pet.getType() == cat) {
  pet.meow();
} else if (pet.getType() == duck) {
  pet.quack()
}

or you can write code that looks like:

pet.speak();

and trust pet to know what to do.

(I also created a couple of static methods before the main that I call upon throughout the program. Are these in the right place or do should methods be initialized inside of the main?)

I avoid static methods. They aren't object oriented. I don't care if I have to create a class with no state (no member variables), I'd rather build a stateless object and call methods on it then use a global like a static method. There are nightmarish situations where this can't be avoided but that doesn't make it right. It's better to let main tell you which actual method you're going to call then to dictate which method you call. To see how that can be done Look up Dependency Injection.

  • The issue is global state and, more generally, ambient authority, not static methods, otherwise you should be dependency injecting +, *, etc. In a capability-safe language, static methods would actually be preferable as they would be unable to rely on any authority (not explicitly provided in parameters) and this fact would be obvious to users of the static method. Your approach is like outlawing spoons because some people use them to free-base crack. The problem isn't the spoon. Given the OP's level of experience, you may want to make it clear that you also mean static (mutable) fields. – Derek Elkins Sep 12 '17 at 10:28
  • @DerekElkins I'm saying Math.abs(a) is as bad as new Math.abs(a). What I prefer is math.abs(a) where something else handed me math. I don't want my business rules dictating the implementation of these methods. I don't want them to know. – candied_orange Sep 12 '17 at 10:48
  • I understand that you intended to dependency inject the object replacing the static method. I'm also completely confident that you don't actually do this in every case, i.e. you do do Math.abs(a). I suspect you do this even in cases where there might be more variety of behavior, like an array or list or dictionary that you use as an intermediate. Dependency injecting these things leads to a dramatic increase in performance overheads, and cognitive and code complexity for something that's almost certainly a YAGNI violation. – Derek Elkins Sep 12 '17 at 11:07
  • @DerekElkins Well yes, you don't do this in every case. You do it in your behavior code. Your construction code is where you reach out and find or build things. You keep these separated so you can change the code in one without changing the code in the other. The exception being known good defaults though defaults must be overridable. Doing this is trivially easy in languages that have named parameters. In languages that don't, like Java, you simulate them with patterns like the Josh Bloch Builder. – candied_orange Sep 12 '17 at 13:20

Your Answer

By clicking "Post Your Answer", you agree to our terms of service, privacy policy and cookie policy

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