Instructional Material: Introduction to Objects
Java is an object-oriented language so it stands to reason that objects are the workhorse construct of the language. We have talked about objects and classes in previous lessons but now its time start our detailed exploration of objects.
An object is a software container that includes state information (variables) and behaviors (methods). Objects are used to model real-world things like cars, people, bank accounts, etc. Joysticks, controllers, Motors, servos, and sensors are all typically going to be objects in robot code.
A class is a prototype or blueprint for an object from which actual object instances are created. You can think of a class as a programmer defined Data Type. Object and class can be used interchangeably and that is ok, but there is a difference. We write a class as source code in a .java file and then use that class definition in another .java file to create one or more instances of the object defined by the class with the new keyword. The basic form of a class definition is:
We will discuss modifiers later, for now we use the word public. This means other classes can access this class. The keyword class is required and the name of the class followed by the class body as a statement block. Here is a simple class definition for a real world object, your dog:
We see the Dog class has state information in the variables breed, name and age. These are also called fields. We have made the fields public so we can access them directly from other code. At this point, we have not created any particular instance of a ‘dog’ object, we have just said “All Dogs will have a breed, name, and age.” The only constraint we have is that the breed and name both have to be strings, and the age has to be an integer.
The new keyword creates a new object instance of the Dog Data Type (class) and puts a reference to that instance into the variable myDog. myDog now points to a Dog object instance, which you can manipulate.
We access the components of the Dog object with the . (dot) notation. We use the myDog variable name followed by a dot and then the name of a Dog class component (field or method) we want to access. So, if we want to use the function bark(), we must state myDog.bark(), as opposed to just bark(). The method bark() is owned by the class Dog, and when writing code that is outside of the class Dog, we must access the method bark() by having a Dog object instance to call it with. With a robot motor, for instance, we would create an instance of the Motor class connecting it to an actual motor, store it in variable motorA and then write motorA.setPower(0.5) to set our motorA object instance to half power.
Note that, while not required, it is considered good programming practice to make all class fields private. This means that fields cannot be directly accessed with the dot notation. In this case, you must provide methods to set and get the values of fields. The reason is to make sure the values of fields are always under the control of the class methods and so the methods can then depend on the values being correct since no outside code can modify them directly. To follow this convention we would rewrite our Dog class like this:
Here we provide methods to give code using our class access to set and get the name and breed fields.
Note that in the setName() method, we used a parameter called name. If we did nothing about this the compiler would not be able to tell the class level field called name from the method parameter called name. The this. keyword allows us to tell the compiler when we are referring to the class level field. You can think of the this. keyword as meaning "class level".
Following that idea, if we have a variable in a method with the same name as a class level field, the variable in the method "hides" the class level field. This means any use of the variable name refers to the method local variable. If we wish to do this and still need to access the class level field, we again use the this. keyword to tell the compiler we mean the class level field.
We also include a constructor method (more later) that allows us to set the dog name when we create an instance with the new keyword. We would use this new Dog class as follows:
Here are the examples on CodingGround (new). Read below before looking at the examples. Add a Cat class with field name and breed and a method called meow() and call it from the main method.
It is a Java convention to have each class is in a separate .java file with the same name as the class. However it is possible to define a class within another class, thus having more than one class in a single file. This is called an inner class. We are only introducing this idea because the new version of CodingGround does not support more than one source file in an example. So in order to have multiple classes in an example, we have to use inner classes. This is a strange limitation as practically all programming languages support breaking projects into multiple source files. The old version of CodingGround allowed multiple files but has quit working.