1 / 15

Cases and Classes and Case Classes

Cases and Classes and Case Classes. And Other Miscellany. Classes and constructors, I. Every class has a constructor, which you write (no “invisible” constructors, as in Java) scala> class Person(val firstName:String, var lastName: String, age: Int) defined class Person

elysia
Download Presentation

Cases and Classes and Case Classes

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Cases and Classes and Case Classes And Other Miscellany

  2. Classes and constructors, I • Every class has a constructor, which you write (no “invisible” constructors, as in Java) • scala> class Person(val firstName:String, var lastName: String, age: Int)defined class Person • The above is complete; no braces are needed unless you want to add code, fields, or methods • The above defines: • firstName(immutable) with getter function firstName • lastName(mutable) with getter function lastNameand setter function lastName_= • The method name uses an underscore, but you use it as an ordinary assignment, for example, lastName = "Smith" • Nothing for age (it can be used as a val in the class)

  3. Classes and constructors, II • Syntax: class ClassName(parameters) { body } • TheClassName should begin with a capital letter and be CamelCase • This is the constructor, and it has parameters • A var parameter will cause a field, getter, and setter to be included:var p: Int gives the methods p: () => Int and p_=: Int => () • These methods can be redefined inside the method • A val parameter will create a field and a getter, but no setter • A parameter with neither val nor var does not create a field or any methods, but it can be used within the body of the class • When a new object of this class is defined, the fields are created, the methods are defined, and any “loose” code (not within a def) is executed

  4. Classes and constructors, III • scala> class Person(val firstName:String, var lastName: String, age: Int)defined class Person • scala> val mary = new Person("Mary", "Smith", 23)mary: Person = Person@d73c3c • scala> mary.firstNameres22: String = Mary • scala> mary.lastNameres23: String = Smith • scala> mary.firstName = "Sally"<console>:7: error: reassignment to val • scala> mary.lastName = "Jones"res24: String = Jones • scala> mary.age<console>:8: error: value age is not a member of Person • scala> mary.lastNameres25: String = Jones

  5. Classes and constructors, IV • Again, but this time with a method: • scala> class Person(val firstName:String, var lastName: String, age: Int) { | override def toString = firstName + " " + lastName + ", age " + age | }defined class Person • scala> val mary = new Person("Mary", "Smith", 23)mary: Person = Mary Smith, age 23 • scala> println(mary)Mary Smith, age 23

  6. Auxiliary constructors • A class (as on the previous slide) defines its primary constructor • You can have additional, auxiliary constructors • The first statement within an auxiliary constructor must be a call to another auxiliary constructor, or to the primary constructor • Thus, every object creation eventually ends up at the primary constructor • Syntax: def this(parameters1) { this(parameters2)… more code… } • Since these are overloaded constructors, parameters1 and parameters2 must be different

  7. Pattern matching with match • You have seen pattern matching with match and literals • today match { case "Saturday" => println("Party! Party! Party!") case "Sunday" => println("Pray....") case day => println(day + " is a workday. :( ")} • You can match with types • something match { case x: Int => println("I'm the integer " + x) case x: String => println("I'm the String \"" + x + "\"") println("My length is " + x.length) case _ => println("I don't know what I am! :( ") }

  8. Pattern matching in assignments • You can pattern match on tuples: • scala> val (a, b, c) = (3, 5, 7)a: Int = 3b: Int = 5c: Int = 7 • But… • scala> val a, b, c = (3, 5, 7)a: (Int, Int, Int) = (3,5,7)b: (Int, Int, Int) = (3,5,7)c: (Int, Int, Int) = (3,5,7) • You can pattern match on lists: • scala> val list = List("once", "upon", "a", "time")list: List[java.lang.String] = List(once, upon, a, time) • scala> val first :: second :: rest = listfirst: java.lang.String = oncesecond: java.lang.String = uponrest: List[java.lang.String] = List(a, time)

  9. Case classes • If you declare a class as a case class, you get some extra features: • It adds a factory method with the name of the class, so you can omit the word new when you create a new object • All constructor parameters are implicitly val • You get reasonable implementations of toString, hashCode, and equals “for free” • Example: • scala> case class Person(firstName: String, lastName: String)defined class Person • scala> val jane = new Person("Jane", "Eyre")jane: Person = Person(Jane,Eyre) • scala> val Person(f, l) = janef: String = Janel: String = Eyre • scala> println(jane)Person(Jane,Eyre)

  10. Case classes can be pattern matched • scala> case class Person(age: Int, name: String)defined class Personscala> val dave = Person(40, "Dave")dave: Person = Person(40,Dave)scala> dave match {| case Person(a, n) if a > 30 => println(n + " is old!")| case _ => println("Whatever")| }Dave is old!scala> val quinn = Person(25, "Quinn")quinn: Person = Person(25,Quinn)scala> quinn match {| case Person(a, n) if a > 30 => println(n + " is old!")| case _ => println("Whatever")| }Whatever

  11. Operations and methods

  12. Parameters in braces • A block consists of any number of statements inside braces, { } • The last value in the block is the value of the block • Parentheses, ( ), can’t enclose multiple statements • When a method takes just one parameter, you can put that parameter inside braces instead of parentheses • scala> "abcdefg" substring { 2 }res0: java.lang.String = cdefg • This example is pointless and looks silly • Sometimes, you may want to compute that parameter by a series of statements • scala> println { | var x = 2 | while (x < 1000) x *= 2 | x | }1024 • This isn’t a great example either, but it does make the point

  13. Methods with no parameters • You can define a “parameterless” method: • scala> def hello = println("Hello!")hello: Unit • scala> helloHello! • scala> hello()<console>:7: error: hello of type Unit does not take parameters • You can define an “empty paren” method: • scala> def hi() = println("Hi!")hi: ()Unit • scala> hiHi! • scala> hi()Hi! • If you define a method without parentheses, you can’t call it with parentheses • You can replace a parameterless method with an empty paren method, without affecting user code (but not vice versa)

  14. Uniform access • In Java, the length of an array is a field, so you have to say myArray.length; but the length of a String is a field, so you have to say myString.length() • This violates the principle of uniform access: The user shouldn’t have to know whether it’s a field or a method • However, if I say foo = bar, or println(bar), I am using barlike a variable, so I expect bar to act like a variable: • bar should not do I/O • bar should not change mutable state • bar should not depend on values in mutable state • In other words, if baris a function, it should be a pure function • Scala convention: When you call a method that does one of the above (impure) things, use parentheses

  15. The End

More Related