코코아 프레임워크, 코코아 터치, 코코아 팟이란?(설치 후 사용까지!)

|

개인공부 후 자료를 남기기 위한 목적임으로 내용 상에 오류가 있을 수 있습니다.
참고한 블로그


Framework

소프트웨어의 구체적인 부분에 해당하는 설계와 구현을 재사용이 가능하게끔 일련의 협업화된 형태로 클래스를 제공하는 것

클래스와 그에 속하는 메서드들을 미리 만들어놓고 필요할때마다 사용하는 라이브러리와 비슷하다고 생각이 들었다. 라이브러리는 필요한 사오항에서 원하는 메서드를 뽑아쓸 수 있도록 즉 완성된 메서드들이 구성되어있는 것을 의미힌다. 이에 반해 프레임워크는 개발자가 자신의 애플리케이션에서 틀이 짜여진 미완성의 메서드를 채워넣을 수 있는 형태로 정의되어있다(자바의 추상메서드 implement와 비슷) 또한 프레임워크는 개발을 하기위한 확장성을 가지는 코드를 포함하고 있다. 이것만 봐도 프레임워크의 역할은 프레임워크에서 내 어플리케이션에 메서드를 가져와 원하는 앱 개발 작업을 할 수 있도록 도와주는 것이라고 알 수 있겠다.

즉, 프레임워크는 앱개발을 편리하고 빠르게 할 수 있도록 뼈대를 미리 세워두는것, 살을 붙일 때 필요한 라이브러리 라고 생각할 수 있겠다.

스위프트에서의 약간 프로토콜과 비슷한 개념이라고도 생각했다.

Cocoa Framework

위에서 언급했듯 프레임워크는 앱의 뼈대를 만들어두는 것이고 이런 프레임워크를 여러개 모아 더욱 큰 프레임워크도 구성한 것이 애플의 코코아프레임워크 이다.

이중 터치와 관련된 디바이스의 애플리케이션을 개발할 때 사용하는 도구가 코코아터치 프레임워크인 것이다. 보통 iOS를 개발할 때 이 코코아 터치 프레임워크를 사용하게 된다. 그리고 이 프레임워크에 우리가 iOS 개발할 때 가장 많이 마주치게되는 UIKit, Foundation 프레임워크가 포함되어 있다. 이를 사용할때는 간단하게 import해주면 된다. Foundation은 말그대로 기반을 위한 도구들이 포함되어있다.(데이터타입, 콜렉션, OS 기능 등) UIKit는 iOS 를 위한 기반을 제공하며 인터페이스 그래픽을 구성하는 도구를 포함하고 있다.

CocoaPods

CocoaPods 공식사이트
CocoaPods is a dependency manager for Swift and Objective-C Cocoa projects. It has over 63 thousand libraries and is used in over 3 million apps. CocoaPods can help you scale your projects elegantly.

코코아팟은 Swift와 Objective-C 코코아 프로젝트를 위한 의존적인 매니저다. 굉장히 많은 라이브러리를 가지고 있으며 굉장히 많은 애플리케이션에 사용되고 있다. 당신의 프로젝트가 우아하게 돌아가도록 도와줄 수 있다.

만약 코코아팟 없이 프로젝트를 만들면, 오픈소스 프레임워크중에 원하는 기능이 있을 때 해당 프레임워크를 수동으로 설치해야하며, 프로젝트 안에 로드시키는 과정이 반드시 필요하다. 빌드 설정또한 우리가 직접 건들여줘야하며, 버전이 업데이트되면 위 작업들을 다시 새로해야하는 불편함또한 생긴다. 이런 불편함등을 해소하기 위해 만든것이 코코아팟이다. 코코아팟에 사용하고자 하는 라이브러리/프레임워크의 목록을 텍스트로 작성해두면 알아서 설치와 업데이트를 진행하고 Xcode 프로젝트와의 연결 및 설정도 도와준다.

Installation

코코아팟은 일단 Ruby로 제작되었다. 따라서 mac에서 설치하기 위해 아래의 명령어를 작성해줘야한다.

sudo gem install cocoapods

