Programação Multiparadigma (2014/2015)



Teórica 06 (13/Out/2014)

Object-oriented paradigm.
Scala Class Hierarchy.
Classes and traits in Scala.
Systems of classes versus Algebraic data types.

Object-oriented paradigm

Object-oriented paradigm is a programming paradigm in terms of objects and their interactions. An object is an active data element, able to send and receive messages. Furthermore, each object has an identity that makes it distinguishable from any other object. A running program is a community of objects exchanging messages among themselves. Who controls the computation are therefore the objects!

Note: When developing objects without mutable state, that is in a functional style, the identity requirement is dropped. Changing the "state" of an object amounts to creating a modified copy of it. The individuality of the objects becomes blurred, but it is still the objects that are in charge of the computation.

Programming based on values - Contrasting with the functional and the imperative paradigms

In the functional and the imperative paradigms, a running program is a community of functions or procedures that invoke each other and exchange values among themselves. Who controls the computer are the functions and the procedures! The data elements are passive elements.

Important concepts in O-O programming

Advantages

The O-O paradigm assists the programmer in modeling the problem domain. This result in program easier to understand and modify.

The O-O paradigm simplifies the process of producing extensible code. An extensible system is a system that you can grow and adapt, without having to change what has already been written.

Really extensible code requires the programmer to write code as abstract as possible. Code written based on abstract concepts is able to deal with the original entities described in the statement of the problem, and also with new entities to be created in the future. Of course, this only works if those future entities conform with the abstractions initially considered.



Examples of simple classes in Scala

Implementation of simple point-objects with mutable state.

For a contrast, see a complete implementation of Rational numbers without state, here [E:31].



Scala Class Hierarchy

Study the following classes:

Scala has a unified type system, meaning that the 8 primitive types of Java are introduced using classes types. All values in Scala are objects (i.e. instances of classes), even the primitive values and the functions. (The primitive values are not implemented as real objects in the underlying host system, but this is an implementation detail.)

All the details are in [F:139-156] (chapter 12).



Classes and objects in Scala

If a new class is defined but no superclass is given, then the superclass AnyRef is implicitly assumed. The list of parents of every class is also implicitly extended with the trail ScalaObject in the last position of the inheritance sequence. So, every Scala language inherits from, at least, the class AnyRef with ScalaObject. The Java classes are the only ones that inherit from AnyRef alone.

All the details are in [E:31-36] (chapter 6).



Traits in Scala

  • Traits [paper] are a simple but flexible composition mechanism for structuring object-oriented programs. Traits generalize and are more powerful than interfaces.

    Typically, a trait defines a general behavior or a general feature that may be added to a new class when the class is defined. A useful trait is one that might apply to many different, usually unrelated, classes. Inheriting from a mixin is not a form of specialization but is rather a means of incorporating some new functionality. So, the role of a trait is quite different form the role of an abstract class.

    We know how to define a new concrete subclass B that extends an existing superclass A. But the new features in the subclass B cannot be reused to extend a different superclass than A. A trail is a generic subclass that in parametrized in its superclass, and therefore can be reused to extend different superclasses.

    A trait contains:

    Interfaces in Java solve the problems of subtyping and conceptual modeling within the context of single inheritance, but does not allow code reuse. Traits allow code reuse and, at the same time, avoid the many problems of multiple inheritance.

    A class can incorporate multiple traits using the with keyword, accumulating their implementations. Example:

    The traits can also be mixed-in when creating a new object. Example:

    Another example: we can add comparison operators to our Point3 class by mixing-in the predefined trait Ordered, as follows:

    The predefined trait Ordered is defined like this: The traits are mixed sequentially, and the later ones become dominant. So, there is never any ambiguity in the inheritance path, when names are reused. Study this example:

    Systems of classes versus Algebraic data types

    The traditional object-oriented modelation using a system of traits, abstract classes and concrete classes is the best for building systems that should be extensible with new types of data. Example:

    But if the types of the data don't change and we want to build systems that should be extensible with new operations, be better approach is to use the old idea of algebraic data types, with the associated notions of constructor and pattern matching (a selection and decomposition mechanism).

    Scala supports directly the idea of algebraic data types via the notion of case class. Example:

    The extern function can be stored as a method inside the abstract class,

    Effects of declaring a case class

    1. A constructor global function with the name of the class is automatic generated - this enables the creation of instances of the class without using the new operator;
    2. The following methods are redefined for the class at hand: toString, equals, hashCode;
    3. Accessors methods to the arguments of the constructor are generated;
    4. The language of the patterns are extended to include the one new pattern for each class.

    Implementing pattern matching

    Pattern matching is embedded in the rules of evaluation of expression of Scala. More details about these subject in [E:43-50] (chapter 7).



    #15