Scala 언어 기초: 객체 지향 프로그래밍의 클래스 및 객체

스칼라는 자바, 파이썬과 같은 객체지향 언어로, 스칼라 객체지향에서 클래스와 객체의 개념과 예제를 설명한다.

1. 클래스

클래스와 개체는 Java 및 C++와 같은 개체 지향 프로그래밍의 기본 개념입니다. 클래스는 개체를 만들기 위한 청사진입니다. 클래스를 정의한 후 new 키워드를 사용하여 개체를 만들 수 있습니다.

클래스의 단순 인스턴스

클래스 정의의 가장 간단한 형태는 다음과 같습니다.

class Counter{
     //这里定义类的字段和方法
}

그런 다음 new 키워드를 사용하여 개체를 생성할 수 있습니다.

new Counter //或者new Counter()

속성 및 방법

이 클래스에 속성과 메서드를 추가해 보겠습니다.

class Counter {
    private var value = 0
    def increment(): Unit = { value += 1}
    def current(): Int = {value}
}

위의 정의에서 value 필드를 private로 설정하여 외부에서는 접근할 수 없고 클래스 내에서만 접근할 수 있는 private 필드가 되도록 했습니다. 필드 앞에 수정자가 없으면 기본적으로 공개되며 필드는 외부에서 액세스할 수 있습니다. 클래스의 경우 공개로 선언할 필요가 없으며 Scala 파일에 포함된 여러 클래스가 모두 서로에게 표시됩니다.

메서드의 정의는 def를 통해 구현한다. 위의 increment()는 매개변수가 없는 메소드로 콜론 뒤의 Unit은 반환값의 타입으로 Scala에서는 반환값이 없으면 Unit으로 표현하는데 Java의 void 타입에 해당한다. . 메서드의 반환 값은 반환 문에 의존할 필요가 없습니다. 메서드의 마지막 표현식 값은 메서드의 반환 값입니다. 예를 들어 현재() 메서드에는 "값" 문이 하나만 있습니다. 위에서 value의 값은 메서드 반환 값의 값입니다.

객체 생성

다음으로 새 개체를 만들고 해당 메서드를 호출합니다.

val myCounter = new Counter
myCounter.increment() //或者也可以不用圆括号,写成myCounter.increment
println(myCounter.current)

위의 코드에서 알 수 있듯이 Scala는 매개변수가 없는 메서드를 호출할 때 메서드 이름 뒤의 괄호를 생략할 수 있습니다.

컴파일 및 실행

이제 위의 전체 코드를 Linux 시스템에서 실행해 보겠습니다. Linux 시스템에 로그인한 후 명령줄 터미널을 열고(단축 키 조합 Ctr+Alt+T를 사용하여 명령줄 터미널을 빠르게 열 수 있음) "/usr/local/scala/mycode" 디렉토리를 입력한 다음 그런 다음 vim 편집기를 사용하여 다음과 같이 새 TestCounter.scala 코드 파일을 만듭니다.

cd /usr/local/scala/mycode
vim TestCounter.scala

TestCounter.scala에 다음 코드를 입력합니다.

class Counter {
    private var value = 0
    def increment(): Unit = { value += 1}
    def current(): Int = {value}
}
val myCounter = new Counter
myCounter.increment()
println(myCounter.current)

저장 후 vim 편집기를 종료하십시오. 그런 다음 scala 명령을 사용하여 이 코드 파일을 실행합니다.

scala TestCounter.scala

게터 및 세터

클래스의 필드에 대한 값을 설정하고 읽는 방법을 살펴보겠습니다. 아시다시피 Java에서는 getter 및 setter 메서드를 통해 이 작업을 수행합니다. Scala에서는 getter 및 setter 메소드 구현도 제공되지만 getXxx 및 setXxx로 정의되지 않습니다.

TestCounterJVM.scala 파일을 계속 수정합니다.

class Counter {
    var value = 0 //注意这里没有private修饰符,从而让这个变量对外部可见
    def increment(step: Int): Unit = { value += step}
    def current(): Int = {value}
}
object MyCounter{
    def main(args:Array[String]){
        val myCounter = new Counter
        println(myCounter.value)  //不是用getXxx获取字段的值
        myCounter.value = 3 //不是用setXxx设置字段的值
        myCounter.increment(1) //这里设置步长为1,每次增加1
        println(myCounter.current)
    }
}

