GWU

CS 1111

Introduction to Software Development

GWU Computer Science


Lecture Notes 09: Classes and Object-Oriented Design


Objectives

By the end of this module, you will be able to:




In the last lecture, we discussed how Java handles memory and scope between variables, methods, and fields (variables declared in a class outside of a method). In this lecture, we'll (finally!) go over classes and show how fields are used to represent object state.

Why are classes and objects useful in computation?

Classes, Objects, and Memory Layout

We have been defining lots of classes all semester -- in fact, to be able to run any code in Java, we need a main method inside of some arbitrary class! However, we were never really using classes so far for their intended purpose: to group related information about some user-defined type (the class) in one place, so that we can operate on that data.

So what is a class? What is an object? You can think of a class as the instructions or blueprint for what we want to store:

What are classes?

So, what are objects?

Activity 1: Let's pretend the String class doesn't exist, and write our own version called String1111. How will we store the data?
What methods would we like to create to operate on this data?
How do we create String1111 objects?




Constructors

If a class gives the blueprint to create objects, constructors lay the initial foundation for each object.

Constructors are methods that are invoked when a new object is created that are used to initialize the data of the new object.

String1111 s = new String1111();

new String1111(); invokes the constructor on the newly created object.

The constructor can be overloaded just like any other method:

String1111 s = new String1111(10);

Activity 2: Let's write two constructors for the String1111 class.


Earlier we saw that we don't have to write a constructor to use one that has no arguments; Java gives you this "for free." Such a constructor will assign all fields their default values (or use how these attributes were initialized). If you start to write your own constructor(s) as above, you will lose the default constructor -- Java's expectation is you know what you're doing and need something more specific than the default behavior.




Accessing an object's member methods and variables

As we saw above, methods in a class can be specified, and they operate on an object using the dot notation. If var is a variable referring to an object,

            var.methodName();
      

invokes the methodName method on var's object.

Read this as "we're invoking the methodName method of the var object"

 

When an object is allocated with new, e.g.:

          A var = new A();
      

 
Activity 3: In a main method in another file, let's create some String1111 objects and call methods on them.





public versus private visibility

You might be wondering why bother having getters and setters, when we can access the field directly, as we did above with string1.filledLength? It turns out that, as good software engineers, we actually want to avoid having people write code like this that allows field access directly, for reasons we will see later this semester.

In Java, we can control what code that is outside of a class is able to see/use. For example, because we defined filledLength to be public, this meant that anyone can access the field from the object directly. However, we're going to stop this for now, and you'll see almost all examples set fields to private visibility, which doesn't allow this type of access; this is why we're writing getters and setters. Later, we'll see examples of where it makes sense (and good software engineering sense) to use the public visibility.

Note that, so far, all of our methods have public visibility; this will often be the case. You can also specify private methods, which means only other methods in the same class can call them.

We'll run though some examples in a bit. For now, let's get used to the proper idioim of keeping our fields private, writing getters and setters, and having methods be public.

Activity 4: Let's design and write a class that will store information about Instagram users called InstagramUser.





What about static?

We can now better understand the static keyword, given that we know what a class and objects are now.

The static keyword is used to indicate when a field is meant to be shared amongst all objects of a class, as opposed to each objects having its own values for that field:



An Example with static and non-static variables and methods:

      public class StaticExample {
        private static int staticVar;
        private int objectVar;

        public static void staticSetVar(int val) {
          staticVar = val;
        }
        public static int staticGetVar() {
          return staticVar;
        }

        public void objSetVar(int val) {
          objectVar = val;
        }
        public int objGetVar() {
          return objectVar;
        }
      }
      

      public class TestStaticExample {
        public static void main(String[] args) {
          StaticExample.staticSetVar();
          System.out.println ( StaticExample.staticGetVar() );

          StaticExample ob1 = new StaticExample();
          ob1.objSetVar();
          System.out.println ( ob1.objGetVar() );
        }
      }
      

Visualizing this:






Null Objects

null is a valid value for a variable of any non-primitive type. This includes:



null is simply a reference to nothing; you can think of it as a reference to a "nothing memory address".

      public class NullTest {
          private int n;
          public int getN() {
              return n;
          }
          public static void main(String[] args) {
              NullTest nt = null;
              System.out.println(nt.getN());
          }
      }
      




Next class:

We'll go through some code traces with classes and objects.

Assignments for next lecture:

Look over homework 6, and try it on your own.