Jump to content

Abstract type

From Wikipedia, the free encyclopedia

This is an old revision of this page, as edited by AshitoshAlwani (talk | contribs) at 06:31, 19 September 2011. The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.

This article discusses types with no direct members; see also Abstract data type.

In programming languages, an abstract type is a type in a nominative type system which is declared by the programmer.The word abstract means to hide data .Abstract data types gives just information and implementation is not present there. It may or may not include abstract methods or properties[1] that contains members which are also shared members of some declared subtype. In many object oriented programming languages, abstract types are known as abstract base classes, interfaces, traits, mixins, flavors, or roles. Note that these names refer to different language constructs which are (or may be) used to implement abstract types.

Two overriding characteristics of abstract classes is that their use is a design issue in keeping with the best object oriented programming practices, and by their nature are unfinished.

User Defined Types

In the early days of computing, a programming language came with built-in types (such as integers, booleans, strings, etc.) and built-in procedures, eg. for input and output. Users could define their own procedures: that’s how large programs were built. A major advance in software development was the idea of abstract types: one that could design a programming language to allow user-defined types too. This idea came out of the work of many researchers, notably Dahl, the inventor of the Simula language, Hoare(who developed many of the techniques that we currently use to reason about abstract types), Parnas (who coined the term ‘information hiding’ and first articulated the idea of organizing program modules around the secrets they encapsulated), and at MIT, Barbara Liskov and John Guttag, who did seminal work in the specification of abstract types, and in programming language support for them.

The key idea of data abstraction is that a type is characterized by the operations you can perform on it. A number is something you can add and multiply, a string is something you can concatenate and take substrings out of, a boolean is something you can negate,and so on. Users could already define their own types in early programming languages: one could create a record type date, for example, with integer fields for day, month and year. But what made abstract types new and different was the focus on operations the user of the type would not need to worry about how its values were actually stored, in the same way that a programmer can ignore how the compiler actually stores integers. All that matters is the operations.

Classifying Types and Operations

Types, whether built-in or user-defined, can be classified as mutable or immutable. The objects of a mutable type can be changed: that is, they provide operations which when executed cause the results of other operations on the same object to give different results. So Vector is mutable, because you can call addElement and observe the change with the size operation. But String is immutable, because its operations create new string objects rather than changing existing ones. Sometimes a type will be provided in two forms, a mutable and an immutable form. StringBuffer, for example, is a mutable version of String (although the two are certainly not the same Java type, and are not interchangeable). Immutable types are generally easier to reason about. Aliasing is not an issue, since sharing cannot be observed. And sometimes using immutable types is more efficient, because more sharing is possible. But many problems are more naturally expressed using mutable types, and when local changes are needed to large structures, they tend to be more efficient.

Operations of Abstract Types

The operations of an abstract type are classified as follows:

  • Constructors create new objects of the type. A constructor may take an object as an

argument, but not an object of the type being constructed.

Example

import java.util.GregorianCalendar;

import com.imperim.splitter.model.Student;

public class Runner {

	public static void main(String[] args) {

		int year = 1992;
		int month = 9;
		int day = 13;

		int studentNumber = 111003066;
		String firstName = "Ashitosh";
		String lastName = "Alwani";
		
		GregorianCalendar dateOfBirth = new GregorianCalendar(year, month, day);
		
		Student student = new Student(studentNumber, firstName, lastName, 
                               gender, dateOfBirth);// This is valid
                Student s2 = new Student(student); /*This is invalid because constructor cannot 
                                                    take an object of the type being constructed*/
		student.printDetails();

	}

}
  • Producers create new objects from old objects. The concat method of String, for example, is a producer: it takes two strings and produces a new one representing their concatenation.

Example

public class Test {
   public static void main(String args[]) {
      String s = "I am a student of";
      s = s.concat(" College of Engineering, Pune. ");
      System.out.println(s);
   }
}

Output:

I am a student of College of Engineering, Pune. 
  • Mutators change objects. The addElement method of Vector, for example, mutates a vector by adding an element to its high end.

Example

The following example creates a Vector object and appends three elements to it.

import java.util.*;

public class Program {
    public static void main(String[] args) {
        // Create a Vector and add three elements to it.
        Vector v = new Vector();
        v.addElement("One");
        v.addElement("Two");
        v.addElement("Three");

        // Display the contents of the Vector.
        Enumeration vEnum = v.elements();
        while (vEnum.hasMoreElements())
        {
            System.out.println(vEnum.nextElement());
        }
    }
}

Output:

One
Two
Three
  • Observers take objects of the abstract type and return objects of a different type. The size method of Vector, for example, returns an integer.

Example

The following example shows how to determine the size of a Vector.

import java.util.*;

public class Program {
    public static void main(String[] args) {
        // Create a LinkedList and add three elements to it.
        LinkedList ll = new LinkedList();
        ll.add("A");
        ll.add("B");
        ll.add("C");

        // Create a Vector containing the same elements as the
        // LinkedList and more.
        Vector v = new Vector();
        v.add("A");
        v.add("B");
        v.add("C");
        v.add("D");
        v.add("E");

        // Retain only those elements found in the LinkedList.
        v.retainAll(ll);

        // Display the size of the Vector.
        System.out.println("size = " + v.size());
    }
}