sudo 명령어는 일단 함부로 쓰면 안되기 떄문에 멈칫- 했지만 해야한다고 하니 일단 해보자.
함부로 쓰면 안되는 가장 기본적인 이유는 sudo를 사용하게 되면 시스템 전역에 설치가 되기 때문이다. 이렇게 함부로 모든 파일들을 sudo를 통해 설치하게 되면 기존 설치된 애들과 의존성문제로 꼬이게 되고 그러다보면 어디서부터 뭐가 잘못된지 모르게 안되는 것들이 하나, 둘 생기게 되는데 이를 해결하는 방법또한 찾을수가 없게된다.(이럴때는 결국 초기화가 답..그래서 정말 어지간한거는 무조건 brew로 설치하는게 가장가장가장!!!!!!!!!좋다!) 이렇게 설치하면 일단 코코아팟 설치가 된것이다.

쓰다보며 확인해봤는데(나는 아직 설치하기 전이었음) brew에도 cocoapods이 있더군요!

brew search cocoapods
brew cask install cocoaPods

Xcode 프로젝트에서 CocoaPods 사용해보기

설치가 끝났으니 이제 프로젝트에서 코코아팟을 사용해보도록 합시다.

터미널을 통해 해당 프로젝트가 있는 폴더로 이동한 뒤 해당 디렉토리에서 아래 명령어를 실행한다.

pod init

해당 명령어를 실행하고 나면 Podfile 파일이 생성된 것을 볼 수 있을 것이다.

이제 Podfile에 사용할 라이브러리 의존성을 추가할 것이다.

vi Podfile

설치가 완료되고나면 아래와 같은 노란글씨가 보일 수 있다.

이건, Podfile을 보면 “# platform :ios, ‘9.0’이라는 문구가 주석 처리되어있는데, Platform Version을 작성해주지 않고 주석처리를 하였기 때문에 CocoaPods에서 자동적으로 12.2 버전으로 assigning 했다는 경고로 직접 버전을 작성해 주셔야 한다면 주석을 풀어주면 된다.

이제 사용하고자 하는 Naver Map에 대한 라이브러리 설치는 완료됐다! (간-단)

자! 지금부터 주의해야하는 점은 아래와 같다.

우리는 지금까지 프로젝트를 열때 .xcodeproj 라는 확장자 파일을 실행했는데 코코아팟을 통해 라이브러리를 설치한 이후부터는 무조건! xcworkspace 라는 확장자 파일을 실행해야만 한다.

open cocoaPodsPractice.xcworkspace

이러고 열려진 xcode를 확인해보면 아래와 같이 기존과 동일한 프로젝트 파일 외에 Pods라는 것이 들어있는 것을 볼 수 있을 것이다.

이제 우리가 적용한 Naver Map을 Import하여 사용해보도록 하자!

import UIKit
import NMapsMap

class ViewController: UIViewController {

    var authState: NMFAuthState!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.

        let nmapView = NMFMapView(frame: view.frame)
        view.addSubview(nmapView)
    }
}

KVO(Key Value Observing)란 무엇인가?

|

개인공부 후 자료를 남기기 위한 목적임으로 내용 상에 오류가 있을 수 있습니다.


KVO(Key-Value Observing)

특정 키의 값의 변화를 감지하기 위한 기능

모델 객체의 어떤 값이 변경되었을 경우 이를 UI에 반영하기 위해서 컨트롤러는 모델 객체에 Observing을 도입하여 델리게이트에 특정 메시지를 보내 처리할 수 있도록 하는 것

즉, 변수에 코드를 붙여 변수가 변경될 때마다 코드가 실행되도록 하는 방법을 의미한다. property observers(willset , didSet)과 아주 유사한데 KVO는 타입 정의 밖에서 observe를 추가한다는 점이 다르다. KVO는 순수 스위프트 코드로는 그리 좋지 않은데, 그 이유는 Objective-c 런타임에 의존 하고 있기 때문이다. 그래서 NSObject를 상속받기 위해 @objc 를 반드시 붙여줘야 한다. 특히 KVO는 속성 각각에 @objc dynamic 을 붙여줘야 한다.

dynamic 은 objective-c 의 문법의 하나로, 특정 method나 function의 구현을 objective-c 런타임에서 하겠다고 결정하는 것이다.
예를들어, 하위클래스가 상위 클래스의 메서드를 override할 때 dynamic dispatch는 어떤 메서드의 구현해야 하는지 파악한다.

