Scope

Named entities

Our programs will always be full of named entities, such as:

  • method names (e.g. main(), getAge()),
  • variable (and field) names (e.g. bob, age),
  • type names (e.g. Person, String, int), etc.

For this topic on scope, we are just going to look at the first two (methods and variables+fields).

Scope of named entities

When we talk about the scope (of a method or variable), we are talking about its “accessibility”.

In other words, from which part(s) of our code can we access that named entity?

  • Something “in scope” may be accessed.
  • Something “not in scope” cannot be accessed.

Consider the following bit of code:

public class Course {
   private String name;
   private int cap;
   private ArrayList<String> students;
   private static int nextID = 0;
   
   public Course(String name, int max) {
      int foo = 23;
      ...   
   }
   
   public boolean enroll(String studentID) {
      int bar = 45;
      ...
   }
   
   public static int getNumberOfCourses(boolean onlyActive) {
      String bar = null;
      ...
   }
}


1. If we are inside the Course() constructor, what’s in scope?

Edit

  • All fields:
    • name (instance field)
    • cap (instance field)
    • students (instance field)
    • nextID (static field)
  • All local variables:
    • name (parameter)
    • max (parameter)
    • foo (locally-declared variable)
  • All methods:
    • enroll() (instance method)
    • getNumberOfCourses() (static method)


2. If we are inside the enroll() instance method, what’s in scope?

Edit

  • All fields:
    • name (instance field)
    • cap (instance field)
    • students (instance field)
    • nextID (static field)
  • All local variables:
    • studentID (parameter)
    • bar (the locally-declared variable inside enroll())
  • All methods:
    • enroll() (instance method – i.e. itself for recursion)
    • getNumberOfCourses() (static method)


3. If we are inside the getNumberOfCourses() static method, what’s in scope?

Edit

  • Only static fields:
    • nextID (static field)
  • All local variables:
    • onlyActive (parameter)
    • bar (the locally-declared variable inside getNumberOfCourses())
  • Only static methods:
    • getNumberOfCourses() (static method – i.e. itself for recursion)




Nesting scope

Above we talked about scope across methods/constructors.

But we can also talk about scope within a method/constructor, which is defined by the nested { ... } blocks:


public class Course {
   private String name;
   private int cap;
   private ArrayList<String> students;
   ...
   
   public boolean enroll(String studentID) {
      int bar = 45;
      String name = "Local variable for fun";
      
      // Check there's space
      if (students.size() < cap) {
         
         // Print current students     
         for (String id: students) {
            System.out.println(id);
         }
         
         // Check not already enrolled
         for (String id: students) {
            if (studentID.equals(id)) {
               boolean result = false;
               return result;
            }
         }
         
         // Not already enrolled in the course, so enroll them
         students.add(studentID);
         
         boolean result = true;
         return result;
      } else {
      
         // No space in course
         boolean result = false;
         return result;
      }
   }
   
   ...
}


We can visualise the nesting of our scopes (for the enroll() method) as follows:

Edit

To keep the diagram tidy, not all possible arrows are drawn. But in a nutshell, the general rules are:

Edit All fields may be accessed from anywhere in any of the method/constructor scopes.

Edit All fields may be accessed from anywhere in any of the nested block scopes.

Edit Parameters may be accessed from anywhere in respective method/constructor scope (including nested block scopes).

Edit Local variables may be accessed after they have been declared.

Edit Local variables cannot be accessed before they have been declared.

Edit Local variables cannot be accessed from an outer scope.

Edit Local variables cannot be accessed between block scopes that are not nested.

Edit Local variables and parameters cannot be accessed from another method.

Of course, the usual rules concerning static fields/methods also need to be observed.




Relationships

So far we have seen classes as defining “standalone” objects.

However, in non-trivial software programs, objects (of different types) will often need to interact with each other.

A class in OOP is really just a building block.

  • We create structures, using classes as building block units.
  • OOP allows us to express the relationship among those units.

If we have classes A and B, three relationships might be:

Edit




Association

Edit

As ■ so ■ ci ■ ate

  1. To connect or involve with a cause, group, or partner.
  2. Joined with another and having equal status.


Association is a weak relationship between objects:

  1. Neither object “owns” the other object.
  2. The two objects have their own lifecycle.

For example, students and teachers exist independently of each other. They may be associated together, but neither owns the other:

Edit

public class Teacher {
   private ArrayList<Student> studentsTeaching;
   ...
}

public class Student {
   private Teacher taughtBy;
   ...
}

Association is a weak relationship, defining an “is using” relationship.

We express associations between classes as a phrase, for example here are two associations:

  • A Student is taught by a Teacher.
  • A Teacher teaches many Students.




Aggregation

Edit

Ag ■ gre ■ gate

  1. To gather into a mass.
  2. A mixture of minerals separable by mechanical means.


Aggregation represents the relationship between a whole and a part:

  1. One object (the whole) “owns” the other object (the part).
  2. However, the two objects still have their own lifecycle.

For example, teachers and departments exist independently of each other (they have their own lifecycle). However, Department (the whole) gathers/collects/consists of Teachers (the part):

Edit

public class Department {
   private ArrayList<Teacher> lecturers;
   ...
}

public class Teacher {
   private Department worksFor;
   ...
}

We think of it as “has a” relationship:

  • A Department “has a” number of Teachers (aggregation).
  • A Teacher “works for” a Department (simple association).




Composition

Edit

Com ■ pos ■ ite

  1. Made up of distinct components; compound.
  2. Combining distinct elements to form a whole.


Composition is a strong aggregation, where there is a “death” relationship between the whole and part.

  1. One object (the whole) “owns” the other object (the part).
  2. The whole’s lifecycle determines that of the part.

For example, if the university ceased to exist, then so would the departments within it:

Edit

public class University {
   ArrayList<Department> departments;
   ...
}

We think of it as defining a “part of” relationship:

  • A Department is “part of” a University.
  • A Petal is “part of” a Flower.




Edit     Remember that OOP modeling is an art!

Which of the following works better?

  • Car has a Engine” [sic] (aggregation)
    • Implies that an engine can be salvaged when its car is decommissioned.
  • Engine is part of a Car” (composition)
    • Implies that an engine will no longer exist when its car is decommissioned.

There’s no science to it!