Object Oriented Programming
- OO is an “extension” of ADT.
- Looking at a single class in isolation is an example of how to apply the principle of ADT (information hiding, etc.)
- In addition to the ADT, OO also adds reuse through inheritance.
- What is the main benefit of / motivation for inheritance?
- Reuse — reuse some an ADT implementation and customize as necessary.
- Subclasses can
- Add data
- Add methods
Override
methods (i.e., modify functionality)
- Class methods/variables
- What is the downside / tradeoff to having inheritance?
- It can be difficult to hide everything
- You may loose some of the interface / implementation separation. (Another way to look at this is that there are more/tighter dependencies between programming units)
- Note: This is one reason to take care not to overuse inheritance.
- The dependencies also are a nightmare to test well.
- Access control (public, private, protected)
- Notice how protected “pokes holes” in the ADT
- Dynamic binding –> Polymorphism
- What is the tradeoff?
- Notice that C++ offers programmers a choice. Most languages do not.
- Single vs. Multiple inheritance
- Issues?
- “diamond” inheritance (Person, Student, Employee, StudentEmployee)
- Designing such a hierarchy effectively is difficult.
- Alternative?
- Issues?
- One common alternative to multiple inheritance is the concept of an Interface (i.e., a list of methods)
- In Java, classes can inherit from one other class, but implement as many interfaces as desired.
- Benefits?
- Limitations?
- Subclasses and subtypes
- “Principle of Substitution”: It works to assign B to a reference of type A.
- B should also have the same behavior as A when using inherited methods
- In this case B is a “subtype” of A
- Not all subclasses are sub-types: B is not a subtype if it overrides one of As public methods.
- “A subtype inherits interfaces and behavior, while a subclass inherits implementation, primarily to promote code re-use”
- “Most static-typed languages that support object-oriented programming are designed so that subclasses are subtypes, unless the programmer specifically designs a subclass that has behavior that differs from that of its parent class.”
- Inheritance usually causes the subclass to implement that parent classes interface.
- What is the primary exception?
- C++ if you choose
private
inheritance.
- C++ if you choose
- What is the primary exception?
- Can we design a language that enforces that a subclass be a “true” subtype when requested?
- Can you have polymorphism without inheritance? If so, explain how.
-
Can you have inheritance without polymorphism?
- Should everything be an object? (Pros / Cons)
- Boxing/unboxing in Java
- Overload vs. override
@Override
in Java.- Notice annotations serve an interesting purpose.
@Override
doesn’t affect running of program, but provides helpful information for the compiler. @Test
in JUnit does affect program running when using reflection.
- How can we use polymorphism in place of lambdas/first-class functions?
- “Function objects”. Objects with a well known method can be used to pass code.
- Java Inner classes (static and non-static)
- Often used to reduce the syntax of creating function objects for button callbacks.
- Can a object of a given class (say
Matrix
) access the private members of other objects of the same class? Why or why not?- Same author. Consequences of that direct access should be clearly known and understood.
- By this same logic, outer classes in Java can access private data of inner classes.
- Think about polymorphism in a static vs. dynamic environment.
- In C++, compiler can build a “dispatch” table for each type. We may not know the type of an object until runtime, but we do have a table ready to go to look up the right method on the fly.
- Scripting languages have to work their way up the hierarchy until they find a method with the desired name.
Ruby / Open classes
- Everything is an object
- Instance variables must be private. Exposing instance variables is done by defining getter/setter methods.
- (Of course there is syntactic sugar to support this.)
- Look at “openness” of classes in JavaScript
- Can add method to an individual object (but not “base” types like String and Number.)
- Notice that trying to add a method to String doesn’t cause an error!
- Can add method to an individual object (but not “base” types like String and Number.)
- Now, look at openness of classes in Ruby.
- Add method to Class by reopening class
- Add method to specific object of class
def objName.new_method
- More orthogonal.
- Show how code that defines a class is just code. You can do “work” inside a class definition.
- In fact, when you run ruby as a script, you are effectively executing code inside the definition of
the class
Object
p self.class
- defining methods “outside” of a class is effectively adding a new method to the private section of the
Object
class. - (define a method, instantiate a new
Object
and call the method. Now, typepublic
and do it again!.) - In some sense you are doing this:
class Object
private
# your script code here
- When you do this:
class Dog
attr_accessor :size
attr_accessor
is a method that runs code that follows a template to create new methods.
$the_name = "size"
class Dog
puts "Name is #{$the_name}"
attr_accessor $the_name.to_sym
end
dog = Dog.new
p dog
dog.size = 19
p dog
- Classes are just an instance of the class
Class
. class Cat
in some sense does something likeCat = Class.new
followed by method calls to add instance data and methods.
Cat = Class.new
Cat.attr_accessor :size
my_cat = Cat.new
my_cat.size = 12
p my_cat