Example

class SomeClass: NSObject {
  @objc dynamic var value: String = ""
}

let someObject = SomeClass()

someObject.observe(\.value) { (object, change) in
  print("SomeClass object value changed to \(object.value)")
}

someObject.value = "test"  // TEST

위 코드는 NSObject를 상속받은 SomeClass클래스를 정의하고 있다. NSObject는 KVO지원을 위해서는 필수인데 KVO 기능이 NSObject에 구현되어 있기 때문이다. 그리고 유일한 프로퍼티인 value앞에는 dynamic이라는 수식어가 붙어있는데 이는 dynamic dispatch를 활성화 시키는 오퍼레이터다. 키패스(KeyPath = /.)이름을 이용해 프로퍼티의 주소를 찾게 해 주도록 하라는 정도라고 할 수 있을 것 같다.

핵심적인 부분은 옵저버를 심기 위한 observe()메소드이다. 이 observe()메소드는 기존 3.x 버전들과는 다르게 클로져를 이용할 수 있게 추가된 메소드다. 즉 해당 오브젝트에서 키패스로 지정된 프로퍼티의 값이 바뀌게 되면 클로져가 호출되게 된다. 귀찮게 오버라이드를 쓸 필요가 없어졌다. 심지어 컨텍스트 같이 몰라도 되는 값은 아예 보이지 않게 되었다. 이 부분은 정말 Swift친화적으로 바뀌었다. 예제의 observe()명령으로 someObject의 value라는 프로퍼티의 변화를 감지하기 시작한다. 결과적으로 마지막 줄에서 someObject.value 값을 바꾸자마자 “SomeClass object value changed to test” 라는 로그가 콘솔에 찍히게 된다.

좀더 이해하기 쉬운 예제로는 아래와 같다.

@objc class Person: NSObject {
    @objc dynamic var name = "Zehye"
}

let zehye = Person

그리고 이제 처음에 말했듯이 상태 변화를 감지하기 위한 코드를 붙여, 변수가 변경될 때마다 코드가 실행되도록 해보자.

zehye.observe(\Person.name, options: .new) { person, change in
    print("I'm now called \(person.name)")
}

이렇게 하면 새로운 변수가 들어오는지 보고 있다가 변수가 set되자마자 person의 이름을 프린트한다.

비록 KVO가 순수한 Swift 코드는 아니지만 Apple의 자체 API로 작업할 때는 더 좋다고한다. 이들이 모두 objective-c로 되어있기 때문에 모두 @objcdynamic 이기 때문이다.


야곰님께 질문

willset, didset과 KVO의 정의 정도는 알았지만, 두개의 쓰임에 있어서는 단순히 observe를 쓰냐 안쓰냐의 차이 정도로만 두개의 차이점을 생각했었는데, 나의 질문에 야곰님이 정말로 무릎을 탁 치게 만드는 답변을 내놓아주셨다. 내 질문은 단순히 위와 같다. willset과 didset 그리고 KVO는 서로 비슷한 역할을 하는 것인것 같은데 그 두개의 차이는 단순히 observe를 쓰냐 안쓰냐의 차이인걸까요?

답변

우리가 타입을 만드는 경우에는 자유롭게 willSet, didSet 등을 구현해줄 수 있겠지만, 다른 사람 혹은 외부 라이브러리에서 정의한 타입이라면 내부 소스를 마음대로 변경할 수 없겠죠.

그럴 때는 그 타입의 프로퍼티 등의 값이 변경되는지 KVO 방식으로 변화를 관찰할 수 있겠습니다.

즉, KVO는 상속 혹은 코드의 변경 없이 옵저빙을 할 수 있는 방법이겠다는 결론이네요 🙂

대………..박!

CollectionView에서의 DataSource와 Delegate

|

개인공부 후 자료를 남기기 위한 목적임으로 내용 상에 오류가 있을 수 있습니다.


데이터소스

컬렉션뷰 데이터소스 객체는 컬렉션뷰와 관련하여 가장 중요한 객체이며, 필수로 제공해야 한다.