이제 scalac 명령을 사용하여 위의 코드를 컴파일하고 오류가 보고됩니다. 개인 필드가 되어 외부에서 액세스할 수 없는 값 필드 앞에 private 수정자가 사용되기 때문입니다.
그러면 값이 비공개 필드가 된 후 Scala는 getter 및 setter 메서드를 제공하지 않습니다. 어떻게 값 필드에 액세스할 수 있습니까? 해결책은 Scala에서 value 및 value_=라고 하는 getter와 setter와 같은 메서드를 각각 다음과 같이 정의할 수 있다는 것입니다.

class Counter {
    private var privateValue = 0  //变成私有字段,并且修改字段名称
    def value = privateValue //定义一个方法,方法的名称就是原来我们想要的字段的名称
    def value_=(newValue: Int){
        if (newValue > 0) privateValue = newValue //只有提供的新值是正数,才允许修改
    }
    def increment(step: Int): Unit = { value += step}
    def current(): Int = {value}
}
object MyCounter{
    def main(args:Array[String]){
        val myCounter = new Counter
        println(myCounter.value)  //打印value的初始值
        myCounter.value = 3 //为value设置新的值
        println(myCounter.value)  //打印value的新值 
        myCounter.increment(1) //这里设置步长为1,每次增加1
        println(myCounter.current)
    }
}

이 파일을 컴파일하고 실행하면 세 줄의 실행 결과를 얻을 수 있는데 첫 번째 줄은 0, 두 번째 줄은 3, 세 번째 줄은 4입니다.

보조 생성자

Scala 생성자는 기본 생성자와 여러(0개 이상) 보조 생성자로 구성됩니다.
먼저 보조 생성자에 대해 알아보겠습니다. 보조 생성자의 이름은 이렇고 각 보조 생성자는 미리 정의된 보조 생성자나 기본 생성자를 호출해야 합니다.
보조 생성자로 클래스를 정의하고 위의 Counter 클래스 정의를 수정해 보겠습니다.

class Counter {
    private var value = 0 //value用来存储计数器的起始值
    private var name = "" //表示计数器的名称
    private var mode = 1 //mode用来表示计数器类型(比如,1表示步数计数器,2表示时间计数器)
    def this(name: String){ //第一个辅助构造器
        this() //调用主构造器
        this.name = name
    }
    def this (name: String, mode: Int){ //第二个辅助构造器
        this(name) //调用前一个辅助构造器
        this.mode = mode
    }
    def increment(step: Int): Unit = { value += step}
    def current(): Int = {value}
    def info(): Unit = {printf("Name:%s and mode is %d\n",name,mode)}
}
object MyCounter{
    def main(args:Array[String]){
        val myCounter1 = new Counter  //主构造器
        val myCounter2 = new Counter("Runner") //第一个辅助构造器,计数器的名称设置为Runner,用来计算跑步步数
        val myCounter3 = new Counter("Timer",2) //第二个辅助构造器,计数器的名称设置为Timer,用来计算秒数
        myCounter1.info  //显示计数器信息
        myCounter1.increment(1)     //设置步长  
        printf("Current Value is: %d\n",myCounter1.current) //显示计数器当前值
        myCounter2.info  //显示计数器信息
        myCounter2.increment(2)     //设置步长  
        printf("Current Value is: %d\n",myCounter2.current) //显示计数器当前值
        myCounter3.info  //显示计数器信息
        myCounter3.increment(3)     //设置步长  
        printf("Current Value is: %d\n",myCounter3.current) //显示计数器当前值

    }
}

위의 코드를 컴파일하고 실행하면 다음과 같은 결과를 얻습니다.

Name: and mode is 1
Current Value is: 1
Name:Runner and mode is 1
Current Value is: 2
Name:Timer and mode is 2
Current Value is: 3

기본 생성자

