วันอังคารที่ 25 กรกฎาคม พ.ศ. 2560
วันพุธที่ 24 กุมภาพันธ์ พ.ศ. 2559
วันพุธที่ 20 พฤษภาคม พ.ศ. 2558
Array in Scala
Array ในภาษา Scala ก้อเหมือนกับภาษาอื่นๆ อาจจะแตกต่างกันบ้างในเรื่องของ Syntax เรามาดูตัวอย่างกัน ดังข้างล่างนี้
val names = new Array[String](3)
names(0) = "a"
names(1) = "b"
names(2) = "c"
names.foreach { s => println(s) }
เราเริ่มจากการประกาศว่า names เป็น array ที่เก็บค่า string และกำหนดขนาดของ array ไว้คือ 3
หลังจากนั้นเราเก็บค่า a ไว้ใน array names ช่องที่ 1, b ช่องที่ 2 และ c ช่องที่ 3 ตามลำดับ ท้ายที่สุดเรา println ค่าที่อยู่ใน names ออกมาทั้งหมด สังเกตุว่าเราใช้
names.foreach{ s=>println(s) }
โดยที่ s จะแทนสมาชิกแต่ละช่องใน names ถ้าเขียนเป็น c# จะได้ดังนี้
foreach(var s in names) { Console.WriteLine(s); }
เราอาจจะประกาศ array และ assign value อีกแบบได้ดังต่อไปนี้
val names = Array("a", "b" , "c");
names.foreach { s => println(s) }
Array ใน Scala เป็น object ชนิดหนึ่งดังนั้นมีหลาย property และ method ให้ใช้ได้ แล้วแต่งานเช่น
names.length คือจำนวนสมาชิกของ names
ลองมาดูอีกตัวอย่างหนึ่ง
import Array._
object Hello {
def main(args: Array[String]) {
val names = Array("a", "b" , "c");
val names2 = Array("d")
var names3 = concat(names,names2)
names.foreach { s => println(s) }
}
}
ตัวอย่างข้างต้นเรา concat names และ names2 เข้าด้วยกัน สังเกตุว่า เราต้อง import Array._ ก่อนถึงจะใช้ฟังก์ชั่น concat ได้ ในที่นี้คือการใช้ implicit class Array นั่นเอง ลองกลับไปดูบทความเรื่อง Implicit class ที่ผมได้เขียนไว้ก่อนหน้านี้ดูครับ
สำหรับเรื่องของ Array ผมคงเขียนไว้สั้นๆ แค่นี้ บทความต่อไปจะเป็นเรื่องของ Immutable/Mutable List
วันจันทร์ที่ 18 พฤษภาคม พ.ศ. 2558
Implicit Parameter
วันนี้เรามาดูกันเรื่องของ Implicit Parameter ในภาษา Scala กัน ลองมาดูนิยามของ implicit parameter กัน
1. implicit parameter คือ parameter ใน constructor หรือ method ที่เราใส่ keyword implicit นำหน้าไว้
2. เวลาเรียกใช้ constructor หรือ method หากเราไม่ได้ส่งค่าให้กับ implicit parameter ภาษา Scala จะ ค้นหาค่า (resolve) จากโค๊ดที่มีอยู่โดยอัติโนมัติ
3. implicit parameter แตกต่างจาก implicit class โดยสิ้นเชิง implicit class คือการเพิ่ม method จาก implicit class ให้ class อื่นๆ โดยไม่จำเป็นต้อง inherit หรือสร้าง wrapper class (ดูบทความก่อนหน้านี้)
4. implicit parameter ไม่ใช่ default parameter value
ลองมาดูตัวอย่างกันครับ
1. implicit parameter คือ parameter ใน constructor หรือ method ที่เราใส่ keyword implicit นำหน้าไว้
2. เวลาเรียกใช้ constructor หรือ method หากเราไม่ได้ส่งค่าให้กับ implicit parameter ภาษา Scala จะ ค้นหาค่า (resolve) จากโค๊ดที่มีอยู่โดยอัติโนมัติ
3. implicit parameter แตกต่างจาก implicit class โดยสิ้นเชิง implicit class คือการเพิ่ม method จาก implicit class ให้ class อื่นๆ โดยไม่จำเป็นต้อง inherit หรือสร้าง wrapper class (ดูบทความก่อนหน้านี้)
4. implicit parameter ไม่ใช่ default parameter value
ลองมาดูตัวอย่างกันครับ
object Hello {
def main(args: Array[String]) {
implicit val x: Int = 10
myPrint //this is 10
myPrint(100) //this is 100
}
def myPrint(implicit a : Int) {
println("this is " + a)
}
}
จากตัวอย่างข้างต้น เรา ประกาศ myPrint ว่าเราจะ print ค่าของ a ออกมาไม่ว่าจะมีการส่งค่าให้กับ parameter a หรือไม่ ใน main method สังเกตุว่าเราประกาศ ว่า x เป็น implicit value ดังนั้นตอนที่เราเรียก myPrint ค่าของ x จะถูกส่งให้ myPrint โดยอัตโนมัติ ส่วนตอนที่เรียก myPrint(100) ค่า 100 จะถูกส่งให้ myPrint แทน
ลองมาดูอีกตัวอย่างหนึ่ง คราวนี้เราต้องการให้ส่ง name ให้กลับ myPrintln เสมอ ส่วน a เป็น implicit
ไม่ต้องส่งมา
object Hello {
def main(args: Array[String]) {
implicit val x: Int = 10
myPrint("jack") //println "this is jack and 10
}
def myPrint(name : String)(implicit a : Int) {
println(s"this is ${name} and ${a} ")
}
}
ลองมาดูตัวอย่างสุดท้าย
ในตัวอย่างนี้เราประกาศให้ myPrint รับ implicit a : Int* หมายถึงรับ int จำนวนกี่ตัวก้อได้ ใน main method เราส่ง parameter (1,2,3) และ (1,2,3,4) ให้กับ myPrint ผลลัพธ์ออกมาดังนี้
WrappedArray(1, 2, 3)
WrappedArray(1, 2, 3, 4)
สำหรับคนที่ใช้ ภาษา c# จะเห็นว่าในกรณีนี้เหมือนกันกับ params array นั่นเอง ในครั้งต่อไปเราจะมาดูกันเรื่อง Array ใน ภาษา Scala กัน
วันเสาร์ที่ 16 พฤษภาคม พ.ศ. 2558
Using Implicit class in Scala
วันนี้เรามาดูเรื่อง implicit class กันครับ บางครั้งเราต้องการที่จะเพิ่มเมทธอดให้กับ class ของคนอื่นที่เรานำมาใช้ (reference library) เราอาจทำได้โดย inherit แล้วเพิ่มเมทธอดเข้าไป ถ้า class นั้นๆ ไม่ได้เป็น final class ใน java หรือ sealed class ใน c# อีกวิธีหนึ่งเราอาจจะสร้าง wrapper class มาใช้งานแทน ตัวอย่างเช่น เราต้องการเพิ่มเมทธอด paddingLeftให้กับ string เราอาจะสร้าง wrapper class ได้ดังนี้
class MyWrapperString {
private String str;
public MyWrapperString(String str) {
this.str = str;
}
public String paddingLeft(int n) {
String ret = "";
for(int i = 0; i < n; i++)
{
ret += " ";
}
return ret + str;
}
}
จะเห็นได้ว่าคนที่เอา class นี้ไปใช้ไม่ได้รู้สึกว่าใช้ String ที่คุ้นเคย ถึงแม้ว่ามี paddingLeft ให้ใช้ก้อตามที ดูตัวอย่างข้างล่างนี้
MyWrapperString str = new MyWrapperString("Hello");
String output = str.paddingLeft(10);
ในที่นี้ output จะมี 10 space ก่อนหน้าคำว่า Hello
ใน Scala เราใช้ implicit class เพื่อที่จะทำหน้าที่อย่างนี้ครับ ที่สำคัญคือ เราไม่จำเป็นต้อง inherit หรือว่า สร้าง wrapper ขึ้นมาเลย
เราสร้าง implicit class MyString ภายใน object Hello แล้วประกาศเมทธอด paddingLeft เหมือนที่เราทำมาก่อนหน้านี้ ทีนี้มาดูวิธีเอาไปใช้กัน
ก่อนอื่นเราจะต้อง import เมทธอดทั้งหมดของ object Helper มาใช้ โดยการ
import Helper._
หรือถ้าเราต้องการ ระบุ class ไปเลยก้อระบุได้ตามนี้
object MyString {
implicit class MyString(str:String)
}
สำหรับผู้ที่ใช้ c# อยู่จะเห็นได้ว่าคล้ายๆ กับ extension method นั่นเอง สำหรับบทความต่อไปเราจะมาดู implicit parameter กันครับ
class MyWrapperString {
private String str;
public MyWrapperString(String str) {
this.str = str;
}
public String paddingLeft(int n) {
String ret = "";
for(int i = 0; i < n; i++)
}
return ret + str;
}
}
จะเห็นได้ว่าคนที่เอา class นี้ไปใช้ไม่ได้รู้สึกว่าใช้ String ที่คุ้นเคย ถึงแม้ว่ามี paddingLeft ให้ใช้ก้อตามที ดูตัวอย่างข้างล่างนี้
MyWrapperString str = new MyWrapperString("Hello");
String output = str.paddingLeft(10);
ในที่นี้ output จะมี 10 space ก่อนหน้าคำว่า Hello
ใน Scala เราใช้ implicit class เพื่อที่จะทำหน้าที่อย่างนี้ครับ ที่สำคัญคือ เราไม่จำเป็นต้อง inherit หรือว่า สร้าง wrapper ขึ้นมาเลย
ก่อนอื่นเราจะต้อง import เมทธอดทั้งหมดของ object Helper มาใช้ โดยการ
import Helper._
หรือถ้าเราต้องการ ระบุ class ไปเลยก้อระบุได้ตามนี้
import Helper.MyString
หลังจาก import มาใช้งานแล้ว ตัวแปรที่ชนิด string ทั้งหมดจะสามารถใช้เมทธอด paddingLeft ได้โดยอัตโนมัติ ผู้ที่เรียกใช้ยังคงประกาศตัวแปรเป็น string และใช้ data/method ต่างๆ ของ string ได้โดยปรกติ แถมยังใช้ paddingLeft ได้อีกด้วย
ที่เป็นเช่นนี้เพราะเราประกาศ implicit class MyString(str : String) นั่นเอง อย่างไรก้อตามเรามีข้อจำกัดในการประกาศใช้ implicit class ดังต่อไปนี้
1. implicit class ไม่สามารถเป็น top level class ได้ ต้องอยู่ภายใน object หรือ class หรือ trait อื่นๆ ในตัวอย่างที่เราดูกันก้ออยู่ภายใน object Helper
2. implicit class มี parameter ใน primary constructor ได้เพียงตัวเดียว เราไม่สามารถทำอย่างนี้ได้
implicit class MyString(str:String, n:Int)
3. ผู้ที่นำไปใช้ต้อง import object หรือ class หรือ trait ไปใช้งาน ในกรณีของเราคือ import Helper._
4. ห้ามตั้งชื่อ implicit class ตรงกับ top level class เราไม่สามารถใช้อย่างนี้ได้
ที่เป็นเช่นนี้เพราะเราประกาศ implicit class MyString(str : String) นั่นเอง อย่างไรก้อตามเรามีข้อจำกัดในการประกาศใช้ implicit class ดังต่อไปนี้
1. implicit class ไม่สามารถเป็น top level class ได้ ต้องอยู่ภายใน object หรือ class หรือ trait อื่นๆ ในตัวอย่างที่เราดูกันก้ออยู่ภายใน object Helper
2. implicit class มี parameter ใน primary constructor ได้เพียงตัวเดียว เราไม่สามารถทำอย่างนี้ได้
implicit class MyString(str:String, n:Int)
3. ผู้ที่นำไปใช้ต้อง import object หรือ class หรือ trait ไปใช้งาน ในกรณีของเราคือ import Helper._
4. ห้ามตั้งชื่อ implicit class ตรงกับ top level class เราไม่สามารถใช้อย่างนี้ได้
object MyString {
implicit class MyString(str:String)
}
สำหรับผู้ที่ใช้ c# อยู่จะเห็นได้ว่าคล้ายๆ กับ extension method นั่นเอง สำหรับบทความต่อไปเราจะมาดู implicit parameter กันครับ
วันพฤหัสบดีที่ 14 พฤษภาคม พ.ศ. 2558
Scala Case Class
วันนี้เรามาดู case class กัน case class ก้อเหมือนกับ class ปรกติโดยทั้่วไป แต่มีคุณสมบัติพิเศษขึ้นมาคือ
- เราสามารถเรียกใช้ constructor parameter ได้ โดยที่ไม่ต้องประกาศ val หรือ var
- เราสร้าง instance ของ case class ได้โดยไม่ต้อง ใช้ new
- Scala จัดการให้เมทธอด equals, toString และ hashCode โดยอัตโนมัติ
- ในไปใช้ใน pattern matching ได้โดยง่าย
- เป็น Immutable object
เราลองมาดูตัวอย่างกัน
case class Dog(name:String, age:Int) {}
object Hello {
def main(args: Array[String]) {
var a = Dog("a", 1)
var b = Dog("a", 1)
println(a.name)
println(a==b)
}
}
จะเห็นได้ว่าเราสร้าง instance ของ Dog ขึ้นมาโดยที่ไม่ใช้ new เลย และยังเรียกใช้ name ได้โดยที่ไม่ได้ประกาศ val/var name เลย ที่เป็นเช่นนี้เพราะ case class จะ export constructor parameter ออกมาให้ใช้งานโดยอัตโนมัติ
นอกจากจะพิมพ์ name ออกมาแล้ว เรายัง check ว่า instance a == instance b หรือไม่ ในกรณีนี้เท่ากันครับ เราจะพิมพ์ true ออกมา ทำไมถึงเป็นอย่างนั้น เพราะว่า Scala จะทำเมทธอด equals และ hashCode ผ่านทาง constructor parameter
ถ้าใครใช้ java bean อยู่จะเห็นว่าเราจะต้อง overide equals/getHashCode/toString เองทุกครั้ง แต่ถ้าเป็น Scala เราไม่ต้องทำครับ มาดูอีกตัวอย่างหนึ่ง
abstract class Animal
case class Dog(name:String) extends Animal
case class Cat(name:String, age:Int) extends Animal
case class Fish() extends Animal
คราวนี้เรามี Animal เป็น base class และมี Dog/Cat/Fish extends Animal และเป็น case class
object Hello {
def main(args: Array[String]) {
toPrint(Fish())
toPrint(Dog("a"))
var d = Dog("c")
}
def toPrint(a : Animal) {
a match {
case Dog(name)=> {
println(name)
}
case Cat(name, age)=> {
println(name + ": + age")
}
case _ => {
println("not match")
}
}
}
}
สังเกตุว่าเมทธอด toPrint รับ instance ของ Animal เข้ามาแล้วเช็กดูว่าเป็น instance ประเภทไหน ถ้าเป็น Dog จะพิมพ์ name ถ้าเป็น Cat จะพิมพ์ name + age ถ้าไม่ใช่ทั้งคู่จะพิมพ์ not match ออกมา
วันนี้คงพอแค่นึ้ครับ ครั้งต่อไปเรามาดูเรื่อง Implicit กัน
วันอังคารที่ 12 พฤษภาคม พ.ศ. 2558
Extends Class and Implement Interface
วันนี้เราจะมาดูวิธีการ Mixin อีกแบบที่เรียกว่า Mixin Class Composition หรือที่เราเข้าใจง่ายๆ คือ การที่ class extends supper class แล้ว implement interface อีกด้วย ขอยกตัวอย่างจากบทความที่แล้วมาใช้ แต่ใช้ extends แทน สังเกตุว่าเราใช้ with Logger แทน
เราอาจจะอ่าน ง่ายๆ เป็นภาษาอังกฤษ ได้อย่างข้างล่างนี้
class FileDataSource extends (DataSource with Logger)
เราอาจจะอ่าน ง่ายๆ เป็นภาษาอังกฤษ ได้อย่างข้างล่างนี้
class FileDataSource extends (DataSource with Logger)
abstract class DataSource {
def otherMethod()
def read() : Boolean
def getString() : String
def printAll() {
while(this.read()) {
println(getString())
}
}
}
trait Logger {
def otherMethod() {}
def write(message: String) {
println(message)
}
}
class FileDataSource extends DataSource with Logger {
val max = 5
var count : Int = 0
def read() :Boolean = {
count = count + 1
return count < max
}
def getString():String = {
return "count=> " + count
}
}
ทีนี้เราลองมาดูวิธีใช้งานกัน คราวนี้เราสร้าง instance ของ FileDataSource โดยไม่มี with อีกแล้ว
object Hello {
def main(args: Array[String]) {
var a =new FileDataSource()
a.printAll()
a.write("done")
}
}
ข้อดีของ การ Mixin Class Compostion คือ การทำ multiple inheritance โดยอ้อมนั่นเอง อย่าลืมว่า Trait ไม่ใช่ interface ดังนั้นมันมีเมทธอดที่มี implementation (โค๊ด) และถ่ายทอดมาให้ subclass ใช้งานได้ ทีนี้ถ้าเกิดว่าเรา Mixin 2 interface ที่มีเมทธอดเหมือนกันแต่ implementation ต่างกันล่ะ ลองมาดูตัวอย่างข้างล่างกัน
trait OtherLogger {
def write(message:String) {
println("--->" + message)
}
}
class FileDataSource extends DataSource with Logger with OtherLogger {
...
เราจะ compile ไม่ผ่านครับ เนื่องจาก inheritance config จะเห็นได้ว่า เราทำ multiple inheritance ได้แต่ก้อยังคงกติกาที่ใช้เหมือนกับ single inheritance และนี่ทำให้ Scala flexible กว่า java และ c#
วันเสาร์ที่ 9 พฤษภาคม พ.ศ. 2558
Mixin in Scala
วันนี้เราจะมาดูเรื่องของ Mixin ใน ภาษา Scala กัน ก่อนอื่นผมอยากจะให้ดูนิยามของคำว่า Mixin ก่อนเผื่อว่าใครยังไม่คุ้นเคยกับคำนี้ นิยามต่อไปนี้ผมเอามาจาก Wiki (en.wikipedia.org/wiki/Mixin)
ก่อนอื่นต้องบอกว่าใน ภาษา Scala เราสามารถ Mixin class (mix methods and properties into some class) โดยการใช้ Trait และ keyword with
เรามาดูตัวอย่างกัน คราวนี้ FileDataSource ไม่ได้ extends DataSource อีกต่อไป สังเกตุว่า DataSource มีเมทธอด otherMethod แต่ FileDataSource ไม่มีและไม่เป็นไรเนื่องจาก FileDataSource ไม่ได้ extends DataSource
In object-oriented programming languages, a mixin is a class that contains a combination of methods from other classes. How such a combination is done depends on the language. If a combination contains all methods of combined classes, it is equivalent to multiple inheritance.
ก่อนอื่นต้องบอกว่าใน ภาษา Scala เราสามารถ Mixin class (mix methods and properties into some class) โดยการใช้ Trait และ keyword with
เรามาดูตัวอย่างกัน คราวนี้ FileDataSource ไม่ได้ extends DataSource อีกต่อไป สังเกตุว่า DataSource มีเมทธอด otherMethod แต่ FileDataSource ไม่มีและไม่เป็นไรเนื่องจาก FileDataSource ไม่ได้ extends DataSource
trait DataSource {
def otherMethod()
def read() : Boolean
def getString() : String
def printAll() {
while(this.read()) {
println(getString())
}
}
}
class FileDataSource {
val max = 5
var count : Int = 0
def read() :Boolean = {
count = count + 1
return count < max
}
def getString():String = {
return "count=> " + count
}
}
คราวนี้เรามี Trait เพิ่มอีกหนึ่ง และมีเมทธอด otherMethod และ write
trait Logger {
def otherMethod() {}
def write(message: String) {
println(message)
}
}
เรามาดูวิธี Mixin กัน ผมอยากจะ Mix in printAll จาก DataSource และ write จาก Logger ไปให้ FileDataSource ได้ใช้โดยที่ไม่ต้องการ inheritance เราทำได้ดังนี้
object Hello {
def main(args: Array[String]) {
var a =new FileDataSource() with DataSource with Logger
a.printAll()
a.write("done")
}
}
จะเห็นได้ว่าผมสร้าง instance ของ FileDataSource (ที่ไม่ได้ประกาศ printAll และ write) และ mix in DataSource และ Logger ให้ ด้วย keyword with หลังจากที่สร้าง instance a แล้ว ผมเรียกเมทธอด printAll จาก DataSource และ write จาก Logger ผลลัพธ์ที่พิมพ์ออกมาคือ
count=> 1
count=> 2
count=> 3
count=> 4
done
วันศุกร์ที่ 8 พฤษภาคม พ.ศ. 2558
Scala Trait
ใน Scala เราใช้ Trait มาแทน Interface ใน java/c# ข้อแตกต่างก้อคือ Trait มี method หรือ property ที่มีโค๊ดได้ ไม่จำเป็นที่ต้องรอ subclass มาทำให้ เราลองมาดูตัวอย่างกัน
trait DataSource {
var src : String
def read() : Boolean
def getString() : String
def printAll() {
while(this.read()) {
println(getString())
}
}
}
เราประกาศ trait DataSource ที่มี src เป็น string และยังไม่ได้กำหนดค่า และมี read() และ getString() เป็น abstract method ทั้งหมดนี้ subclass จะต้อง override ไม่เช่นนั้นจะ compile ไม่ผ่าน เราลองมาดู subclass กัน
class FileDataSource extends DataSource {
var src : String = "file"
val max = 5
var count : Int = 0
def read() :Boolean = {
count = count + 1
return count < max
}
def getString():String = { return src }
}
จะเห็นได้ว่า FileDataSource ได้ extends DataSource และ override read() กับ getString() รวมถึง กำหนดค่าให้กับ src และ max นอกจากนี้ยังเพิ่ม count เป็น data member ใหม่อีกด้วย ลองมาดูการทำงานกัน
object Hello {
def main(args: Array[String]) {
var a =new FileDataSource()
a.printAll()
}
}
โค๊ดข้างบนจะ พิมพ์
file
file
file
file
สำหรับบทความต่อไปเราจะมาดูวิธีการใช้ trait กันต่อ ในหัวข้อเรื่อง Mixin
วันพุธที่ 6 พฤษภาคม พ.ศ. 2558
Scala Abstract type
ใน Scala นอกจากจะมี Abstract class แล้วเรายังมี Abstract type ด้วย โดยปรกติ Abstract class จะประกอบไปด้วย property หรือ method ที่เป็น abstract (มีเพียงแค่ declaration แต่ยังไม่โค๊ด) แต่คราวนี้จะมีเพิ่มอีก abstract คือ type ที่ยังไม่ได้ประกาศว่าเป็น ชนิดอะไร เราลองมาดูตัวอย่างกันตามข้างล่างนี้
abstract class MyPoint {
type T //มี T แต่ยังไม่รู้ว่าเป็น type อะไร
var value : T //มี value ที่ประกาศว่าเป็นตัวแปรแบบ T
def print() {
println(value)
}
}
class Score extends MyPoint {
type T = Int //T เป็น Int
var value = 0
}
class Point extends MyPoint {
type T = (Int, Int) //T เป็น (int, int)
var value = (0,0)
}
เราประกาศ class MyPoint โดยที่ MyPoint มีการประกาศว่าเราจะมี value ที่เป็นข้อมูลชนิด T อย่างไรก้อตามเรายังไม่รู้ว่าเราจะใช้ T เป็น Int, Double, String ... เราจึงประกาศว่า เรายังไม่รู้ ณ ตอนนี้ เราใช้
type T
และประกาศให้ MyPoint เป็น abstract ถัดมาเราประกาศ class Score โดยที่ Score extends มาจาก MyPoint คราวนี้ Score ประกาศว่า T เป็น Int และ value เป็นค่าศูนย์
type T = Int
var value = 0
เรายังประกาศ Point เพิ่มอีก โดยที่ extends มาจาก MyPoint เช่นกัน และให้ T เป็นชนิดข้อมูลที่เก็บค่า Int 2 ตัว หรือ (Int, Int)
var T = (Int, Int)
var value = (0,0)
หมายเหตุ: ถ้าเราอยากเก็บ Int 3 ตัวเราก้อประกาศเป็น (Int, Int, Int) และเซ็ตค่าเป็น (0,0,0)
จะเห็นได้ว่าจากตัวอย่างข้างบนเราประกาศ abstract type ใน abstract class และ subclass จะประกาศว่า type ที่จะนำไปใช้งานคือชนิดไหน เราลองมาดูตัวอย่างกันเต็มๆ อีกที
ในเมทธอด Main เราสร้าง instance ของ Score และ Point แล้วพิมพ์ค่าของ value ออกมาดังต่อไปนี้
(0,0)
0
เราสามารถเขียน abstract type ให้สั้นกว่านี้ได้โดยใช้ [T] ได้ ลองมาดูตัวอย่างต่อไปนี้เราจะเขียน MyPoint, Score และ Point ใหม่
abstract class MyPoint[T] {
var value : T
def print() {
println(this.value)
}
}
class Score extends MyPoint[Int] {
var value = 10
}
class Point extends MyPoint[(Int, Int)] {
var value = (10,10)
}
จะเห็นได้ว่า เราใช้ MyPoint[T] และ subclass Score บอกว่า T คือ Int โดย extends MyPoint[Int] และ Point ประกาศว่า T เป็น (Int, Int) โดย extends MyPoint[(Int, Int)]
เรื่องของ abstract คงมีเพียงแค่นี้ บทความต่อไปจะเป็นเรื่อง Trait
สมัครสมาชิก:
บทความ (Atom)