컬렉션뷰의 콘텐츠(데이터)를 관리하고 해당 콘텐츠를 표현하는 데 필요한 뷰를 만든다. 데이터소스 객체를 구현하려면 UICollectionViewDataSource 프로토콜을 준수하는 객체를 만들어야 하며, 데이터소스 객체는 최소한 collectionView(_:numberOfItemsInSection:)collectionView(_:cellForItemAt:) 메서드를 구현해야 하며 나머지 메서드는 선택사항이다!

필수 메서드

// collectionView(_:numberOfItemsInSection:) : 지정된 섹션에 표시할 항목의 개수를 묻는 메서드
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int

// collectionView(_:cellForItemAt:) : 컬렉션뷰의 지정된 위치에 표시할 셀을 요청하는 메서드
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell

주요 선택 메서드

// numberOfSections(in:) : 컬렉션뷰의 섹션의 개수를 묻는 메서드 > 이 메서드를 구현하지 않으면 섹션 개수 기본 값은 1
optional func numberOfSections(in collectionView: UICollectionView) -> Int

// collectionView(_:canMoveItemAt:) : 지정된 위치의 항목을 컬렉션뷰의 다른 위치로 이동할 수 있는지를 묻는 메서드
optional func collectionView(_ collectionView: UICollectionView, canMoveItemAt indexPath: IndexPath) -> Bool

// collectionView(_:moveItemAt:to:) : 지정된 위치의 항목을 다른 위치로 이동하도록 지시하는 메서드
optional func collectionView(_ collectionView: UICollectionView, moveItemAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath)

델리게이트

컬렉션뷰 델리게이트 프로토콜은 컬렉션뷰에서 셀의 선택 및 강조표시를 관리하고 해당 셀에 대한 작업을 수행할 수 있는 메서드를 정의하며 이 프로토콜의 메서드는 모두 선택사항이다.

주요 메서드

// collectionView(_:shouldSelectItemAt:) : 지정된 셀이 사용자에 의해 선택될 수 있는지 묻는 메서드
// 선택이 가능한 경우 true로 응답하며 아닌 경우는 false로 응답
optional func collectionView(_ collectionView: UICollectionView, shouldSelectItemAt indexPath: IndexPath) -> Bool

// collectionView(_:didSelectItemAt:) : 지정된 셀이 선택되었음을 알리는 메서드
optional func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath)

// collectionView(_:shouldDeselectItemAt:) : 지정된 셀의 선택이 해제될 수 있는지 묻는 메서드 > 선택 해제가 가능한 경우 true로 응답하며, 그렇지 않다면 false
optional func collectionView(_ collectionView: UICollectionView, shouldDeselectItemAt indexPath: IndexPath) -> Bool

// collectionView(_:didDeselectItemAt:) : 지정된 셀의 선택이 해제되었음을 알리는 메서드
optional func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath)

// collectionView(_:shouldHighlightItemAt:) : 지정된 셀이 강조될 수 있는지 묻는 메서드 > 강조해야 하는 경우 true로 응답하며, 그렇지 않다면 false 
optional func collectionView(_ collectionView: UICollectionView, shouldHighlightItemAt indexPath: IndexPath) -> Bool

// collectionView(_:didHighlightItemAt:) : 지정된 셀이 강조되었을 때 알려주는 메서드
optional func collectionView(_ collectionView: UICollectionView, didHighlightItemAt indexPath: IndexPath)