Scala의 모든 클래스에는 기본 생성자가 있습니다. 그러나 Scala의 기본 생성자는 Java와 크게 다릅니다.Scala의 기본 생성자는 전체 클래스 본문이며 생성자에 필요한 모든 매개 변수는 클래스 이름 뒤에 나열되어야 합니다.이 매개 변수는 필드로 컴파일되며 필드의 값은 개체를 만들 때 전달된 매개 변수의 값입니다.
카운터의 이름과 모드를 설정하는 위의 예에서 방금 보조 생성자를 사용하여 이름과 모드의 값을 설정했습니다. 이제 다시 수행합니다. 이번에는 주 생성자를 사용하여 이름과 모드의 값을 설정합니다. .

class Counter(val name: String, val mode: Int) {
    private var value = 0 //value用来存储计数器的起始值    
    def increment(step: Int): Unit = { value += step}
    def current(): Int = {value}
    def info(): Unit = {printf("Name:%s and mode is %d\n",name,mode)}
}
object MyCounter{
    def main(args:Array[String]){       
        val myCounter = new Counter("Timer",2)
        myCounter.info  //显示计数器信息
        myCounter.increment(1)  //设置步长  
        printf("Current Value is: %d\n",myCounter.current) //显示计数器当前值       
    }
}

위의 코드를 컴파일하고 실행하면 다음과 같은 결과를 얻습니다.

Name:Timer and mode is 2
Current Value is: 1

2. 개체

싱글톤 객체

Scala는 Java와 같은 정적 메소드나 정적 필드를 제공하지 않지만 object 키워드를 사용하여 Java 정적 메소드와 동일한 기능을 가진 싱글톤 객체를 구현할 수 있습니다.

object Person {
    private var lastId = 0  //一个人的身份编号
    def newPersonId() = {
        lastId +=1
        lastId
    }
}

위의 정의에서 알 수 있듯이 싱글톤 객체의 정의는 클래스의 정의와 매우 유사하지만 class 키워드 대신 object 키워드를 사용한다는 점에서 분명한 차이점이 있습니다.
클래스 관리 시스템이 있다고 가정하면 새 클래스 구성원이 도착할 때마다 식별 번호가 할당됩니다. 첫 번째 사람이 클래스에 참여하면 Person.newPersonId()를 호출하여 ID를 얻을 수 있습니다.

동반자 개체

Java에서는 인스턴스 메서드와 정적 메서드를 모두 포함하는 클래스를 사용해야 하는 경우가 종종 있는데, Scala에서는 컴패니언 객체를 통해 이를 달성할 수 있습니다. 싱글톤 객체가 클래스와 이름이 같은 경우 해당 클래스의 "컴패니언 객체"라고 합니다. 클래스와 동반 개체는 동일한 파일에 있어야 하며 전용 멤버(필드 및 메서드)에 대한 상호 액세스 권한이 있어야 합니다.

다음은 컴패니언 객체를 사용하는 방법을 예제를 통해 보여줍니다. "/usr/local/scala/mycode" 디렉토리에서 vim 편집기를 사용하여 test.scala를 다시 만들고 파일에 다음 코드를 입력합니다.

class Person {
    private val id = Person.newPersonId() //调用了伴生对象中的方法
    private var name = ""
    def this(name: String) {
        this()
        this.name = name
    }
    def info() { printf("The id of %s is %d.\n",name,id)}
}
object Person {
    private var lastId = 0  //一个人的身份编号
    private def newPersonId() = {
        lastId +=1
        lastId
    }
    def main(args: Array[String]){
        val person1 = new Person("xiaoming")
        val person2 = new Person("xiaohong")
        person1.info()
        person2.info()      
    }
}

컴패니언 객체에 정의된 newPersonId()는 실제로 Java에서 정적 메서드의 기능을 구현하므로 인스턴스화된 객체 person1의 newPersonId()를 호출하여 반환되는 값은 1이고 인스턴스화된 객체의 newPersonId()를 호출하여 반환되는 값은 1입니다. 객체 person2는 2입니다. 우리가 말했듯이 Scala 소스 코드는 컴파일 후 JVM 바이트코드가 됩니다. 인스턴스 멤버, 개체 멤버는 정적 멤버가 되었습니다.

응용 프로그램 객체

모든 Scala 애플리케이션은 객체의 메인 메소드로 시작해야 하는데, 앞에서 소개한 HelloWorld 프로그램이 아주 전형적인 예입니다.
"/usr/local/scala/mycode" 디렉토리에서 vim 편집기로 test.scala를 다시 만들고 파일에 다음 코드를 입력할 수 있습니다.

