Scala Object 의 구체 적 인 사용(소결)
앞에서 Scala Methods 를 배 웠 고,이어서 Scala 의 Object 를 배 웠 습 니 다.
2.개체
Object 는 Scala 에 두 가지 의미 가 있 습 니 다.자바 에 서 는 하나의 인 스 턴 스 를 대표 합 니 다.Scala 에 서 는 하나의 키워드 입 니 다.이 편 은 먼저 object 를 하나의 인 스 턴 스 로 보고 대상 을 하나의 유형 에서 다른 유형 으로 바 꾸 는 방법 을 보 여 줍 니 다.그 다음 에 하나의 대상 을 만 드 는 방법 을 보 여 줍 니 다.Scala 에 가방 대상 도 존재 합 니 다.Scala 에 서 는 다음 과 같은 정의 가 자주 있 습 니 다.
type Throwable = java.lang.Throwable
type Exception = java.lang.Exception
type Error = java.lang.Error
type Seq[+A] = scala.collection.Seq[A]
val Seq = scala.collection.Seq
type 정 의 를 사용 하면 코드 를 더욱 간결 하 게 할 수 있 습 니 다.동반 대상 을 사용 하여 정적 방법 을 만 들 수 있 고 동반 대상 은 클래스 대상 을 만 들 때 new 키 워드 를 사용 하지 않 아 도 됩 니 다.다음 과 같 습 니 다.
val siblings = List(Person("Kim"), Person("Julia"), Person("Kenny"))
2.1 대상 전환1.문제 설명
동적 생 성 대상 과 같은 인 스 턴 스 를 하나의 유형 에서 다른 유형 으로 바 꿔 야 합 니 다.
2.해결 방안
asInstanceOf 방법 으로 유형 전환 을 진행 합 니 다.다음 lookup 방법 으로 돌아 오 는 대상 은 Recognizer 대상 으로 전 환 됩 니 다.
val recognizer = cm.lookup("recognizer").asInstanceOf[Recognizer]
이상 코드 는 자바 에서 다음 과 같 습 니 다.
Recognizer recognizer = (Recognizer)cm.lookup("recognizer");
asInstanceOf 방법 은 Any 클래스 에 정의 되 어 있 기 때문에 모든 클래스 에서 이 방법 을 사용 할 수 있 습 니 다.3.토론
동적 프로 그래 밍 에 서 는 하나의 클래스 에서 다른 클래스 로 전환 해 야 합 니 다.예 를 들 어 Spring 프레임 워 크 에서 applicationContext 파일 을 사용 하여 Bean 을 초기 화 합 니 다.
// open/read the application context file
val ctx = new ClassPathXmlApplicationContext("applicationContext.xml")
// instantiate our dog and cat objects from the application context
val dog = ctx.getBean("dog").asInstanceOf[Animal]
val cat = ctx.getBean("cat").asInstanceOf[Animal]
디지털 형식 전환 을 할 때 도 asInstanceOf 방법 을 사용 할 수 있다.자바 와 의 대화 가 필요 할 때 asInstanceOf 방법 을 사용 할 수 있 습 니 다.
val objects = Array("a", 1)
val arrayOfObject = objects.asInstanceOf[Array[Object]]
AJavaClass.sendObjects(arrayOfObject)
자바 와 유사 하 며,유형 전환 은 ClassCastException 이상 을 던 질 수 있 습 니 다.try/catch 를 사용 하여 이 문 제 를 해결 할 수 있 습 니 다.
2.2 자바 의 class 와 대응 하 는 방법
1.문제 설명
API 가 클 라 스 대상 을 전달 해 야 할 때 자바 에 서 는.class 를 사용 할 수 있 지만 스칼라 에 서 는 통 하지 않 습 니 다.
2.해결 방안
Scala 의 classOf 방법 을 사용 하면 다음 과 같 습 니 다.
val info = new DataLine.Info(classOf[TargetDataLine], null)
자바 에 서 는 다음 과 같이 사용 합 니 다.
info = new DataLine.Info(TargetDataLine.class, null);
classOf 방법 은 Predef 대상 에 정의 되 어 있 기 때문에 import 없 이 직접 사용 할 수 있 습 니 다.3.토론
이 방법 은 반 사 를 배우 기 시작 할 수 있 습 니 다.다음 예제 에서 String 류 를 방문 할 수 있 는 방법 입 니 다.
2.3 대상 을 정 하 는 클래스
1.문제 설명
Scala 에 서 는 표시 할 필요 가 없 는 성명 형식 입 니 다.가끔 은 대상 의 클래스 나 형식 을 인쇄 하여 Scala 의 작업 체 제 를 알 고 싶 습 니 다.
2.해결 방안
대상 의 getClass 방법 을 사용 하여 Scala 가 자동 으로 값 을 부여 하 는 유형 을 확인 할 수 있 습 니 다.가 변 적 인 매개 변수 작업 절 차 를 알 아야 할 때 getClass 방법 을 사용 하여 상황 에 따라 유형 도 다 릅 니 다.
def printAll(numbers: Int*) {
println("class: " + numbers.getClass)
}
여러 개의 매개 변 수 를 사용 하여 printAll 방법 을 호출 하 는 것 과 매개 변 수 를 사용 하지 않 고 printAll 방법 을 호출 하 는 것 은 결과 가 다 릅 니 다.스칼라 의 XML 라 이브 러 리 를 처리 할 때 이 방법 은 매우 효과 적 입 니 다.서로 다른 상황 에서 처리 하 는 클래스 를 알 수 있 습 니 다.다음 과 같 습 니 다.
탭 에 하위 클래스 가 포함 되 어 있 습 니 다.
탭 에
탭 을 추가 하면 그 결 과 는 다음 과 같 습 니 다.
3.토론
IDE 에서 대상 의 종 류 를 알 수 없 으 면 getClass 방법 으로 대상 종 류 를 가 져 올 수 있 습 니 다.
2.4 사용 대상 시작 응용
1.문제 설명
main 방법 으로 프로그램 을 시작 하거나 스 크 립 트 에 입 구 를 제공 하려 고 합 니 다.
2.해결 방안
응용 프로그램 을 시작 하 는 데 는 두 가지 방법 이 있 는데 하 나 는 응용 프로그램 을 계승 하 는 것 이 고,다른 하 나 는 대상 을 정의 하고 main 방법 을 정의 하 는 것 이다.
첫 번 째 방법 에 대해 그 통용 방법 은 다음 과 같다.
object Hello extends App {
println("Hello, world")
}
이 때 object 내 문 구 는 자동 으로 실 행 됩 니 다.두 번 째 방법 은 main 방법 을 정의 하 는 것 입 니 다.
object Hello2 {
def main(args: Array[String]) {
println("Hello, world")
}
}
3.토론상기 두 가지 방법 중 모두 object 를 통 해 응용 을 시작 합 니 다.
2.5 Object 를 사용 하여 단일 예 만 들 기
1.문제 설명
단일 대상 을 만 들 려 고 합 니 다.
2.해결 방안
object 키 워드 를 사용 하여 단일 대상 을 만 듭 니 다.
object Hello2 {
def main(args: Array[String]) {
println("Hello, world")
}
}
CashRegister 는 object 로 정의 되 기 때문에 하나의 인 스 턴 스 만 있 고 호출 된 방법 은 자바 의 정적 방법 에 해당 합 니 다.다음 과 같이 호출 됩 니 다.
object Main extends App {
CashRegister.open
CashRegister.close
}
도구 방법 을 만 들 때 도 이 방법 은 유효 합 니 다.
import java.util.Calendar
import java.text.SimpleDateFormat
object DateUtils {
// as "Thursday, November 29"
def getCurrentDate: String = getCurrentDateTime("EEEE, MMMM d")
// as "6:20 p.m."
def getCurrentTime: String = getCurrentDateTime("K:m aa")
// a common function used by other date/time functions
private def getCurrentDateTime(dateTimeFormat: String): String = {
val dateFormat = new SimpleDateFormat(dateTimeFormat)
val cal = Calendar.getInstance()
dateFormat.format(cal.getTime())
}
}
방법 은 object 에 정의 되 어 있 기 때문에 DateUtils 를 직접 사용 하여 이 방법 을 호출 할 수 있 습 니 다.예 를 들 어 자바 에서 정적 방법 을 호출 하 는 것 과 같 습 니 다.
DateUtils.getCurrentDate
DateUtils.getCurrentTime
actors 를 사용 할 때 단일 대상 은 다시 사용 할 수 있 는 메 시 지 를 만 들 수 있 습 니 다.메 시 지 를 받 아들 이 고 보 낼 수 있 는 actor 가 있다 면 다음 과 같은 방법 으로 단일 예 를 만 들 수 있 습 니 다.
case object StartMessage
case object StopMessage
이 대상 들 은 메시지 로 전달 되 며,actor 에 전 달 될 수 있 습 니 다.
inputValve ! StopMessage
outputValve ! StopMessage
3.토론동반 대상 을 사용 할 때 한 가지 유형 은 비정 상 방법 도 있 고 정태 적 인 방법 도 있 을 수 있다.
2.6 동반 대상 을 사용 하여 정적 구성원 만 들 기
1.문제 설명
클래스 를 위 한 인 스 턴 스 방법 과 클래스 방법 을 만 들 려 고 하지만 Scala 에는 static 키워드 가 없습니다.
2.해결 방안
class 에서 비정 상 구성원 을 정의 하고 object 에서 정적 구성원 을 정의 합 니 다.대상 과 클래스 는 같은 이름 을 가지 고 같은 파일 에 있어 야 합 니 다.이 대상 을 반생 대상 이 라 고 합 니 다.
이 방법 을 사용 하면 정적 구성원(필드 와 방법)을 만 들 수 있 습 니 다.
// Pizza class
class Pizza (var crustType: String) {
override def toString = "Crust type is " + crustType
}
// companion object
object Pizza {
val CRUST_TYPE_THIN = "thin"
val CRUST_TYPE_THICK = "thick"
def getFoo = "Foo"
}
Pizza 클래스 와 Pizza 대상 은 같은 파일 에 있 습 니 다(Pizza.scala).Pizza 대상 의 구성원 은 자바 클래스 의 정적 구성원 과 같 습 니 다.
println(Pizza.CRUST_TYPE_THIN)
println(Pizza.getFoo)
너 도 일반적인 방법 에 따라 피자 대상 을 만 들 수 있다.
var p = new Pizza(Pizza.CRUST_TYPE_THICK)
println(p)
3.토론class 와 object 는 같은 이름 을 가지 고 같은 파일 에서 class 에서 비정 상 구성원 을 정의 합 니 다.object 에서 정 의 된 것 은 정적 구성원 입 니 다.
class 와 그 동반 대상 은 서로 상대방 의 개인 구성원 을 방문 할 수 있 습 니 다.예 를 들 어 아래 object 의 double 방법 은 class 의 개인 변수 secret 에 접근 할 수 있 습 니 다.
class Foo {
private val secret = 2
}
object Foo {
// access the private class field 'secret'
def double(foo: Foo) = foo.secret * 2
}
object Driver extends App {
val f = new Foo
println(Foo.double(f)) // prints 4
}
다음 class 클래스 의 비정 상 방법 은 동반 대상 의 정적 개인 변 수 를 방문 할 수 있 습 니 다.
class Foo {
// access the private object field 'obj'
def printObj { println(s"I can see ${Foo.obj}") }
}
object Foo {
private val obj = "Foo's object"
}
object Driver extends App {
val f = new Foo
f.printObj
}
2.7 상용 코드 를 가방 대상 에 넣 기1.문제 설명
클 라 스 나 object 가 필요 없 이 방법,필드,다른 코드 를 패키지 단계 에 두 고 싶 습 니 다.
2.해결 방안
패키지 대상 아래 에 코드 를 배치 합 니 다.예 를 들 어,코드 를 com.hust.grid.leesf.model 에 의 해 모든 종 류 를 사용 할 수 있 도록 패키지 에 넣 으 려 면 com/hust/grid/leesf/model 디 렉 터 리 에 있 는 package.scala 파일 을 만 듭 니 다.package.scala 에서 패키지 성명 에서 model 을 제거 하고 이름 으로 가방 을 만 듭 니 다.대체로 아래 와 같다
package com.hust.grid.leesf
package object model {
다른 코드 는 model 에 놓 여 있 습 니 다.다음 과 같 습 니 다.
package com.hust.grid.leesf
package object model {
// field
val MAGIC_NUM = 42
// method
def echo(a: Any) { println(a) }
// enumeration
object Margin extends Enumeration {
type Margin = Value
val TOP, BOTTOM, LEFT, RIGHT = Value
}
// type definition
type MutableMap[K, V] = scala.collection.mutable.Map[K, V]
val MutableMap = scala.collection.mutable.Map
}
이때,com.hust.grid.leesf.model 패키지 아래 클래스,대상,인터페이스 등에 서 상기 정 의 된 필드,방법 등 을 임의로 방문 할 수 있 습 니 다.
package com.hust.grid.leesf.model
object MainDriver extends App {
// access our method, constant, and enumeration
echo("Hello, world")
echo(MAGIC_NUM)
echo(Margin.LEFT)
// use our MutableMap type (scala.collection.mutable.Map)
val mm = MutableMap("name" -> "Al")
mm += ("password" -> "123")
for ((k,v) <- mm) printf("key: %s, value: %s
", k, v)
}
3.토론가장 의 심 스 러 운 것 은 패키지 대상 을 어디 에 두 었 는 지,가방 이름과 대상 명 이다.
코드 를 com.hust.grid.leesf.model 가방 에서 보 려 면 package.scala 를 com/hust/grid/leesf/model 디 렉 터 리 에 두 고 package.scala 에 서 는 가방 이름 이 다음 과 같 아야 합 니 다.
package com.hust.grid.leesf
그리고 model 을 대상 으로 합 니 다.
package object model {
마지막 으로 대체로 다음 과 같다.
package com.hust.grid.leesf
package object model {
가방 에 매 거 진 형식,상수,암시 적 변환 을 저장 할 수 있 습 니 다.2.8 new 키 워드 를 사용 하지 않 고 대상 인 스 턴 스 를 만 듭 니 다.
1.문제 설명
new 키 워드 를 사용 하지 않 고 대상 을 만 들 때 Scala 코드 는 상대 적 으로 간결 해 보 입 니 다.다음 과 같 습 니 다.
val a = Array(Person("John"), Person("Paul"))
2.해결 방안두 가지 방법 이 있어 요.
class Person {
var name: String = _
}
object Person {
def apply(name: String): Person = {
var p = new Person
p.name = name
p
}
}
이제 뉴 키 워드 를 사용 하지 않 고 Person 대상 을 만 들 수 있 습 니 다.
val dawn = Person("Dawn")
val a = Array(Person("Dan"), Person("Elijah"))
Scala 컴 파 일 러 는 짝 짓 기 대상 중의 apply 를 특수 처리 하여 new 키 워드 를 사용 하지 않 고 대상 을 만 들 수 있 도록 합 니 다.클래스 를 case 클래스 로 정의 하고 해당 하 는 매개 변 수 를 받 아들 입 니 다.
case class Person (var name: String)
현재 다음 과 같은 방법 으로 대상 을 만 들 수 있 습 니 다.
val p = Person("Fred Flinstone")
Scala 는 케이스 클래스 의 동반 대상 을 위해 apply 방법 을 만 듭 니 다.3.토론
컴 파일 러 는 동반 대상 의 apply 를 특수 처리 합 니 다.이것 은 Scala 의 문법 사탕 입 니 다.
val p = Person("Fred Flinstone")
상기 코드 는 다음 과 같은 코드 로 바 뀔 것 이다.
val p = Person.apply("Fred Flinstone")
apply 방법 은 공장 방법 입 니 다.Scala 의 이 문법 사탕 은 new 키 워드 를 사용 하지 않 고 대상 을 만 들 수 있 습 니 다.반생 대상 에 여러 개의 apply 방법 을 만 들 수 있 습 니 다.이것 은 여러 개의 구조 함수 에 해당 합 니 다.
class Person {
var name = ""
var age = 0
}
object Person {
// a one-arg constructor
def apply(name: String): Person = {
var p = new Person
p.name = name
p
}
// a two-arg constructor
def apply(name: String, age: Int): Person = {
var p = new Person
p.name = name
p.age = age
p
}
}
다음 방법 으로 대상 을 만 들 수 있 습 니 다.
val fred = Person("Fred")
val john = Person("John", 42)
케이스 클래스 에 여러 개의 구조 함 수 를 만 들 기 위해 서 는 케이스 클래스 뒤의 논 리 를 알 아야 합 니 다.scala 컴 파일 러 를 사용 하여 case 클래스 를 컴 파일 할 때,Person$.class 와 Person.class 파일 두 개 를 생 성 합 니 다.javap 를 사용 하여 Person$.class 파일 을 컴 파일 할 때 출력 은 다음 과 같 습 니 다.
Person 대상 으로 돌아 가 는 apply 방법 을 포함 하고 있 습 니 다.
public Person apply(java.lang.String);
String 은 case 클래스 의 name 에 대응 합 니 다.
case class Person (var name: String)
javap 명령 을 사용 하면 Person.class 에서 name 을 위 한 getter 와 setter 함 수 를 볼 수 있 습 니 다.다음 코드 에는 케이스 클래스 와 apply 방법 이 존재 합 니 다.
// want accessor and mutator methods for the name and age fields
case class Person (var name: String, var age: Int)
// define two auxiliary constructors
object Person {
def apply() = new Person("<no name>", 0)
def apply(name: String) = new Person(name, 0)
}
name 과 age 는 모두 var 이기 때문에 getter 와 setter 를 생 성하 고 object 에서 두 개의 apply 함 수 를 정의 하기 때문에 다음 과 같은 세 가지 방식 으로 Person 대상 을 생 성 할 수 있 습 니 다.
object Test extends App {
val a = Person()
val b = Person("Al")
val c = Person("William Shatner", 82)
println(a)
println(b)
println(c)
// test the mutator methods
a.name = "Leonard Nimoy"
a.age = 82
println(a)
}
그 결 과 는 다음 과 같다.
Person(<no name>,0)
Person(Al,0)
Person(William Shatner,82)
Person(Leonard Nimoy,82)
2.9 apply 를 사용 하여 공장 방법 을 실현 한다.1.문제 설명
하위 클래스 가 어떤 유형의 대상 을 만들어 야 하 는 지,그리고 한 곳 에서 만 대상 을 만 들 수 있 도록 공장 방법 을 실현 하고 싶 습 니 다.
2.해결 방안
동반 대상 의 apply 방법 을 사용 하여 공장 방법 을 실현 할 수 있 으 며,공장 실현 알고리즘 을 apply 방법 에 배치 할 수 있 습 니 다.
Animal 공장 을 만 들 고 Cat 과 Dog 로 돌아 가 Animal 류 의 동반 대상 에서 apply 방법 을 실현 하려 면 다음 과 같은 방식 으로 다른 대상 을 만 들 수 있 습 니 다.
val cat = Animal("cat") // creates a Cat
val dog = Animal("dog") // creates a Dog
우선 Animal trait 를 만들어 야 합 니 다.
trait Animal {
def speak
}
그 다음 에 같은 파일 에 동반 대상 을 만 들 고 Animal 을 실현 하 는 클래스 를 만 들 며 적당 한 apply 방법 을 만 듭 니 다.
object Animal {
private class Dog extends Animal {
override def speak { println("woof") }
}
private class Cat extends Animal {
override def speak { println("meow") }
}
// the factory method
def apply(s: String): Animal = {
if (s == "dog") new Dog
else new Cat
}
}
그리고 다음 문 구 를 사용 하여 서로 다른 대상 을 만 들 수 있 습 니 다.
val cat = Animal("cat") // creates a Cat
val dog = Animal("dog") // creates a Dog
3.토론apply 방법 을 사용 하지 않 으 면 다음 과 같은 getAnimal 방법 으로 이 기능 을 실현 할 수 있 습 니 다.
// an alternative factory method (use one or the other)
def getAnimal(s: String): Animal = {
if (s == "dog") return new Dog
else return new Cat
}
그리고 다음 과 같은 방법 으로 다른 대상 을 만 들 수 있 습 니 다.
val cat = Animal.getAnimal("cat") // returns a Cat
val dog = Animal.getAnimal("dog") // returns a Dog
이상 의 두 가지 방법 은 모두 실행 가능 하 다.3.총화
이 편 은 스칼라 의 object 와 그 에 상응하는 용법 을 배 웠 는데 스칼라 의 실제 프로 그래 밍 에서 도 매우 광범 위 하 게 응용 되 었 다.
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
sbt-native-packager로 docker 이미지의 기반을 amazoncorretto로 만들고 싶습니다.build.sbt에 다음을 추가합니다. 그런데 에서 빌드하려고하면 같은 오류가 발생하여 실패합니다 생성 된 Dockerfile을 들여다 보면 같은 행이 있습니다. 이지만 amazonlinux에서는 addgroup 또...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.