// collectionView(_:didUnhighlightItemAt:) : 지정된 셀이 강조가 해제될 때 알려주는 메서드
optional func collectionView(_ collectionView: UICollectionView, didUnhighlightItemAt indexPath: IndexPath

UINavigationController와 UIViewController 차이점

|

개인공부 후 자료를 남기기 위한 목적임으로 내용 상에 오류가 있을 수 있습니다.


  • 계층구조로 구성된 content를 순차적으로 보여주는 container view controller
  • stack 구조로 구현 > navigation stack
  • 계층 구조 탐색으로 앱 content를 보여주기 적절
  • 한번에 한 child view controller의 content만 보여짐

이는 트리 구조처럼 상위 카테고리에서 점차 하위 카테고리로 넓어져 가는 구조를 표현하며 상위 카테고리로 돌아가기 위해서는 가장 최근에 보여진 뷰컨트롤부터 역순으로 거쳐 가야한다. 따라서 스택구조가 이를 구현하기에 적절하다. 이러한 네비게이션 뷰 컨트롤러는 pop/push메소드를 사용하여 보여지는 child view controller를 변경이 가능하다.

  • 화면 상단에 있는 항상 보여지는 바
  • root view 외의 모든 view 에서 back버튼이 있어 user가 계층구조에서 다시 뒤로 올라갈 수 있게끔 함
  • 현재 stack의 top level에 있는 view controller가 변하면 그에 맞게 navigation controller의 navigation bar도 변함
  • navigation bar button item: left, middle, right
  • View controller - title property 설정시 navigation bar의 가운데에 표시됨

Stack에 다음 View Controller를 쌓으며 디스플레이하는 것이 Push, 이전의 View Controller로 되돌아가는 것이 Pop 액션이다. Pop 액션에는 최초에 디스플레이됐던 View Controller로 돌아가는 Pop to Root 액션이 포함되어 있다.

Optional Tool Bar

  • Tool bar는 현재 위치한 content에서 할 수 있는 조작을 보여주는 bar
  • tab bar는 content 간 전환에 사용됨
    • tool bar 는 현재 content 내에서의 가능한 동작을 보여주는 용도
  • Tool Bar 보여주기
    • isToolBarHidden property == false 이면 tool bar displayed
    • Interface Builder 에서 ✅ Show Toolbar
  • Tool Bar item 추가하기
    • toolbar가 보여질 때, 현재 활성화된(active) view controller의 toolBarItems property를 보여줌
    • view controller 의 toolBarItems (UIBarButtonItem type) 에 객체 넣어주면 tool bar에 item이 보임

View Controller

  • 뷰를 제어하는 컨트롤러 객체
  • view 프로퍼티를 가짐으로써 프로퍼티로 가지고 있는 뷰와 서브뷰의 레이아웃이나 모양, 컨텐츠를 변경
  • 뷰 내의 컨트롤을 사용자가 조작할때 호출되는 액션을 처리
  • 뷰의 라이프 사이클을 관리
  • 모든 뷰가 뷰컨트롤러를 가질 필요는 없으며 앱의 전체화면 영역을 차지하는 뷰마다 1개씩 있으면 됨

뷰 컨트롤러는 단일 루트 뷰를 관리하며 자체에는 여러 개의 하위 뷰가 포함될 수 있다. 해당 뷰 계층과의 사용자 상호 작용은 필요에 따라 앱의 다른 객체와 조정되는 뷰 컨트롤러에서 처리한다.

  • 모든 앱에는 컨텐츠가 기본 창을 채우는 하나 이상의 뷰 컨트롤러가 있다
  • 앱에 한 번에 화면에 표시 할 수있는 것보다 더 많은 콘텐츠가있는 경우 여러 뷰 컨트롤러를 사용하여 해당 콘텐츠의 다른 부분을 관리

Two types of view Controllers

  • Content View Controllers
    • 모든 뷰를 단독으로 관리
    • UIViewController, UITableViewController, UICollectionViewController등
  • Container View Controllers
    • 자체뷰 + 하나 이상의 자식 뷰 컨트롤러가 가진 루트뷰 관리
    • 컨터에너는 컨텐츠를 관리하는 것이 아니라 루트뷰만 관리하며 컨테이너 디자인에 따라 크기 조정
    • UINavigationController, UITabbarController, UIPageViewController 등

ViewController는 Responder 객체다. 직접 이벤트를 받아 처리하는것이 가능하나 일반적으로 지양!
뷰가 그 자신의 터치 이벤트를 연관된 객체(보통 뷰컨트롤러)에 action 메서드나 delegate로 전달

The Root View Controller

  • UIWindow는 그 자체로는 유저에게 보여지는 콘텐츠를 가지지 못한다
  • Window는 정확히 하나의 RootViewController를 가지고 이를통해 컨텐츠를 표현

Container View Controller

Presented View Controller


내 생각 정리

추가해야하거나 잘못된 점은 댓글로 알려주시면 감사하겠습니다 :)

궁극적으로 네이게이션 컨트롤러는 스택같은 계층구조임을 떠올리면 된다. 예로 들어 생각해보면 아래와 같다.

설정 -> 내이름 터치 > 이름, 전화번호, 이메일 > 이름