object HelloWorld {
    def main(args: Array[String]){
        println("Hello, World!")
    }
}

위의 코드를 실행하기 위해 이제 두 가지 다른 방법을 사용할 수 있습니다.
첫 번째 방법: 직접 scala 명령을 실행하여 결과를 얻습니다.
이 코드에는 클래스가 정의되어 있지 않기 때문에 싱글톤 객체이므로 컴파일하지 않고 바로 scala 명령어를 실행하여 결과를 얻을 수 있습니다.

cd /usr/local/scala/mycode
scala test.scala

업데이트 적용

우리는 객체의 apply 메소드와 update 메소드를 자주 사용하는데 표면적으로는 인지하지 못하지만 사실 Scala에서는 적용 메소드와 update 메소드를 관련 규약에 따라 호출하게 됩니다. 괄호를 사용하여 전달 변수(객체)에 하나 이상의 매개변수를 할당할 때 Scala는 이를 적용 메서드에 대한 호출로 변환합니다. 개체를 호출합니다. 업데이트 메서드는 호출 시 대괄호 안의 매개 변수와 등호 오른쪽의 개체를 모두 업데이트 메서드의 입력 매개 변수로 사용하여 호출을 실행합니다.

다음으로 apply 메서드가 호출되는지 테스트합니다. Linux 시스템의 "/usr/local/scala/mycode/test.scala" 파일에 다음 코드를 입력할 수 있습니다.

class TestApplyClass {
    def apply(param: String): String = {
        println("apply method called, parameter is: " + param)
        "Hello World!"
    }
}
val myObject = new TestApplyClass
println(myObject("param1"))

실행하면 다음과 같은 결과가 나타납니다.

apply method is called, parameter is:param1
Hello World!

println(myObject("param1")) 문을 주석 처리하면 위의 결과가 나타나지 않습니다. 실제로 apply 메소드가 호출되는 것을 볼 수 있으며, myObject("param1")가 실행될 때 호출되는 것을 알 수 있다. 인쇄.

적용 방법은 이전에 소개했지만 실제로 업데이트 방법은 비슷합니다(관심 있는 독자는 업데이트 방법을 테스트하는 방법에 대한 온라인 정보를 찾을 수 있으므로 여기에서 자세히 설명하지 않겠습니다).

val myStrArr = new Array[String](3) //声明一个长度为3的字符串数组,每个数组元素初始化为null
myStrArr(0) = "BigData" //实际上,调用了伴生类Array中的update方法,执行myStrArr.update(0,"BigData")
myStrArr(1) = "Hadoop" //实际上,调用了伴生类Array中的update方法,执行myStrArr.update(1,"Hadoop")
myStrArr(2) = "Spark" //实际上,调用了伴生类Array中的update方法,执行myStrArr.update(2,"Spark")

튜플 할당을 할 때 Java에서 대괄호 myStrArr[0]을 사용하지 않고 괄호 형태인 myStrArr(0)을 사용하는 이유는 위에서 언급한 업데이트 방식 때문임을 위에서 알 수 있다. 메커니즘 .

참조 링크:

http://dblab.xmu.edu.cn/blog/spark/

https://www.runoob.com/scala/scala-tutorial.html

역사 추천

엄마는 더 이상 이중 시스템 설치에 대해 걱정할 필요가 없습니다!

Spark 기계 학습: 모델 평가 지표

Spark 기계 학습: 빈번한 패턴 마이닝

파충류 전투: Selenium은 Jingdong 제품을 크롤링합니다.

파충류 전투: Douban 영화 top250 크롤링

파충류 전투: QQ 음악을 크롤링하는 Scrapy 프레임워크

데이터 분석 및 마이닝

데이터 구조 및 알고리즘

기계 학습 및 빅 데이터 구성 요소

관심을 가져 주셔서 감사합니다. "시청"해주셔서 감사합니다. 운명을 따르는 것은 드뭅니다 ~

 

Supongo que te gusta

Origin blog.csdn.net/qq_36936730/article/details/106132543
Recomendado
Clasificación