Skip to content
Snippets Groups Projects
progfun1-3-2.md 4.87 KiB
Newer Older
% How Classes are Organized
Martin Odersky's avatar
Martin Odersky committed
%
%

Packages
========
Martin Odersky's avatar
Martin Odersky committed

Classes and objects are organized in packages.
Martin Odersky's avatar
Martin Odersky committed

To place a class or object inside a package, use a package clause
at the top of your source file.
Martin Odersky's avatar
Martin Odersky committed

      package progfun.examples
Martin Odersky's avatar
Martin Odersky committed

      object Hello
        ...
This would place `Hello` in the package `progfun.examples`.
Martin Odersky's avatar
Martin Odersky committed

You can then refer it by its _fully qualified name_,
`progfun.examples.Hello`. For instance, to run the `Hello` program:
Martin Odersky's avatar
Martin Odersky committed

       > scala progfun.examples.Hello
Martin Odersky's avatar
Martin Odersky committed

Imports
=======
Martin Odersky's avatar
Martin Odersky committed

Say we have a class `Rational` in package `week3`.
Martin Odersky's avatar
Martin Odersky committed

You can use the class using its fully qualified name:
Martin Odersky's avatar
Martin Odersky committed

      val r = week3.Rational(1, 2)
Martin Odersky's avatar
Martin Odersky committed

Alternatively, you can use an import:
Martin Odersky's avatar
Martin Odersky committed

      import week3.Rational
      val r = Rational(1, 2)
Martin Odersky's avatar
Martin Odersky committed

Forms of Imports
================
Martin Odersky's avatar
Martin Odersky committed

Imports come in several forms:
Martin Odersky's avatar
Martin Odersky committed

      import week3.Rational           // imports just Rational
      import week3.{Rational, Hello}  // imports both Rational and Hello
      import week3._                  // imports everything in package week3
Martin Odersky's avatar
Martin Odersky committed

The first two forms are called _named imports_.
Martin Odersky's avatar
Martin Odersky committed

The last form is called a _wildcard import_.
Martin Odersky's avatar
Martin Odersky committed

You can import from either a package or an object.
Martin Odersky's avatar
Martin Odersky committed

Automatic Imports
=================
Martin Odersky's avatar
Martin Odersky committed

Some entities are automatically imported in any Scala program.
Martin Odersky's avatar
Martin Odersky committed

These are:
Martin Odersky's avatar
Martin Odersky committed

 - All members of package `scala`
 - All members of package `java.lang`
 - All members of the singleton object `scala.Predef`.
Martin Odersky's avatar
Martin Odersky committed

Here are the fully qualified names of some types and functions which you have seen so far:

      Int                            scala.Int
      Boolean                        scala.Boolean
      Object                         java.lang.Object
      require                        scala.Predef.require
      assert                         scala.Predef.assert

Scaladoc
========
Martin Odersky's avatar
Martin Odersky committed

You can explore the standard Scala library using the scaladoc web pages.
Martin Odersky's avatar
Martin Odersky committed

You can start at
Martin Odersky's avatar
Martin Odersky committed

 [\blue{www.scala-lang.org/api/current}](http://www.scala-lang.org/api/current)
Martin Odersky's avatar
Martin Odersky committed

Traits
======
Martin Odersky's avatar
Martin Odersky committed

In Java, as well as in Scala, a class can only have one superclass.
Martin Odersky's avatar
Martin Odersky committed

But what if a class has several natural supertypes to which it conforms
or from which it wants to inherit code?
Martin Odersky's avatar
Martin Odersky committed

Here, you could use `trait`s.
Martin Odersky's avatar
Martin Odersky committed

A trait is declared like an abstract class, just with `trait` instead of
`abstract class`.
Martin Odersky's avatar
Martin Odersky committed

      trait Planar with
        def height: Int
        def width: Int
        def surface = height * width
Martin Odersky's avatar
Martin Odersky committed

Traits (2)
==========
Martin Odersky's avatar
Martin Odersky committed

Classes, objects and traits can inherit from at most one class but
arbitrary many traits.
Martin Odersky's avatar
Martin Odersky committed

Example:
Martin Odersky's avatar
Martin Odersky committed

     class Square extends Shape, Planar, Movable ...
Martin Odersky's avatar
Martin Odersky committed

Traits resemble interfaces in Java, but are more powerful because they can have parameters and
contain fields and concrete methods.
Scala's Class Hierarchy
Martin Odersky's avatar
Martin Odersky committed
=======================

\includegraphics[scale=0.33]{images/classhierarchy.pdf}

Top Types
=========
Martin Odersky's avatar
Martin Odersky committed

At the top of the type hierarchy we find:
Martin Odersky's avatar
Martin Odersky committed

\begin{tabular}{ll}
\verb@Any           @ & the base type of all types
\\[1em]
                 & Methods: `==`, `!=`, `equals`, `hashCode, `toString`
\\[2em]
\verb@AnyRef@    & The base type of all reference types;
\\               & Alias of `java.lang.Object`
\\[2em]
\verb@AnyVal@     & The base type of all primitive types.
\end{tabular}

The Nothing Type
Martin Odersky's avatar
Martin Odersky committed
================

`Nothing` is at the bottom of Scala's type hierarchy. It is a subtype of every other type.

There is no value of type `Nothing`.

Why is that useful?

 - To signal abnormal termination
 - As an element type of empty collections (see next session)

Exceptions
==========

Scala's exception handling is similar to Java's.
Martin Odersky's avatar
Martin Odersky committed

The expression
Martin Odersky's avatar
Martin Odersky committed

     throw Exc

aborts evaluation with the exception `Exc`.

The type of this expression is `Nothing`.

The Null Type
=============

Every reference class type also has `null` as a value.

The type of `null` is `Null`.

`Null` is a subtype of every class that inherits from `Object`; it is
incompatible with subtypes of `AnyVal`.

     val x = null         // x: Null
     val y: String = null // y: String
     val z: Int = null    // error: type mismatch

The Problem With Nulls
======================

Having `null` as a value in every reference type has been called by its inventor Tony Hoare "A Billion-Dollar Mistake".

Why?

->

 - High risk of failing at run-time with a `NullPointerException`.

 - It would be safer to reflect the possibility that a reference is `null` in its static type.

Making Null Safer
=================

It is planned to add explicit null types to Scala. I.e.

      String            // The type of strings, no `null` allowed
      String | Null     // Either a string or `null`.

Therefore, the following would be an error:

      def f(x: String) = println(x + "!")
      f(null)     // error, expected: String, found: Null

Work on implementing this feature is ongoing.
Martin Odersky's avatar
Martin Odersky committed

Exercise
========

What is the type of

      if true then 1 else false

      O        Int
      O        Boolean
      O        AnyVal
      O        Object
      O        Any