Читайте также:
|
|
JDK 1.5 introduces several extensions to the Java programming language. One of these is the introduction of generics. This tutorial is aimed at introducing you to generics. You may be familiar with similar constructs from other languages, most notably C++ templates. If so, you’ll soon see that there are both similarities and important differences. If you are not familiar with look-a-alike constructs from elsewhere, all the better; you can start afresh, without unlearning any misconceptions.
Generics allow you to abstract over types. The most common examples are container types, such as those in the Collection hierarchy.
Here is a typical usage of that sort:
List myIntList = new LinkedList(); // 1
myIntList.add(new Integer(0)); // 2
Integer x = (Integer) myIntList.iterator().next(); // 3
The cast on line 3 is slightly annoying. Typically, the programmer knows what kind of data has been placed into a particular list. However, the cast is essential. The compiler can only guarantee that an Object will be returned by the iterator. To ensure the assignment to a variable of type Integer is type safe, the cast is required.
Of course, the cast not only introduces clutter. It also introduces the possibility of a run time error, since the programmer might be mistaken. What if programmers could actually express their intent, and mark a list as being
restricted to contain a particular data type? This is the core idea behind generics. Here is a version of the program fragment given above using generics:
List<Integer> myIntList = new LinkedList<Integer>(); // 1’
myIntList.add(new Integer(0)); //2’
Integer x = myIntList.iterator().next(); // 3’
Notice the type declaration for the variable myIntList. It specifies that this is not just an arbitrary List, but a List of Integer, written List<Integer>. We say that List is a generic interface that takes a type parameter - in this case, Integer. We also specify a type parameter when creating the list object. The other thing to pay attention to is that the cast is gone on line 3’. Instead of a cast to Integer on line 3, we have Integer as a type parameter on line 1’. However, there is a very big difference here. The compiler can now check the type correctness of the program at compile-time. When we say that myIntList is declared with type List<Integer>, this tells us something about the variable myIntList, which holds true wherever and whenever it is used, and the compiler will guarantee it.
20) Recursion in the programming language C++.
The process of solving a problem by reducing it into smaller versions of itself is called recursion. This problem solving technique can be a very powerful way to solve certain types of problems that would be very verbose and lengthy using other techniques such as an iterative approach.
When implementing a recursive solution one usually has at least two cases:
For a function/method to be called recursive, it usually has a call to itself within its code in the general case, with a smaller case being passed through.
Direct Recursion – a function that calls itself within its block.
Indirect Recursion – a function that calls another function and eventually returns in the original function.
Infinite Recursion – when the recursive function never returns to the base case but continually calls the general case. This is one of the big pitfalls of recursion, and one should be careful to ensure that the base case will always be met so that the system can exit the call loop.
To design a recursive function one should do the following:
Some problems that can be solved elegantly using recursion are listed below…
· A typical example to illustrate a recursive function is the factorial function (i.e 5!)
· //************************************
// Returns the factorial of a number
//************************************
int fact(int num)
{
if(num <= 0)
return 1; // Base Case
else
return num * fact(num-1); // General Case - also note it calls itself
}
21) This pointer in the programming language C++.
This pointer
This pointer is used as a pointer to the class object instance by the member function. The address of the class instance is passed as an implicit parameter to the member functions. It is a common knowledge that C++ keeps only one copy of each member function and the data members are allocated memory for all of their instances. Various kind of instances of data is maintained by the use of this pointer.
The keyword this identifies a special type of pointer. Suppose that you create an object named x of class A, and class A has a nonstatic member function f(). If you call the function x.f(), the keyword this in the body of f() stores the address of x. You cannot declare the this pointer or make assignments to it.
A static member function does not have a this pointer.
The type of the this pointer for a member function of a class type X, is X* const. If the member function is declared with the const qualifier, the type of this pointer for that member function for class X, is const X* const.
A const this pointer can by used only with const member functions. Data members of the class will be constant within that function.
The function is still able to change the value, but requires a const_cast to do so:
Example
#include <iostream.h> struct X { private: int a; public: void Set_a(int a) { // The 'this' pointer is used to retrieve 'xobj.a' // hidden by the automatic variable 'a' this->a = a;} void Print_a() { cout<< "a = " << a <<endl;}}; int main() { X xobj; int a = 5; xobj.Set_a(a); xobj.Print_a(); return 0;} |
22) Function overloading in the programming language C++.
Function overloading or method overloading is a feature found in various programming languages such as Ada, C++, C#, D, and Java, that allows creating several methods with the same name which differ from each other in the type of the input and the output of the function. It is simply defined as the ability of one function to perform different tasks.
For example, doTask() and doTask(object O) are overloaded methods. To call the latter, an object must be passed as a parameter, whereas the former does not require a parameter, and is called with an empty parameter field. A common error would be to assign a default value to the object in the second method, which would result in an ambiguous call error, as the compiler wouldn't know which of the two methods to use.
Another appropriate example would be a Print(object O) method. In this case one might like the method to be different when printing, for example, text or pictures. The two different methods may be overloaded as Print(text_object T); Print(image_object P). If we write the overloaded print methods for all objects our program will "print", we never have to worry about the type of the object, and the correct function call again, the call is always: Print(something).
Дата добавления: 2015-11-16; просмотров: 72 | Нарушение авторских прав
<== предыдущая страница | | | следующая страница ==> |
Floating-point numbers | | | Continue Statement |