Output:

size = 3

Designing An Abstract Type

Designing an abstract type involves choosing good operations and determining how they should behave.

  • It should contain few simple operations that can be combined in powerful ways than lots of complex operations.
  • Each operation should have a well-defined purpose, and should have a coherent behavior rather than a panoply of special cases.
  • The set of operations should be adequate; there must be enough to do the kinds of computations clients are likely to want to do. A good test is to check that every property of an object of the type can be extracted. For example, if there were no get operation, one would not be able to find out what the elements of the list are. Basic information should not be inordinately difficult to obtain. The size method is not strictly necessary, because we could apply get on increasing indices, but this is inefficient and inconvenient.
  • The type may be generic: a list or a set, or a graph. Or it may be domain-specific: a street map, an employee database, a phone book, etc. But it should not mix generic and domain-specific features.


Signifying abstract types

Abstract classes can be created, signified, or simulated in several ways:

  • By use of the explicit keyword abstract in the class definition, as in Java, D or C#.
  • By including, in the class definition, one or more methods (called pure virtual functions in C++), which the class is declared to accept as part of its protocol, but for which no implementation is provided.
  • By inheriting from an abstract type, and not overriding all missing features necessary to complete the class definition.
  • In many dynamically typed languages such as Smalltalk, any class which sends a particular method to this, but doesn't implement that method, can be considered abstract. (However, in many such languages, the error is not detected until the class is used, and the message returns results in an exception error message such as "does Not Understand").

Example: abstract class demo { abstract void sum(int x,int y); }


Types of abstract types

Abstract methods

[2]

*An abstract method is a method that is declared without an implementation (without braces, and followed by a semicolon), like this:

   abstract void swap(int var1, int var2);

Abstract class

  • abstract base classes are classes either explicitly declared to be abstract, or which contain abstract (unimplemented) methods. Except the instantiation capability, they have the same capabilities as a concrete class or type.They may or may not contain abstract methods.Full abstract types were present in the earliest versions of C++; and the abstract base class remains the only language construct for generating abstract types in C++. A class having only pure virtual methods is often called a pure virtual class; it is necessarily abstract.
  • Note: Due to technical issues with multiple inheritance in C++ and other languages; many OO languages sought to restrict inheritance to a single direct base class. In order to support multiple subtyping, several languages added other features which can be used to create abstract types, but with less power than full-blown classes
  • If a class includes abstract methods, the class itself must be declared abstract, as in:
  public abstract class college {
      // declare fields
      // declare non-abstract methods
      abstract void professor();
  }//above declaration is allowed
  public class college {
      abstract void professor();
  }//above declaration is not allowed
  • Note: When an abstract class is subclassed, the subclass usually provides implementations for all of the abstract methods in its parent class. However, if it does not, the subclass must also be declared abstract.
  • Common Lisp Object System includes mixins, based on the Flavors system developed by David Moon for Lisp Machine Lisp. (CLOS uses generic functions, defined apart from classes, rather than member functions defined within the class).
  • Java includes interfaces, an abstract type which may contain method signatures and constants (final variables), but no method implementations or non-final data members. Java classes may "implement" multiple interfaces. An abstract class in Java may implement interfaces and define some method signatures while keeping other methods abstract with the "abstract" keyword.
  • Traits are a more recent approach to the problem, found in Scala and Perl 6 (there known as roles), and proposed as an extension to Smalltalk (wherein the original implementation was developed). Traits are unrestricted in what they include in their definition, and multiple traits may be composed into a class definition. However, the composition rules for traits differ from standard inheritance, to avoid the semantic difficulties often associated with multiple inheritance.

Use of abstract types

Abstract types are an important feature in statically typed OO languages. They do not occur in languages without subtyping. Many dynamically typed languages have no equivalent feature (although the use of duck typing makes abstract types unnecessary); however traits are found in some modern dynamically-typed languages.

Some authors argue that classes should be leaf classes (have no subtypes), or else be abstract.[3][4]

Abstract types are useful in that they can be used to define and enforce a protocol; a set of operations which all objects that implement the protocol must support.

References

  1. ^ http://java.sun.com/docs/books/tutorial/java/IandI/abstract.html
  2. ^ [www.headfirstlabs.com/books/hfjava/ Head First Java]. O'Reilly Media. 2003. p. 688. ISBN 0-596-00920-8. {{cite book}}: Check |url= value (help)
  3. ^ Riel, Arthur (1996). Object-Oriented Design Heuristics. Addison-Wesley Professional. p. 89. ISBN 0-201-63385-X.
  4. ^ Meyers, Scott (1996). More Effective C++. Addison-Wesley Professional. p. 258. ISBN 020163371x.

External links

  • Types and Programming Languages by Benjamin Pierce (MIT Press 2002) [1]
  • More Effective C++: 35 New Ways to Improve Your Programs and Designs by Scott Meyers (1995) ISBN 0-201-63371-X
  • Traits: Composable Units of Behavior by Nathanael Schärli, Stéphane Ducasse, Oscar Nierstrasz and Andrew Black