Object-Oriented Programming Concepts
- Introductory Terminology:
- Object: a named model or abstraction drawn from a problem domain. Objects have state.
- State: An object's state is represented by the instance variables associated with the object.
- Instance variables: a unique set of variables that each instance of an object possesses.
- Class: Objects are created from classes. The class describes the kind of object; the objects represent individual instantiations of the class.
- Method: The sole means of communicating with an object; one invokes an object's method.
- Constructor Methods: Method which causes a new instance of an object to come into being. It always has the same name as the class that defines it. Constructor methods never have return types.
- Accessor Methods: Methods that do not modify the state of the object. They report on the current state of the object. These methods always return something - they are never "void" methods.
- Mutator Methods: Methods that have the potential to modify the current state of the object. Depending on the circumstances, a mutator method may or may not be a "void" method.
- All methods, can be described by their signature: a line of code indicating the method's name, its return type, and the required parameters.
- Type: All java variables and values have a type (i.e. domain) associated with them. Some common types are int and string. A variable's type is defined at its declaration. Furthermore, where a declaration occurs in the class definition defines the variable's scope and lifetime.
- Return type: the "type" of the value returned by a non-void method.
- Parameters: All parameters, both formal and actual have a "type" associated with them.
- Class definitions are composed of comments and the definitions of the instance variables and methods. Method definitions are composed of statements. These include variable definition statements, assignment statements, conditional statements, iteration statements, and return statements (for non-void methods). Statements often have expressions within them. (e.g. boolean expression or algebraic statement)
- Variables come in three flavors:
- Instance variables: persistent for the life of the object; accessible from all the object's methods. Used to help represent the state of the object.
- Local (automatic) variables: local to the method/block defined in; disappear at the end of the method. Used to aid in the computation required of the method.
- Parameters (formals): autoinitialized local variables; Java uses "pass by value" A good programming style is to treat all parameters as constant (final) variables.
- Objects:
- Objects are created (constructed) via a call to "new"
- Objects do not have names. One creates references to constructed objects, which in turn do have names. "Variables of class types store references to objects."
- Objects disappear (automatically in Java) when there are no more references to it.
- Scalar vs aggregate variables.
- Scalar variables store only one single value at a time. Aggregate variables store multiple values at a time.
- Often aggregates support iterators. An iterator is an object that facilitates the one-by-one examination of each object in the aggregate/collection.
- Programming Minutae:
- Develop a consistent programming style:
- Capitalize all class names.
- All variables (instance, parameter, and local) names and methods names should not be capitalized
- Constant variables (final) should be in all-caps
- Each non-void method should one and only one return statement. This one return statement should not be inside either a selection or repetition statement.
- Document each method. Include comprehensive statements regarding both preconditions and postconditions, and both what and how a function accomplishes its mission.
- Keep your class files organized: instance variables, constructors, accessor methods, mutator methods, private methods.
- Always name your methods and variables in ways that will aid the human reader.
- Each object should have a "toString" method defined for it. When one attempts to print a (reference to a specific) object, that object's "toString" method is automatically called.
- Use a cast statement: a parenthesized type name that proceeds an expression, when unsure if there is a type mismatch.
- Use a "for" loop when one knows precisely the number of iterations needed; otherwise use a while statement.
- Advanced Concepts:
- Programming Design: How one attacks the solution of a problem is as important as the basic algorithmic notion of one's solution.
- Brute Force - When all else fails...
- Top Down Design - Solve the basic problem statement making many assumptions regarding the function/purpose of helper functions/methods. (i.e. If Java had xx builtin, then this is the solution to the problem.)
- Incremental Improvement - If you can't solve the problem stated, solve an easier version of the problem. ("If you can't solve the problem you want, solve the problem you're with...") Hopefully the solution to the easier (simpler) problem version provides the needed insight to solve a more complicated version of the problem. Hopefully, eventually, you will get all the way to the original problem.
- Loose coupling: classes do not heavily depend upon each other.
- Tight cohesion: each class provides a good model for the object or process it is representing.
- Responsibility-driven design: let each class take responsibility for maintaining, reporting on, and updating its own state.
- Recursion - Don't forget that often times the solution to a complex problem can be stated as the solution to a sub-problem with some additional work. (e.g. Factorial, Merge sort, binary search, etc)
- Safe Computing:
- Pre and Postconditions: know them and fully document them!
- Insure that all pre and postconditions are met: use if statements (and possibly indicative return values), or use the "assert" statement.
- "Throwing" an instance of an unchecked exception: personalized assert statements. (e.g. NullPointerException, IllegalArguementException, etc.)
- Try blocks to protect code fragments along with "Catch" blocks to gracefully handle/recover from thrown checked exceptions.
- Data Structures: Data structures are the scalar and aggregate variables/structures that hold values.
- Scalar variables - single values of a specified type
- Plain ole' arrays - ordered, homogeneous fixed size aggregate
- Arraylists - ordered, variable sized hetergeneous (Object) aggregate. All values are contiguous in the collection (i.e. no holes)
- Sets (Hashset) - unordered, variable sized hetergeneous (Object) aggregate that prevents duplicates
- Maps (Hashmap) - unordered, variable sized hetergeneous (Object) aggregate that associates another object with each entry. Duplicates are not allowed.
- Stack (Last In First Out) - list oriented abstract data type. Supports push, pop, isEmpty, and top.
- Queue (First In First Out) - list oriented abstract data type. Supports enqueue, dequeue, isEmpty, and first.
- Inheritance - the development of classes as the extension of (previously defined) other classes. The primary benefit is the economy of scale this technique offers. It prevents the need to define the same aspect of state (and methods that maintain it) in multiple places.
- Polymorphism ("Many States") - An important OO technique (which makes use of responsibility driven design) that allows one to work with different subclasses of a common --possibly abstract-- superclass in such a way so that the code need not be aware which subclass it is dealing with at the moment. Programming without a proliferation of selection (if) statements.