Friday, September 7, 2007

Polymorphism

Polymorphism means that the same thing can exist in two forms. This is an important characteristic of true object oriented design - which means that one could develop good OO design with data abstraction and inheritance, but the real power of object oriented design seems to surface when polymorphism is used.

In programming languages, polymorphism means that some code or operations or objects behave differently in different contexts.
For example, the + (plus) operator in C++:
4 + 5 <-- integer addition 3.14 + 2.0 <-- floating point addition s1 + "bar" <-- string concatenation!
In C++, that type of polymorphism is called overloading.


Polymorphism

  • Literal meaning - many forms
  • OOP meaning
    - Same method (message) but different behavior
    - Object determines which method gets executed
  • Function or Method Overloading
    - Similar message but different behavior
  • Abstract interfaces to class hierarchies
    - Define core data and behavior capabilities of a class family
    - All classes in the family support core capabilities
    - All objects in family respond to core methods (messages)

A classic example is how area is calculated on different shapes. We define an abstact base class shape and derive two classes - rectangle and circle from it. An area() method defined in the base class will have to be implemented differently in rectangle and circle, since it has to be calculated differently.

This is an example of polymorphic behavior, and in C++, this is implemented using virtual member functions. The area() member function is defined virtual in the base class, which signals to the compiler that this member function has to be invoked from the correct derived class at run time. This is indeed a run time decision, and which derived class member function is to be invoked depends on which derived class pointer has been assigned to the base class pointer. This also brings in the concept of late binding (run time binding), since the above association to the area member function can only be done at run time. The compiler will have to insert extra code to do the late binding, which adds in a little runtime overhead.


Types of Polymorphism:
C++ provides three different types of polymorphism.
Virtual functions
Function name overloading
Operator overloading

In addition to the above three types of polymorphism, there exist other kinds of polymorphism:
run-time
compile-time
ad-hoc polymorphism
parametric polymorphism


Other types of polymorphism defined:
run-time:
The run-time polymorphism is implemented with inheritance and virtual functions.
compile-time:
The compile-time polymorphism is implemented with templates.
ad-hoc polymorphism:
If the range of actual types that can be used is finite and the combinations must be individually specified prior to use, this is called ad-hoc polymorphism.
parametric polymorphism:
If all code is written without mention of any specific type and thus can be used transparently with any number of new types it is called parametric polymorphism.

In general, there are two main categories of Polymorphism namely
Ad Hoc Polymorphism
Pure Polymorphism


Overloading concepts fall under the category of Ad Hoc Polymorphism and Virtual methods. Templates or parametric classes fall under the category of Pure Polymorphism.

Persistence

One of the most critical tasks that applications have to perform is to save and restore data. Whether it be a word processing application that saves documents to disk, a utility that remembers its configuration for next time, or a game that sets aside world domination for the night, the ability to store data and later retrieve it is a vital one. Without it, software would be little more effective that the typewriter - users would have to re-type the data to make further modifications once the application exits.

Therefore, an object that has the ability to store and remember values is often said to have persistence. For Example, the ability of your car radio to remember your list of favorite stations is often referred to as persistence.

