-
Notifications
You must be signed in to change notification settings - Fork 16
Classes and Objects
Here we will learn how functions can create and encapsulate data structures.
A class in scala can be defined with its constructor as below:
class Foo(x: Int, y: Int) {
def numer = x
def denom = y
}
This definition has 2 entities:
- A "type" named Foo
- A Constructor to create elements of this type.
Scala keeps types and values in different namespaces, so there is no conflict between the definitions of Foo.
In the above examples, instead of taking constructor params, and assigning them to class variables/constants, we can do the below directly:
class Foo(var numer: Int, val denom: Int) {
}
Here numer
is a variable and denom
is a constant. No getters/setters needed.
Objects are elements of a class type, created by using the new
keyword.
val foo = new Foo(1,2)
Functions can be packaged in the class:
class Foo(x: Int, y: Int) {
def numer = x
def denom = y
def multiplyBy(that: Foo) {
new Foo( numer * that.numer, denom * that.denom )
}
}
// call
val foo1 = new Foo(1,2)
val foo2 = new Foo(5,6)
foo1.multiply(foo2)
-
String Representation: Overwrite the
toString()
method of a class to provide a custom string representation of a class, just like in JAVA. - Access Specifiers: Variables and function definitions in a class that are only for use inside the class can be marked with the private access specifier like in JAVA.
-
this: The
this
keyword can be used inside a class to refer to current object.
The require
keyword be used to define requirements of a particular class. It takes in a condition and an optional message.
Example:
class Foo(x: Int) {
require( x! = 0, "Integer must be non-zero")
def numer = x
def divideBy(that: Foo) {
new Foo( this.numer / that.numer)
}
}
So if we call:
val foo1 = new Foo(4)
val foo2 = new Foo(0)
foo1.divideBy(foo2) // Fails with "IllegalArgumentException: requirement failed: Integer must be non-zero"
Similarly assert
also takes in a condition and an optional message.
val x = sqrt(y)
assert(x >= 0)
// Fails with AssertionError instead of IllegalArgumentException
The difference between require
and assert
is the "intent" of use.
- require is used to enforce a precondition on the caller of a function
- assert is used to check the code of a function
Classes are defined with an implicit constructor which is the primary constructor. Additional constructors can be defined by using the this
keyword.
class Foo(x: Int, y: Int) {
def numer = x
def denom = y
// additional constructor which uses the primary constructor
def this(x: Int) = {
this(x, 1)
}
def multiplyBy(that: Foo) {
new Foo( numer * that.numer, denom * that.denom )
}
}
Week 1
Week 2
- Higher Order Functions
- Classes and Objects
- Substitution Model (CBV, CBN) with Classes
- Operators, Precedence and Types
Week 3
- Class Hierarchies and Dynamic Binding
- Organizing Classes and Scala Class Hierarchy
- Polymorphism (Subtyping and Generics)
Week 4
- Objects-Everywhere
- Subtyping and Generics (Bounds and Covariance)
- Decomposition
- Pattern Matching
- Collections (Lists)
Week 5
- Collections (List Methods)
- Pairs and Tuples
- Collections (Lists - Applying functions to elements)
- Collections (Lists Reduction)
- Collections Theory (Lists concat and reverse)
Week 6