11.方法


メソッドは、特定のタイプに関連付けられた関数です.クラス、構造体、および列挙型は、特定のタスクおよび機能をサポートする方法を定義して、特定のタイプのインスタンス操作を実行することができる.また、タイプ自体に関連するタイプメソッドを定義することもできます.

インスタンスメソッド

  • インスタンスメソッドは、特定のクラス、構造体、および列挙型インスタンスに属する関数である.インスタンス・プログラムへのアクセスと変更方法を提供し、さまざまな有益な機能を提供します.インスタンスメソッドは、関数で説明したように、関数構文と完全に同じです.また、これは、自分が属するタイプの特定のインスタンスで呼び出す必要があります.
  • class Counter {
    	var count = 0
        func increment() {
        	count += 1
        }
        
        func increment(by amount : Int) {
        	count =+ amount
        }
       	
        func reset() {
        	count = 0
        }
    }
    // Counter클래스는 3개의 인스턴스 메서드를 정의한다.
    //각 인스턴스 메서드는 호출에 따라서 count프로퍼티에 대한 기능을 적용한다. 
    
    let counter = Counter()
    //인스턴스 생성
    counter.increment()
    //count = 1
    counter.increment(by: 5)
    //count = 6
    counter.reset()
    //count = 0

    自己保護

  • タイプのすべてのインスタンスは、インスタンス自体と完全に一致するselfの暗示的特徴を有する.独自のインスタンスメソッドではself propertyを使用して現在のインスタンスを参照します.
  • func increment() {
    	self.count += 1
    }
    //다음과 같이 위의 increment메서드는 작성이 가능하다. 
    //실제 코드에서는 self를 작성할 필요가 없다. self를 명시적으로 작성하지 않으면,
    //Swift는 메서드 내에서 이미 알고있는 프로퍼티나 메서드를 사용할때마다
    //현재 인스턴스의 프로퍼티나 메서드를 참조한다고 가정하기 때문이다.
    //하지만 인스턴스 메서드에 파라미터 명이 인스턴스 프로퍼티와 동일할 때 명시해야 한다.
    
    struct point {
    	var x = 0.0, y = 0.0
        
        func isToTheRightOf(x : Double) -> Bool {
        	return self.x > x
        }
    }
    //리턴하는 값에서 파라미터는 그냥 x이며, 인스턴스의 프로퍼티는 self.x를 통해서 분별하였다.

    インスタンスメソッドの値タイプの変更

  • 辞書に記載されているように、構造体および列挙型は値タイプである.デフォルトでは、値タイプのプロパティはインスタントメソッドでは変更できません.ただし、特定のメソッドの構造または列挙形式の構成を変更する必要がある場合は、メソッドの動作を変更することを選択できます.このメソッドでは、メソッド内でPropertyを変更できます.メソッドが完了すると、既存の構造体に変更が作成されます.このメソッドは、暗黙的self propertyに新しいインスタンスを割り当て、新しいインスタンスはメソッドの終了後に既存のインスタンスを置き換えます.これにより、mutatingキーワードをfuncの前に操作することができます.
  • struct Point {
    	var x = 0.0
        var y = 0.0
        
        mutating func moveBy(x deltaX : Double, y deltaY : Double) {
        	x += deltaX
            y += deltaY
        }
    }
    
    var somePoint = Point(x : 1.0, y : 1.0)
    //somePoint 구조체 값을 설정한다.
    somePoint.moveBy(x: 2.0, y : 3.0)
    print(somePoint.x, somePoint.y)
    //3.0, 4.0을 출력하게 된다.
    //구조체는 값 타입으로 이를 외부 메소드로 변경할 수 없으나, 
    //내부에서 메서드 값 수정을 위한 함수를 설정하여 조정이 가능하다. 
    //그리고 이를 변수값으로 사전에 정의한 것도 포인트.
  • 定数構造体インスタンスのストレージプロパティでは値を変更できないため、上記の方法で変更値を呼び出そうとするとエラーが発生します.
  • 変更メソッドのself割り当ては、既存のインスタンスメソッドの役割と同じであり、構造内の関数のパラメータとインスタンスプロセスの違いを区別するために使用できます.
  • struct Point {
    	var x = 0.0, y = 0.0
        
        mutating func moveBy(x deltaX: Double, y deltaY: Double) {
        	self.Point(x : X + deltaX), y : y + deltaY)
        }
    }
    //위와 같이 인스턴스의 프로퍼티와 메서드의 파라미터를 구분지어 작성할 수 있다.
  • 列挙の変更方法は、同じ列挙から異なるインスタンスに暗黙的に設定することができる.
  • enum TriStateSwitch {
    	case off, low, high
        mutating func next() {
        	switch self {
            case .off:
            	self = .low
            case .low:
            	self = .high
            case .high:
            	self = .off
            }
    }
    
    var ovenLight = TriStateSwitch.low
    ovenLight.next()
    //다음과 같은 경우 .high로 변경된다.
    ovenLight.next()
    //다음인 .off로 변경된다.
    
    자체 인스턴스에 대한 값을 self를 통해서 반영해준다. 

    タイプメソッド

  • において上述した例示的方法は、特定のタイプのインスタンスから呼び出される方法である.タイプ自体から呼び出されるメソッドも定義できます.このタイプをタイプメソッドと呼びます.タイプメソッドを表すキーワードstaticを作成します.クラスはclassキーワードを使用できますが、サブクラスはメソッドのスーパークラス実装を再定義できます.
  • class SomeClass {
    	class func someTypeMethod() {
        	//타입메서드가 입력된다.
        }
    }
    
    SomeClass.someTypeMethod()
    //타입 메서드 바디 내 암시적 self프로퍼티는 타입 인스턴스가 아닌 타입 자체를 참조한다. 
    //인스턴스 프로퍼티와 인스턴스 메서드 파라미터에서와 같이 
    //self를 타입 프로퍼티와 타입메서드 파라미터를 명확하게 사용하도록 사용 가능하다.
  • は、通常、タイプメソッドの本体内で使用されていない非正規化メソッドおよびproperty名で、他のタイプレベルのメソッドおよびpropertyを参照する.タイプメソッドは、接頭辞としてタイプ名を必要とせず、他のタイプメソッドを呼び出すには、他のメソッド名を使用します.
  • struct LevelTracker {
    	static var highestUnlockedLevel = 1
        //타입 프로퍼티
        var currentLevel = 1
        //레벨 트렉커 구조체의 프로퍼티
        
        static func unlock(_ level : Int) {
        	if level > highestUnlockedLevel {
            	highestUnlockedLevel = level
            }
        }
        
        static func isUnlocked(_ level : Int) -> Bool {
        	return level <= highestUnlockedLevel
        }
        
        @discardableResult
        mutating func advance(to level : Int) -> Bool {
        	if LevelTracker.isUnlocked(level) {
            	currentLevel = level
                return true
            } else {
            	return false
            }
        }
    }
    //LevelTracker구조체는 모든 플레이어가 푼 가장 높은 레벨을 추적한다.
    //이 값은 highestUnlockedLevel이라는 프로퍼티에 저장된다.
    //이와 더불어 위 프로퍼티와 동작하는 2개의 타입 메서드도 정의한다.
    //이 타입 메서드는 LevelTracker.highestUnlockedLevel로 작성하지 않아도, 
    //해당 프로퍼티에 접근이 가능하다.(타입 자체의 타입 변수이므로, 호출하지 않아도..?)
    //이 외에도 각 플레이어의 진행사항을 추적한다. 
    //플레이어가 현재 플레이 중인 레벨을 추적하는 currentLevel이라는 인스턴스 프로퍼티를 사용한다.
    //이 currentLevel 프로퍼티 관리를 돕기 위해서 별도의 인스턴스 메서드를 정의한다.
    
    class Player {
    	var tracker = LevelTracker()
        let playerName : String
        
        func complete(level : Int) {
        	LevelTracker.unlock(level + 1)
            tracker.advance(to: level + 1)
        }
        
        init(name : String) {
        	playerName = name
        }
    }
    
    let player = Player(name: "경윤")
    var tracker = LevelTracker()
    tracker.currentLevel = 12
    print(tracker.currentLevel)
    //다음과 같이 인스턴스 생성 후 타입 변수와 메서드에 접근하려 하는 경우 에러가 발생한다.
    LevelTracker.highestUnlockedLevel = 3
    print(LevelTracker.highestUnlockedLevel)
    //다음과 같이 인스턴스를 생성하지 않고 바로 접근할 경우 타입 변수에 접근이 가능하다.
    //인스턴스를 생성한 후 해당 값으로 접근이 안되지만, 타입에 고유하게 할당되어 조작이 가능하다.