
If you have not already done so, please follow the free course instructions at https://www.udemy.com/stairway-to-scala-setup-instructions/learn/#/ so that you are ready to run both the Scala REPL and the exercises. Also please download the slides and exercises from the next document after this video has finished.
Thanks and enjoy the course. This is part two of a three part course, the first part covers converting to Scala from other programming languages, while part three will concentrate on the core libraries and APIs in Scala.
Examine Scala concepts such as classes and abstract classes, the abstract keyword, uniform access, val, lazy val, and def, plus extends, superclass methods, overriding, final, case classes, and domain modelling.
Explore abstract classes in scala, using a car example that cannot be instantiated, then learn how supplying a body creates an anonymous concrete subclass with implemented abstract members.
Explore anonymous classes with overrides in Scala and learn to expose parametric fields with val to access year from subclasses and outside.
See how replacing a def with a val caches a boolean vintage, and learn override rules: def can be overridden by def or val; val cannot be overridden by def.
Apply the uniform access principle by comparing val, def and lazy val in Scala, showing eager evaluation, repeated access behavior, and first-use caching of properties.
Explore how inheritance and the extends keyword implement is-a relationships, using abstract classes, a fruit hierarchy, and parametric fields to define a name.
Learn how to invoke superclass constructors in Scala by extending a vehicle with required name and age parameters, and implement overridden toString using super to access superclass behavior.
compare override val with private instance fields, which remove external access and name ambiguity; remain aware that override val is the idiomatic choice in Scala.
Learn the Scala override rules: mark overridden fields or methods with override, avoid it for new subclass definitions, and optionally override abstract parents; overloads require distinct signatures.
Explore how the final keyword prevents methods from being overridden in Scala, illustrating authority with final methods and an argumentative example.
Analyze why the String class is final in the JVM and Scala libraries, preventing extension to avoid surprising behavior, and consider alternatives such as extending char sequence.
Explore how case classes in Scala provide value objects with immutable, public fields and a factory method via apply, with built-in equals, hashCode, and toString.
Explore a parking structure in scala by modeling a vehicle storage with abstract members and a case class for vehicles, plus a toString that shows garage contents and count.
Module seven tasks include building a train domain model in Scala, including rolling stock, cars, and engines with max car limits, using a mutable list buffer and string representations.
Explore the Scala type hierarchy and learn how options and optional types compare to nulls. Apply these concepts in the Scala applied course's module eight.
Scala defines three top types—Any, AnyVal, and AnyRef—with Unit as a single instance in AnyVal; singleton objects extend AnyRef, and Any exposes toString, equals, hashCode, and not equals.
Explore top types and the distinction between runtime and compile-time types, illustrating how any, anyref, and anyval interact with strings and ints.
Explain how null works across languages, show that Scala treats null as a type with a single null instance, and introduce the nothing type and a method returning nothing.
Explore how a method that returns nothing in Scala must throw an exception, making nothing the inferred or explicit result and revealing its role in type calculus.
Nothing acts as bottom type, completing scala's type calculus and enabling A plus nothing to yield A. The least upper bound widens B and C of A to a supertype.
Explore how Scala's type inference combines product and serializable with case classes, and how explicit type annotations prevent unwanted least upper bound results.
Explore implicit conversions and rich wrappers in Scala, adding extension methods to numeric types and strings, including abs, min, max, floor, ceiling, round, reverse, and slice.
Apply the @specialized annotation in Scala to generate versions for int, double, and long, avoiding boxing, but use it carefully because it can generate many implementations.
Understand why specialized generation backfires by creating many boxed boolean combinations and tuples, and inspect the generated code with javap only if boxing impacts performance.
Explore Scala extension methods and implicit classes, wrapping types like int and double to add methods such as times, min, and max via implicit conversions and infix notation.
Use extends any val to write extension methods in Scala, requiring a single public val parameter and no other state; the Scala compiler turns them into static methods, avoiding boxing.
Explore Scala's negative types, nil as the empty list and null as the instance reference. Note nothing has no instance, and none denotes absence of a sum in option.
Explore how using an option of string avoids null pointer errors, exposes some and none at compile time, and uses map get to return options instead of exceptions.
Extract values from an option using pattern matching or get or else, returning the word or a default such as unknown, showcasing an idiomatic approach that reduces conditionals.
Learn to use option to safely get the fourth letter from words in a word map, returning none when missing, by composing drop and head option for condition-free code.
Master how to implement equals and hashCode in Scala, addressing the contract and common pitfalls on the JVM, and learn state-based equality by building example classes.
Leverage IntelliJ to generate equals and hashCode for a class, selecting fields such as first name, last name, and age, and verify the hash code contract by compiling and running.
Learn how to implement a robust equals method in scala by using canEqual, handling type checks, and overriding equals and hashCode for reliable, reflexive comparisons.
Explains implementing subclass equality in Scala by extending fruit with apple, including color and brand in equality, overriding canEqual to restrict comparisons, and computing a robust hashCode using primes.
Use case classes in Scala to automatically generate equals and hashCode from their state, giving stable, predictable comparisons. Note that they cannot extend other case classes and are often final.
Explore product types in scala, comparing tuples and case classes, with equality based on contents. Learn to use product iterator, arity, and product prefix, and why case classes suit APIs.
Explore the product type features in Scala, including product, iterator, arity, product element, and product prefix, with practical reminders for potential exercises.
Explore Scala's traits and their functionality for enabling multiple inheritance in Scala while avoiding common issues found in other languages.
Compare traits with interfaces and Java's interfaces, and learn how to create, mix, and stack traits on a class using Scala's linearization. Explore initialization order and selfless traits.
Explore how Scala uses traits to address the diamond inheritance problem in multiple inheritance, illustrating how super calls determine which parent method runs and the resulting predictability issues.
Explore how scala's traits tackle the diamond inheritance problem by mixing in multiple traits with state and behavior. Contrast with java's single superclass and interfaces lacking state or implementation.
Create a trait like a class, but traits cannot be instantiated directly. Use abstract vals or defs to require color, or instantiate via an anonymous class with a body.
Learn how to use a trait in a Scala class by extending a trait for syntactic convenience, supplying abstract members like color, and understanding trait mixins.
Explore polymorphism with Java interfaces and Scala traits. Upcast objects to traits to access rich, trait-based behavior and enable function composition.
Mix multiple traits with an abstract class to model a car, and see how classic and convertible traits extend the describe method, resolving diamond inheritance.
Scala rewires superclasses via linearization when traits mix, resolving the diamond problem and ordering convertible, classic, and car from the right.
We explore stacking traits by mixing an abstract class with classic, convertible, powered convertible, and hardtop convertible cars, showing how different combinations address trait composition challenges.
Explore stacking traits in Scala by tracing trait linearization as a directed acyclic graph, revealing how hardtop, vintage, powered convertible, convertible, color, and car are ordered through a trait traversal.
Stack traits in order: classic, then hardtop convertible, then powered convertible to produce a vintage 1965 hardtop powered convertible red car.
Compare traits and classes in Scala, noting traits cannot have constructor parameters. Use lazy vals with abstract fields to avoid initialization order issues and understand trait-based design.
Explain trait initialization by showing how X and Y are not assigned values until after the origin has been calculated.
Explore traits with type parameters and upper bounds, implementing a compare age mechanism to select the older of two items, illustrated with a vintage car example.
Explore using polymorphism with compare age across any trait, defining a person and older method to compare ages. Learn about implicit type class patterns and how ordering enables sorted collections.
Define a selfless trait with no abstract methods or super traits, then pair it with a companion object that provides its behavior and state, enabling extension or import from it.
Explore how Scala organizes class definitions and objects, uses packages to disambiguate similar names, and manages imports, scope modifiers, and a lean public API.
Explore Scala visibility modifiers—public, protected, and private—and importing from within packages, package objects, and from objects and class instances, including renaming, selective importing, and companion objects with their classes.
Learn how Scala packages organize classes and objects into logical units, using package declarations and imports to access dessert, ice cream, and jello within demo.food.domain.api.
Explore Scala package structure alternatives, including the c-sharp namespace style with nested scopes and curly braces, demonstrated by demo food domain api with dessert, ice cream, and jello.
Explore Scala package visibility with private and protected, learn about super packages and domain scoping, and compare with Java visibility rules; understand private this and the resulting accessor methods.
Explore how to disambiguate top-level packages and design package layouts, using a top-level domain and logger to show how to request the logger amid subpackage domains.
Introduce the demo wine package, its domain API, and a private map that pairs foods with wines, returning an optional wine for desserts like ice cream with old vine zinfandel.
Explore scala's importing kung fu: import from any object, scope imports to control namespace, and bring in methods like log directly from logger using curly brace blocks.
Learn how to import from a class instance in Scala, importing everything from an ice cream instance and then flavor methods to access a char at three.
Learn selective importing in Scala using curly braces for items like immutable HashMap and HashSet. Exclude items with underscore and use alias imports; note abs via predef and default imports.
Define a laser class in module ten package structure, explore imports and scoping, and practice wiring tests to pass as you complete the module ten exercises.
Explore testing in Scala with unit and integration tests, pre and post conditions, stubbing and mocking, and property driven testing, emphasizing automated tests to verify code correctness.
Explore pre and post conditions, the ScalaTest framework, and the tests versus specifications. Examine matches DSL, exception handling, stubbing and mocking, property-driven testing, and futures-based asynchronous testing.
Explore preconditions, postconditions, and invariants in Scala, and how ensuring uses predicates to validate values, returning the original value or throwing when checks are enabled, unlike runtime-disabled assertions.
Eliding asserts and assumes lets you turn them off in production with a disable assertions flag, so they may not fail, while ensuring they still throw when appropriate.
Explore functional testing with FunSuite in ScalaTest, organizing tests around classes that extend a suite and mix in traits, using the matches DSL, setup, and pending tests.
Learn how fun spec enables behavior driven design in Scala, using the matches DSL to describe weather service behavior and operation conditions, with pending tests awaiting implementation.
Describe the matcher feature for Scala case classes, enabling quick value checks using single-quoted symbols like 'first, 'last, and 'age to write concise tests.
Explore how to use matchers and intercept in Scala to test for expected exceptions, verify messages, and apply tolerance when checking floating point results like sqrt(2).
Compare unit testing and integration testing: unit tests are small and fast with no external resources; integration tests use external resources to validate the complete system.
Use a Scala mock factory to simulate a weather service, scripting operational and get weather calls for PDX, and assert results and call counts.
Leverage mocks to verify calls and control conditions, such as throwing a network failure when not operational, ensuring the weather service is not called.
Explore mocks and stubs in Scala applied, part 2, learning how mocks script expected behavior while stubs return predefined values, with mocks verifying automatically and stub verifications separate.
Explore fakes, more general than mocks or stubs, as flexible stand-ins for an entire system using an in-memory map to save and load data through a trait.
Explore property driven testing with Scala check, generating random data to verify abs on integers, guard int min value edge cases, and augment unit tests with property checks.
Create custom property generators to produce random strings from a defined valid character set, varying lengths 0–30, and verify that reversing a string equals the original for all generated strings.
Practice property-based testing with custom generators, verify that reverse on strings returns the original, and manage futures to ensure tests wait for asynchronous results and fail when appropriate.
Explore module 11 exercises that require you to write tests, work with core libraries, and practice pattern matching, asynchronous programming, and a genetic sequence generator.
Scala Applied, Part 2 covers Scala features that are different from other languages or maybe unique to Scala. It is intended to follow on from Part 1, and dovetails nicely into that flow.
While part 1 covered common concepts from other languages in Scala, part 2 concentrates on the parts of the language that are more specific to Scala and may be unfamiliar when coming from other programming languages, either the features themselves or the syntax for using them, taught by an instructor with over 15 years experience programming in Scala, and more than a dozen years teaching it.
As part of the larger Scala Applied 3 part course, this will prepare you with everything you need for day-to-day development in the Scala language.
In particular, by following this course you will:
Understand Scala's composition and inheritance features
Create abstract classes and pure abstract members (methods and fields)
Override and overload class methods
Create primary and auxiliary constructors
Call superclass constructors and methods
Understand and use parametric fields
Create factory methods in companion objects
Construct simple DSLs (Domain Specific Languages)
Understand top and bottom types and how Scala uses them
Write correct equals and hashCode methods
Use traits to mix behavior into classes
Know the different styles of packages and visibility modifiers
Be able to import anything from anywhere
Write pre-conditions and post-conditions
Test your code with unit testing