It also can be defined as the property of an object by which its existence transcends time(i.e., the object continues to exist after its creator ceases to exists) and/or space (i.e., the object's locations moves from the address space in which it was created).

Hierarchy

In computer science's object-oriented programming, the mapped relationships of sub- and superclasses is known as a hierarchy. This can be visualized as an upside-down tree (or perhaps a pyramid), the top of which is known as the root.

The issue is more complicated with languages that support multiple inheritance, where hierarchy can be any directed acyclic graph.

Aggregation or Composition relationships in object-oriented design also form a hierarchy, composition hierarchy.

In object-oriented programming, a class is a template that defines the state and behavior common to objects of a certain kind. A class can be defined in terms of other classes. For example, a truck and a racing car are both examples of a car. Another example is a letter and a digit being both a single character that can be drawn on the screen.

In the latter example, the following terminology is used:


  • The letter class is a subclass of the character class; (alternative names: child class and derived class)

  • The character class is immediate superclass (or parent class) of the letter class;

  • The letter class extends the character class.
The third formulation expresses that a subclass inherits state (instance variables) and behavior (methods) from its superclass(es). Letters and digits share the state (name, font, size, position) and behavior (draw, resize, ...) defined for single characters.

The purpose of a subclass is to extend existing state and behavior: a letter has a case (upper and lower case, say stored in the instance variable letterCase) and methods for changing the case (toUpperCase, toLowerCase) in addition to the state that it already has as a character.

However, a digit does not have a case, so the methods toUpperCase, toLowerCase do not belong on the common level of the Character class. There are methods that are special to the digit class. For instance, a digit may be constructed from an integer value between 0 and 9, and conversely, the integer value of a digit may be the result of say the intValue method.

In graphical terms, the above character example may look as follows:



The classes form a class hierarchy, or inheritance tree, which can be as deep as needed. For example, the letter class can have on its turn the subclasses vowel and consonant.




When a message is sent to an object, it is passed up the inheritance tree starting from the class of the receiving object until a definition is found for the method. This process is called upcasting. For instance, the method toString() is defined in the Object class. So every class automatically has this method.

In graphical terms, the inheritance tree and the message handling may look as follows:



A hierarchy is useful if there are several classes which are fundamentally similar to each other. In C++, a "base class" is a synonym for superclass and"derived class" is a synonym for subclass.


Messaging

"The process by which an object sends data to another object or asks the other object to invoke a method." Also known to some programming languages as interfacing.

The object's interface consists of a set of commands, each command performing a specific action. An object asks another object to perform an action by sending it a message. The requesting (sending) object is referred to as sender and the receiving object is referred to as receiver.




Control is given to the receiving object until it completes the command; control then returns to the sending object.

For example, a School object asks the Student object for its name by sending it a message asking for its name. The receiving Student object returns the name back to the sending object.



A message can also contain information the sending objects needs to pass to the reveiving object, called the argument in the message. A receiving object always returns a value back to the sending object. This returned value may or may not be useful to the sending object.

For example, the School object now wants to change the student's name. It does this by sending the Student object a message to set its name to a new name. The new address is passed as an argument in the message. In this case, the School object does not care about the return value from the message.



It is very common that a message will cause other messages to be sent, either to itself or to other objects, in order to complete its task. This is called sequential operation. Control will not return to the original sending object untill all other messages have been completed.

For example, in the following diagram, Object A sends a message to Object B. For Object B to process that message it sends a message to Object C.Likewise, Object C sends a mesage to Object D. Object D returns to Object C who then returns to Object B who returns to Object A. Control does not return to Object A until all the other messages have completed.



How do receiving objects interpret messages from the senders? How are the messages processed?
Each message has code that associated with it. When an object receives a message, code is excercuted. In other words, these messages determine an object's behavior and the code determines how the object carries out each message. The code that is associated with each message is called a method. The message name is also called the method name due to its close association with the method.
When an object receives a message, it determines what method is being requested and passes control to the method. An object has as many methods as it it takes to perform its designed actions.
Refer to the following diagram, name, name:, address and name:address are method names for the Student object. When the Student object receive the name message, the name message passes control to the name method defined in Student.

Fundamental Concepts - OOP

Object-oriented programming (OOP) is a programming paradigm that uses "objects" and their interactions to design applications and computer programs. It is based on several techniques, including inheritance, modularity, polymorphism, and encapsulation.


Class
A class defines the abstract characteristics of a thing (object), including the thing's characteristics (its attributes, fields or properties) and the thing's behaviors (the things it can do or methods or features). For example, the class Dog would consist of traits shared by all dogs, such as breed and fur color (characteristics), and the ability to bark (behavior). Classes provide modularity and structure in an object-oriented computer program. A class should typically be recognizable to a non-programmer familiar with the problem domain, meaning that the characteristics of the class should make sense in context. Also, the code for a class should be relatively self-contained. Collectively, the properties and methods defined by a class are called members.


Object
A particular instance of a class. The class of Dog defines all possible dogs by listing the characteristics and behaviors they can have; the object Lassie is one particular dog, with particular versions of the characteristics. A Dog has fur; Lassie has brown-and-white fur. In programmer jargon, the object Lassie is an instance of the Dog class. The set of values of the attributes of a particular object is called its state.The object consists of state and the behaviour that's defined in the object's class.


Method
An object's abilities. Lassie, being a Dog, has the ability to bark. So bark() is one of Lassie's methods. She may have other methods as well, for example sit() or eat(). Within the program, using a method should only affect one particular object; all Dogs can bark, but you need one particular dog to do the barking.


Message passing
"The process by which an object sends data to another object or asks the other object to invoke a method." Also known to some programming languages as interfacing


Inheritance
"Subclasses" are more specialized versions of a class, which inherit attributes and behaviors from their parent classes, and can introduce their own.
For example, the class Dog might have sub-classes called Collie, Chihuahua, and GoldenRetriever. In this case, Lassie would be an instance of the Collie subclass. Suppose the Dog class defines a method called bark() and a property called furColor. Each of its sub-classes (Collie, Chihuahua, and GoldenRetriever) will inherit these members, meaning that the programmer only needs to write the code for them once.
Each subclass can alter its inherited traits. For example, the Collie class might specify that the default furColor for a collie is brown-and-white. The Chihuahua subclass might specify that the bark() method produces a high-pitched by default. Subclasses can also add new members. The Chihuahua subclass could add a method called tremble(). So an individual chihuahua instance would use a high-pitched bark() from the Chihuahua subclass, which in turn inherited the usual bark() from Dog. The chihuahua object would also have the tremble() method, but Lassie would not, because she is a Collie, not a Chihuahua. In fact, inheritance is an "is-a" relationship: Lassie is a Collie. A Collie is a Dog. Thus, Lassie inherits the members of both Collies and Dogs.
Multiple inheritance is inheritance from more than one ancestor class, neither of these ancestors being an ancestor of the other. For example, independent classes could define Dogs and Cats, and a Chimera object could be created from these two which inherits all the (multiple) behavior of cats and dogs. This is not always supported, as it can be hard both to implement and to use well.



Encapsulation
Encapsulation conceals the functional details of a class from objects that send messages to it.
For example, the Dog class has a bark() method. The code for the bark() method defines exactly how a bark happens (e.g., by inhale() and then exhale(), at a particular pitch and volume). Timmy, Lassie's friend, however, does not need to know exactly how she barks. Encapsulation is achieved by specifying which classes may use the members of an object. The result is that each object exposes to any class a certain interface — those members accessible to that class. The reason for encapsulation is to prevent clients of an interface from depending on those parts of the implementation that are likely to change in future, thereby allowing those changes to be made more easily, that is, without changes to clients. For example, an interface can ensure that puppies can only be added to an object of the class Dog by code in that class. Members are often specified as public, protected or private, determining whether they are available to all classes, sub-classes or only the defining class. Some languages go further: Java uses the default access modifier to restrict access also to classes in the same package, C# and VB.NET reserve some members to classes in the same assembly using keywords internal (C#) or Friend (VB.NET), and Eiffel and C++ allows one to specify which classes may access any member.



Abstraction
Abstraction is simplifying complex reality by modeling classes appropriate to the problem, and working at the most appropriate level of inheritance for a given aspect of the problem.
For example, Lassie the Dog may be treated as a Dog much of the time, a Collie when necessary to access Collie-specific attributes or behaviors, and as an Animal (perhaps the parent class of Dog) when counting Timmy's pets.Abstraction is also achieved through Composition. For example, a class Car would be made up of an Engine, Gearbox, Steering objects, and many more components. To build the Car class, one does not need to know how the different components work internally, but only how to interface with them, i.e., send messages to them, receive messages from them, and perhaps make the different objects composing the class interact with each other.



Polymorphism
Polymorphism allows you to treat derived class members just like their parent class's members. More precisely, Polymorphism in object-oriented programming is the ability of objects belonging to different data types to respond to method calls of methods of the same name, each one according to an appropriate type-specific behavior. One method, or an operator such as +, -, or *, can be abstractly applied in many different situations. If a Dog is commanded to speak(), this may elicit a Bark. However, if a Pig is commanded to speak(), this may elicit an Oink. They both inherit speak() from Animal, but their derived class methods override the methods of the parent class; this is Overriding Polymorphism. Overloading Polymorphism is the use of one method signature, or one operator such as "+", to perform several different functions depending on the implementation. The "+" operator, for example, may be used to perform integer addition, float addition, list concatenation, or string concatenation. Any two subclasses of Number, such as Integer and Double, are expected to add together properly in an OOP language. The language must therefore overload the concatenation operator, "+", to work this way. This helps improve code readability. How this is implemented varies from language to language, but most OOP languages support at least some level of overloading polymorphism. Many OOP languages also support Parametric Polymorphism, where code is written without mention of any specific type and thus can be used transparently with any number of new types. Pointers are an example of a simple polymorphic routine that can be used with many different types of objects.



Not all of the above concepts are to be found in all object-oriented programming languages, and so object-oriented programming that uses classes is called sometimes class-based programming. In particular, prototype-based programming does not typically use classes. As a result, a significantly different yet analogous terminology is used to define the concepts of object and instance, although there are no objects in these languages.

Tuesday, September 4, 2007

Differences Between C and Java

If you are a C or C++ programmer, you should have found much of the syntax of Java--particularly at the level of operators and statements--to be familiar. Because Java and C are so similar in some ways, it is important for C and C++ programmers to understand where the similarities end. There are a number of important differences between C and Java, which are summarized in the following list:

No preprocessor

Java does not include a preprocessor and does not define any analogs of the #define, #include, and #ifdef directives. Constant definitions are replaced with staticfinal fields in Java. (See the java.lang.Math.PI field for an example.) Macro definitions are not available in Java, but advanced compiler technology and inlining has made them less useful. Java does not require an #include directive because Java has no header files. Java class files contain both the class API and the class implementation, and the compiler reads API information from class files as necessary. Java lacks any form of conditional compilation, but its cross-platform portability means that this feature is very rarely needed.

No global variables

Java defines a very clean namespace. Packages contain classes, classes contain fields and methods, and methods contain local variables. But there are no global variables in Java, and, thus, there is no possibility of namespace collisions among those variables.

Well-defined primitive type sizes

All the primitive types in Java have well-defined sizes. In C, the size of short, int, and long types is platform-dependent, which hampers portability.

No pointers

Java classes and arrays are reference types, and references to objects and arrays are akin to pointers in C. Unlike C pointers, however, references in Java are entirely opaque. There is no way to convert a reference to a primitive type, and a reference cannot be incremented or decremented. There is no address-of operator like &, dereference operator like * or −>, or sizeof operator. Pointers are a notorious source of bugs. Eliminating them simplifies the language and makes Java programs more robust and secure.

Garbage collection

The Java Virtual Machine performs garbage collection so that Java programmers do not have to explicitly manage the memory used by all objects and arrays. This feature eliminates another entire category of common bugs and all but eliminates memory leaks from Java programs.

No goto statement

Java doesn't support a goto statement. Use of goto except in certain well-defined circumstances is regarded as poor programming practice. Java adds exception handling and labeled break and continue statements to the flow-control statements offered by C. These are a good substitute for goto.

Variable declarations anywhere

C requires local variable declarations to be made at the beginning of a method or block, while Java allows them anywhere in a method or block. Many programmers prefer to keep all their variable declarations grouped together at the top of a method, however.

Forward references

The Java compiler is smarter than the C compiler, in that it allows methods to be invoked before they are defined. This eliminates the need to declare functions in a header file before defining them in a program file, as is done in C.

Method overloading

Java programs can define multiple methods with the same name, as long as the methods have different parameter lists.

No struct and union types

Java doesn't support C struct and union types. A Java class can be thought of as an enhanced struct, however.

No enumerated types

Java doesn't support the enum keyword used in C to define types that consist of fixed sets of named values. This is surprising for a strongly typed language like Java, but there are ways to simulate this feature with object constants.

No bitfields

Java doesn't support the (infrequently used) ability of C to specify the number of individual bits occupied by fields of a struct.

No typedef

Java doesn't support the typedef keyword used in C to define aliases for type names. Java's lack of pointers makes its type-naming scheme simpler and more consistent than C's, however, so many of the common uses of typedef are not really necessary in Java.

No method pointers

C allows you to store the address of a function in a variable and pass this function pointer to other functions. You cannot do this with Java methods, but you can often achieve similar results by passing an object that implements a particular interface. Also, a Java method can be represented and invoked through a java.lang.reflect.Method object.

No variable-length argument lists

Java doesn't allow you to define methods such as C's printf() that take a variable number of arguments. Method overloading allows you to simulate C varargs functions for simple cases, but there's no general replacement for this feature.

Differences Between Java and C/C++


  • The Preprocessor
  • Pointers
  • Structures and Unions
  • Functions
  • Multiple Inheritance
  • Strings
  • The goto Statement
  • Operator Overloading
  • Automatic Coercions
  • Variable Arguments
  • Command-Line Arguments

It is no secret that the Java language is highly derived from the C and C++ languages. Because C++ is currently considered the language of choice for professional software developers, it's important to understand what aspects of C++ Java inherits. Of possibly even more importance are what aspects of C++ Java doesn't support. Because Java is an entirely new language, it was possible for the language architects to pick and choose which features from C++ to implement in Java and how.

The focus of this appendix is to point out the differences between Java and C++. If you are a C++ programmer, you will be able to appreciate the differences between Java and C++. Even if you don't have any C++ experience, you can gain some insight into the Java language by understanding what C++ discrepancies it clears up in its implementation. Because C++ backwardly supports C, many of the differences pointed out in this appendix refer to C++, but inherently apply to C as well.

The Preprocessor

All C/C++ compilers implement a stage of compilation known as the preprocessor. The C++ preprocessor basically performs an intelligent search and replace on identifiers that have been declared using the #define or #typedef directives. Although most advocates of C++ discourage the use of the preprocessor, which was inherited from C, it is still widely used by most C++ programmers. Most of the processor definitions in C++ are stored in header files, which complement the actual source code files.

The problem with the preprocessor approach is that it provides an easy way for programmers to inadvertently add unnecessary complexity to a program. What happens is that many programmers using the #define and #typedef directives end up inventing their own sublanguage within the confines of a particular project. This results in other programmers having to go through the header files and sort out all the #define and #typedef information to understand a program, which makes code maintenance and reuse almost impossible. An additional problem with the preprocessor approach is that it is weak when it comes to type checking and validation.

Java does not have a preprocessor. It provides similar functionality (#define, #typedef, and so on) to that provided by the C++ preprocessor, but with far more control. Constant data members are used in place of the #define directive, and class definitions are used in lieu of the #typedef directive. The result is that Java source code is much more consistent and easier to read than C++ source code. Additionally, Java programs don't use header files; the Java compiler builds class definitions directly from the source code files, which contain both class definitions and method implementations.

Pointers

Most developers agree that the misuse of pointers causes the majority of bugs in C/C++ programming. Put simply, when you have pointers, you have the ability to trash memory. C++ programmers regularly use complex pointer arithmetic to create and maintain dynamic data structures. In return, C++ programmers spend a lot of time hunting down complex bugs caused by their complex pointer arithmetic.

The Java language does not support pointers. Java provides similar functionality by making heavy use of references. Java passes all arrays and objects by reference. This approach prevents common errors due to pointer mismanagement. It also makes programming easier in a lot of ways simply because the correct usage of pointers is easily misunderstood by all but the most seasoned programmers.

You may be thinking that the lack of pointers in Java will keep you from being able to implement many data structures, such as dynamic arrays. The reality is that any pointer task can be carried out just as easily and more reliably with objects and arrays of objects. You then benefit from the security provided by the Java runtime system; it performs boundary checking on all array indexing operations.

Structures and Unions

There are three types of complex data types in C++: classes, structures, and unions. Java only implements one of these data types: classes. Java forces programmers to use classes when the functionality of structures and unions is desired. Although this sounds like more work for the programmer, it actually ends up being more consistent, because classes can imitate structures and unions with ease. The Java designers really wanted to keep the language simple, so it only made sense to eliminate aspects of the language that overlapped.

Functions

In C, code is organized into functions, which are global subroutines accessible to a program. C++ added classes and in doing so provided class methods, which are functions that are connected to classes. C++ class methods are very similar to Java class methods. However, because C++ still supports C, there is nothing discouraging C++ programmers from using functions. This results in a mixture of function and method use that makes for confusing programs.

Java has no functions. Being a purer object-oriented language than C++, Java forces programmers to bundle all routines into class methods. There is no limitation imposed by forcing programmers to use methods instead of functions. As a matter of fact, implementing routines as methods encourages programmers to organize code better. Keep in mind that strictly speaking there is nothing wrong with the procedural approach of using functions; it just doesn't mix well with the object-oriented paradigm that defines the core of Java.

Multiple Inheritance

Multiple inheritance is a feature of C++ that allows you to derive a class from multiple parent classes. Although multiple inheritance is indeed powerful, it is complicated to use correctly and causes many problems otherwise. It is also very complicated to implement from the compiler perspective.

Java takes the high road and provides no direct support for multiple inheritance. You can implement functionality similar to multiple inheritance by using interfaces in Java. Java interfaces provide object method descriptions but contain no implementations.

Strings

C and C++ have no built-in support for text strings. The standard technique adopted among C and C++ programmers is that of using null-terminated arrays of characters to represent strings.

In Java, strings are implemented as first class objects (String and StringBuffer), meaning that they are at the core of the Java language. Java's implementation of strings as objects provides several advantages:

  • The manner in which you create strings and access the elements of strings is consistent across all strings on all systems
  • Because the Java string classes are defined as part of the Java language and not part of some extraneous extension, Java strings function predictably every time
  • The Java string classes perform extensive runtime checking, which helps eliminate troublesome runtime errors

The goto Statement

The dreaded goto statement is pretty much a relic these days even in C and C++, but it is technically a legal part of the languages. The goto statement has historically been cited as the cause for messy, impossible to understand, and sometimes even impossible to predict code known as "spaghetti code." The primary usage of the goto statement has merely been as a convenience to substitute not thinking through an alternative, more structured branching technique.

For all these reasons and more, Java does not provide a goto statement. The Java language specifies goto as a keyword, but its usage is not supported. I suppose the Java designers wanted to eliminate the possibility of even using goto as an identifier! Not including goto in the Java language simplifies the language and helps eliminate the option of writing messy code.

Operator Overloading

Operator overloading, which is considered a prominent feature in C++, is not supported in Java. Although roughly the same functionality can be implemented by classes in Java, the convenience of operator overloading is still missing. However, in defense of Java, operator overloading can sometimes get very tricky. No doubt the Java developers decided not to support operator overloading to keep the Java language as simple as possible.

Automatic Coercions

Automatic coercion refers to the implicit casting of data types that sometimes occurs in C and C++. For example, in C++ you can assign a float value to an int variable, which can result in a loss of information. Java does not support C++ style automatic coercions. In Java, if a coercion will result in a loss of data, you must always explicitly cast the data element to the new type.

Variable Arguments

C and C++ let you declare functions, such as printf, that take a variable number of arguments. Although this is a convenient feature, it is impossible for the compiler to thoroughly type check the arguments, which means problems can arise at runtime without you knowing. Again Java takes the high road and doesn't support variable arguments at all.

Command-Line Arguments

The command-line arguments passed from the system into a Java program differ in a couple of ways from the command-line arguments passed into a C++ program. First, the number of parameters passed differs between the two languages. In C and C++, the system passes two arguments to a program: argc and argv. argc specifies the number of arguments stored in argv. argv is a pointer to an array of characters containing the actual arguments. In Java, the system passes a single value to a program: args. args is an array of Strings that contains the command-line arguments. In C and C++, the command-line arguments passed into a program include the name used to invoke the program. This name always appears as the first argument and is rarely ever used. In Java, you already know the name of the program because it is the same name as the class, so there is no need to pass this information as a command-line argument. Therefore, the Java runtime system only passes the arguments following the name that invoked the program.

Abstraction

"An abstraction denotes the essential characteristics of an
object that distinguish it from all other kinds of object and thus
provide crisply defined conceptual boundaries, relative to the
perspective of the viewer."

-- [Booch, 1991]



"[A] simplified description, or specification, of a system that
emphasizes some of the system's details or properties while
suppressing others. A good abstraction is one that emphasizes
details that are significant to the reader or user and suppress
details that are, at least for the moment, immaterial or
diversionary."

-- [Shaw, 1984]


Abstraction, as a process, denotes the extracting of the essential
details aboutan item, or a group of items,while ignoring the
inessential details.

Abstraction, as an entity,
denotes a model, a view, or some other focused representation for
an actual item. Abstraction is most often used as a complexity
mastering technique.


Abstraction
refers to the act of representing essential features
without including the background details or explanations.
Classes use the concept of abstraction and are defined as a
list of abstract attributes.

Example:

An electrician and an interior decorator will look at the same building each in two different ways. The decorator will probably view the building primarily as a series of rooms. However, the electrician will view it as a series of walls and floors. Walls are in both their views, but serve a different purpose, have a different priority, and relate in different ways.

Thus, the "abstraction" used by the decorator may be rooms which are composed/comprised of walls and floors/ceilings. But the electrician's view may have the walls be the primary abstraction, with room information incidental, perhaps only to locate the proper wall when walking around.

Further, in the electrician's view, walls are a complex 3D structure with their own little world inside, while the interior decorator may view them mostly as 2D flat panels. Both have walls in their mental abstractions, but view and relate them differently.





Object Oriented Typing

The concept of type is more or less important in a language, depending on whether the language is strongly or weakly (or not at all) typed.

In strongly typed languages, the compiler prevents you from mixing different kinds of data together. This is limiting, but can be very helpful when you want to avoid putting a string, say, into the floating point value for the altitude of an airplane’s automatic pilot.

In OO languuages, type is a synonym for class, at least as a first cut. In fact, class and type are quite distinct. A more nuanced understanding of type is one of the things that distinguishes a shallow from a deep understanding of OO design and programming.

Type defines the properties and behaviors shared by all objects of the same type (class).

OO languages can run the range of un-typed, weakly typed, or strongly typed.

The advantage of strongly typed languages is that the compiler can detect when an object is being sent a message to which it does not respond. This can prevent run-time errors. The other advantages of strong typing are:

  • earlier detection of errors speeds development
  • better optimized code from compiler
  • no run-time penalty for determining type

The disadvantages of strong typing are:

  • loss of some flexibility
  • more difficult to define collections of heterogenous objects

C++ maintains strong class typing. An object may only be sent a message containing a method that is defined in the object’s class, or in any of the classes that this object inherits from. The compiler checks that you obey this.
Objective C support strong typing, but it also allows for weak typing. A special type, id, can be used for object handles. An id can be a handle to any class of object, thus it has no typing information, and the compiler can’t check if you are sending proper messages. This is done instead at run-time.

Monday, September 3, 2007

Program Execution

The topology of a structure program is inherently different than the topology of an OO program. Modules are nested into a calling tree, as shown below:



By contrast, the topology of an OO program is inherently less ordered. Objects cluster together by those which communicate most frequently. Inter-cluster messages exist, but are less common than intra-cluster messages. Notice how much like a computer network this topology looks.

Object Model

The object model has many facets. Here are the ones you’ll eventually have to understand to be mature OO developers. Note that these aren’t “OO” concepts. There is however a way of thinking about and understanding them in an OO context.

Abstraction, Encapsulation, Identity, Modularity, Hierarchy, Typing, Concurrency, Persistence
This is initially a scary, rather monstrous task. We’ll take them iteratively, in keeping with our OO development methodology.

Saturday, September 1, 2007

Simple C++ Quiz

Computer memory is called RAM because:

[A] It provides rapid access to data

[B] It is mounted on the motherboard

[C] It is measured in megabytes

[D] Its bytes can be addressed in random order (correct answer)

[E] Its chips are mounted in a rectangular array



What is the debugger used for?

[A] Removing comments from the source code

[B] Running and tracing programs in a controlled way (correct answer)

[C] Running diagnostics of hardware components

[D] Removing syntax errors from C++ programs

[E] Removing dust from the computer screen



Which program helps programmers create and modify source code?

[A] Editor (correct answer)

[B] Make

[C] Compiler

[D] Linker

[E] None of the above



Which program converts source code into object modules?

[A] Editor

[B] Make

[C] Compiler (correct answer)

[D] Linker

[E] None of the above



Which program converts object modules into an executable program?

[A] Editor

[B] Make

[C] Compiler

[D] Linker (correct answer)

[E] None of the above



Data files read by a program are read when that program is:

[A] Compiled

[B] Linked

[C] Loaded into RAM

[D] Executed (correct answer)

[E] Run for the first time



The complexity of a program is often measured by:

[A] The number of lines in the source file (correct answer)

[B] The time it took to write it

[C] The time it takes to run

[D] The number of data files it reads

[E] None of the above



How many reserved words are there in C++?

[A] 5-10

[B] 15-20

[C] 25-50 (correct answer)

[D] Over 100

[E] All words that start with a #



True or False: CPU instructions are stored in a special area of computer memory reserved for all programs.

[A] True

[B] False (correct answer)



You are hired to write a gradebook program. What is the first step in developing this program?

[A] Create the exact program specifications (correct answer)

[B] Create the necessary algorithms

[C] Create a "stubs" program to check for global execution flow

[D] Gather all the necessary grades and other input files

[E] Write the main body of the program with function calls for all the major modules



Consider the following statement: (Blank) is the concept of thinking about programming features and using programming features without concern, or knowledge about the implementation of such features.

[A] information hiding (correct answer)

[B] top-down design and step-wise refinement

[C] object oriented programming

[D] data abstraction

[E] encapsulation



A team of programmers works together on a large project. Each individual team member is assigned to create, write, and test a large function. Which of the following is required information for each programmer to complete his/her assigned task?
I: Complete program specifications, including any input/output requiremens
II: Preconditions and postconditions of the assigned function
III: Parameter list of the assigned function that interfaces with the rest of the program

[A] I only

[B] II only

[C] III only

[D] II and III only (correct answer)

[E] I, II, and III



True or False: The char data type is used for variables that hold character strings.

[A] True

[B] False (correct answer)



True or False: The typedef statement is used to define the size of variables of a particular built-in type.

[A] True

[B] False (correct answer)



True or False: The same name can be used for an integer and a double variable in the same function.

[A] True

[B] False (correct answer)



True or False: Each variable must be declared on a separate line.

[A] True

[B] False (correct answer)



All variables must always be declared at the top of the function's body.

[A] True

[B] False (correct answer)



True or False: It is considered a good practice for a beginning programmer to use only global variables.

[A] True

[B] False (correct answer)



True or False: It is acceptable to use the same name for local variables in different functions.

[A] True (correct answer)

[B] False

Quiz: C++ File I/O

1. Which of the following classes handlers file input?
A. ofstream
B. ifstream
C. instream
D. inputfile

2. Which of the following is not a valid ofstream argument?
A. ios::app
B. ios::trunc
C. ios::noreplace
D. ios::create

3. What does ios::ate mean as an argument to ofstream?
A. Open file, but do not create.
B. Open file, create.
C. Open file for read access only.
D. Open file, set the position to the end.

4. How would you output to an open file named a_file?
A. a_file.out("Output");
B. a_file="Output";
C. a_file<<"Output";
D. a_file.printf("Output");

5. What header file contains C++ file I/O instructions?
A. iostream.h
B. fstream.h
C. infstream.h
D. outstream.h

C++ Quiz

Question 1
Can you name the special functions a C++ compiler can create implicitly?

Question 2
What are the two ways to achieve automatic type conversion from type X to type Y?

Question 3
Which of one of these represents an assignment operation?
1. C c1 = c2;
2. c3 = c4;
3. both


Answers


Answer to question 1
The four special functions that may be generated by the compiler are:
1. the default constructor
2. the copy constructor
3. the operator=() function
4. the destructor

Answer to question 2
X can define the member function operator Y()
Y can define the constructor Y(const X&)

Answer to question 3
c3 = c4 is an assignment
C c1 = c2 is a copy-construction