CSC/ECE 517 Fall 2010/ch3 4b mt: Difference between revisions
No edit summary |
No edit summary |
||
Line 144: | Line 144: | ||
==== Disadvantages ==== | ==== Disadvantages ==== | ||
==== Single-state storage ==== | |||
One large disadvantages to primitive types are that they are generally capable of only holding a single dimension state. This limitation requires the programmer to use other variables in conjunction if they desire to hold more than one field of data. | One large disadvantages to primitive types are that they are generally capable of only holding a single dimension state. This limitation requires the programmer to use other variables in conjunction if they desire to hold more than one field of data. | ||
==== Refactoring ==== | |||
Since primitive types do not allow you to encapsulate your data, if you ever desire to change the behavior of your program, you are forced to manually check each use of the variable for enforcement. | |||
For example, suppose you have a system designed in Java that maintains an integer value which represents the number of books you have in a library. | |||
<code><pre> | |||
int numBooks; | |||
... | |||
numBooks = 0; | |||
... | |||
numBooks++; | |||
... | |||
numBooks--; | |||
... | |||
</pre></code> | |||
A few days later, you realize that you should probably refactor your system to maintain a log of when this variable updates. You immediately face a problem since, as it is, your code directly manipulates a single-state type integer. Without resorting to a more object-oriented solution, you would have to update each location in the code of where a change takes place in order to establish this bookkeeping (pun intended). | |||
<code><pre> | |||
public static void integerValueChanged(){ | |||
// records that the value has been changed | |||
... | |||
} | |||
public static void main(String[]args){ | |||
int numBooks; | |||
... | |||
numBooks = 0; | |||
integerValueChanged(); | |||
... | |||
numBooks++; | |||
integerValueChanged() | |||
... | |||
numBooks--; | |||
integerValueChanged() | |||
... | |||
</pre></code> | |||
<br /> | <br /> |
Revision as of 02:07, 21 October 2010
Types vs Classes
Introduction
It is often that we talk about types, strongly typed, weakly typed, classes. To make it clear, let us look into it clearly. Every programming language has a way to define a variable. A variable is a named address location which stores a particular value.
Types
Time for an analogy? Imagine a variable to be a vacant house. It could have animals, humans, robots, or another smaller house, or whatever you can think of. There has to be a way, from a third party perspective, so as to be cognizant of the kind of things that reside in the house. Types and typing is a concept which realizes this concept. A typed language or a strongly typed language is one where the type of a variable has to be declared so as to avoid any wrong dealings of the value during run time. For example, Java is a strongly typed language. If I need to use two integers for addition, I would explicitly have to mention them as an integer:-
int integer1;
int integer2;
However, we can’t then re-initialize it to any other type in its defined scope.
integer1 = “Hello World”; // cannot map an int to a String
In the case of non-typed languages, say Ruby, or Visual Basic, etc. We don’t need to specify a type.
def variable1;
def variable2;
Now, it could be initialized with anything,
variable1 = 3
as well as
variable1 = “Good morning Vietnam” are allowed.
Classes
A class is a “type” of variable specification. The difference between a class and a regular primitive integer, character, etc is that a class:-
- consists of one or more primitive or non-primitive variables
- is a pre-defined structure
- defines methods which operate on the internal state of the object
The Type of Class is “Class”, just like the Type of integer is “integer” in case of strongly typed languages.
For example, in case of Java:-
“The types of the Java programming language are divided into two categories: primitive types and reference types. The primitive types are the boolean type and the numeric types. The numeric types are the integral types byte, short, int, long, and char, and the floating-point types float and double. The reference types are class types, interface types, and array types. There is also a special null type. An object is a dynamically created instance of a class type or a dynamically created array. The values of a reference type are references to objects. All objects, including arrays, support the methods of class Object . String literals are represented by String objects .” [2]
So, as mentioned before, in Java, there are two “Types”:-
- Primitive Type
- Reference Type
Classes, Interfaces, Arrays are all consolidations of Primitive types, so they just need to “point” to or reference the primitive ones, hence the name.
Types and Classes in Languages
Ruby
Ruby claims to be a strong object oriented language. It is object oriented to the extent that every thing is an object. Primitive datatypes are objects, and we can make use of the object oriented techniques on even the primitives. As mentioned before, Ruby is a dynamic typed language, as the type is bound at compile time. Everything in Ruby has a class. Every class in Ruby is inherited from class Class.
Type in Ruby is well defined as well. Using self inspection (reflection), we can find out whether a name is a Class, or a method. Let us see this in action:-
The first thing that comes to a one’s mind is something like :
5.class #=> Fixnum
"hello".class #=> String
But have you thought of your class as an object? Well that seems odd, but that’s how ruby works:
5.class #=> Fixnum
class Foo;end #=> nil
Foo.class #=> Class
What does the above snippet of code mean exactly? It means 2 things : Foo is a constant and that constant holds(refers to) an object of Class type.
Let us prove that:
Foo = Class.new
(irb):8 warning: already initialized constant Foo
=> Foo
As you can see, we got a warning because we tried to initialize the constant Foo again.
So ,when you define some class ‘Foo’ in ruby, all you are doing is: 1-instantiating an object of type Class. 2-initializing a constant Foo that refers to that created object .
So, when we say “object” ,then we do mean any object; an object of Class type, or any object of any type.[3]
Java
As mentioned before, Java is a strongly typed language. The type of data needs to be declared before using. The types of "types" in Java are :
* Primitive Types:- boolean and numeric. The numeric types are the integral types byte, short, int, long, and char, and the floating-point types float and double. * Reference Types:- class types, interface types and array types. [2]
Java is an object-oriented language, but it does make a clear distinction between the primitive type and Classes. int, float, char etc. are primitives, and the other data types other than the primitives are references. It is an interesting distinction to note, because of the differences in method calling system in different languages. Java makes a distinction in "calling-by-value" when a primitive is passed as a parameter, and "calling-by-reference" when an object is passed. This can be shown
C++
C
Note: purely procedural, however can be simulated by the concept of structs.
Perl
Python
Javascript
Discussion of Issues
Okay, so you're about to write a program and you need to represent data somehow. Should you use a primitive type? What about a class? There are several features that are handed to you with each.
Primitive Types
Advantages
Simplicity
In strongly typed languages, primitive types are ideal for data which doesn't necessarily need to be partitioned into several smaller components. If you are looking to store and represent a simple throw-away integer for looping, for example, there's little reason why one would want to construct a class for this purpose.
Primitive types are also often times coupled with native operations, handed to you by the language. For example, in Java, variables of type int are automatically given operations such as addition, subtraction, multiplication, and so on. These operations work as follows:
- Receive both inputs
- Cast if necessary (for example, from an int to a double)
- Perform calculation
- Return result
It is important to note that the primitive types themselves are left unchanged, and the result is returned from the operation, giving the programmer the ability to place the result elsewhere.
Efficiency
In efficiency-critical applications, primitive types and their operations are oftentimes mapped directly to hardware-supported equivalents, thus operations can be performed very quickly. This style of downgrading the logic to more so the hardware level has been replaced over the years for general applications, since improvements to hardware components have eradicated the once-imperative necessity to program efficiently. Another point of view concerning efficiency could be from development time: if the program one is writing doesn't require complex design, it would be quicker to use the language's built-in types instead of taking the time to design a class to do the same feature.
Disadvantages
Single-state storage
One large disadvantages to primitive types are that they are generally capable of only holding a single dimension state. This limitation requires the programmer to use other variables in conjunction if they desire to hold more than one field of data.
Refactoring
Since primitive types do not allow you to encapsulate your data, if you ever desire to change the behavior of your program, you are forced to manually check each use of the variable for enforcement.
For example, suppose you have a system designed in Java that maintains an integer value which represents the number of books you have in a library.
int numBooks;
...
numBooks = 0;
...
numBooks++;
...
numBooks--;
...
A few days later, you realize that you should probably refactor your system to maintain a log of when this variable updates. You immediately face a problem since, as it is, your code directly manipulates a single-state type integer. Without resorting to a more object-oriented solution, you would have to update each location in the code of where a change takes place in order to establish this bookkeeping (pun intended).
public static void integerValueChanged(){
// records that the value has been changed
...
}
public static void main(String[]args){
int numBooks;
...
numBooks = 0;
integerValueChanged();
...
numBooks++;
integerValueChanged()
...
numBooks--;
integerValueChanged()
...
Class Types
Advantages
Disadvantages
References
[1] http://download.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html
[2] Java:- Types, Values and Variables
http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html
[3] Ruby Reflection ,http://www.khelll.com/blog/ruby/ruby-reflection/