이런식으로 하나의 갈래에서 정보를 파고파고 들어가는 형태이다. 이때 각 뷰컨트롤러의 데이터는 우리가 push해서 들어갈때마다 이전 정보를 저장해주고 있으며 그렇기 때문에 우리가 현재 화면에서 이전화면으로 돌아간다하더라도(pop) pop을 통해 타고타고 돌아가는것이 가능하다. 맨 첫화면으로 바로 돌아갈 수도 있는데 이를 잘 활용하기 위해서는 반드시 root view controller를 지정해주는 것이 필요하다!

반면 뷰 컨트롤러는 각 뷰컨트롤러마다의 데이터를 다른 뷰 컨트롤러가 저장을 해놓고 있지 않다. 우리가 만약에 첫번째 뷰 컨트롤러에서 두번째 뷰 컨트롤러, 세번째 뷰 컨트롤러로 타고타고 넘어갔다고 하자. 현재 유저의 화면이 세번째 뷰 컨트롤러에 있다면 그 뷰컨트롤러에서는 첫번째 뷰 컨트롤러의 데이터를 가지고 있지 않다. 따라서 세번째에서 첫번쨰로 넘어가려고 한다면 그 방법이 존재하지 않는다. 그 이유는 첫번째 뷰 컨트롤러에 대한 정보를 가지고 있지 않기 때문이다.

뷰 컨트롤러의 present는 단순히 덮어씌우기 기능이라고 생각하면 쉽다. 첫번째 뷰 컨트롤러의 정보를 두번째 뷰 컨트롤러에 덮어씌운다. 그렇기 때문에 바로 전 뷰 컨트롤러의 정보에 대해서만 간직하고 있다. 우리가 dismiss를 두번한다고 해서 세번째에서 첫번째 뷰 컨트롤러로 접근할수가 없다.

개발을 할때 정보의 흐름이 하나로 주욱 이어지는 화면을 구현해야한다면 네비게이션 컨트롤러를 사용하고, 각각의 독립적인 뷰를 보여줘야한다면 뷰 컨트롤러를 사용하는게 옳다고 생각한다. 그렇지만 이 둘을 또 각각 다른 단독적인 애들이라고 생각하기 보다는 기본적으로 우리는 뷰 컨트롤러를 사용하고 그 안에서 정보의 흐름이 이어지는 구성이 필요하다면 네비게이션 컨트롤러를 선택적으로 사용하며 그 흐름을 뷰 컨트롤러로 push, pop하는 것이라고 생각하는게 옳은 것 같다.

swift - 인스턴스 메서드와 클래스 메서드

|

개인공부 후 자료를 남기기 위한 목적임으로 내용 상에 오류가 있을 수 있습니다.


참고한 블로그: Swift의 static 메서드와 class 메서드

인스턴스 메서드

클래스, 구조체, 열거형의 인스턴스에 속한 메소드를 의미

인스턴스는 다른 프로그래밍 언어를 접해보신 분들께는 꽤 익숙한 개념이지만, 접해보지 못한 분들을 위해 간단히 설명하자면 클래스를 통해 호출할 수 없고, 클래스를 실체화 하여 생성된 인스턴스를 통해서 호출할 수 있는 메서드를 의미

class  Temp {
  func instanceMethod() {
	print("instanceMethod")
  }
}

let temp = Temp()
temp.instanceMethod()

인스턴스 메소드를 호출하기 위해서는 Temp를 인스턴스화 후 해당 메소드를 호출해야한다. 인스턴스 없이 독립적으로 호출할 수 없다.

참고: 타입 메소드란

타입 자체에서 호출할 수 있는 메소드를 의미

클래스를 위한 타입메소드는 func 키워드 앞에 class 키워드를 작성하는 것으로 구조체와 열거형을 위한 타입메소드는 func 키워드 앞에 static 키워드를 작성하는 것을 의미한다.

클래스 메서드

인스턴스 메서드와 다르게 굳이 인스턴스화 하지 않고 클래스로부터 직접 메서드를 호출할 수 있다.

Class 메소드의 경우 타입에 의존하므로 타입을 명시함으로써 메소드에 접근가능하다. 그러므로 해당 메소드에서 상태를 변경하게되면 해당 타입 그 자체의 상태가 변경된다. 뿐만 아니라 오버라이딩이 가능하다는 점이 큰 특징이며 상속또한 가능하다.