클래스의 override를 제한하거나 서브클래스가 더 이상 존재하지 않을 때 final 키워드를 사용한다.
final을 통해 상속이 더 이상 필요없음을 명시할 수 있을 뿐더러, 런타임 성능이 향상된다.
swift에는 어떤 메소드를 호출할 것인지를 결정하여 실행하는 메커니즘인 Dispatch라는 개념이 존재한다
이 Dispatch는 다시 Static Dispatch와 Dynamic Dispatch로 구분된다.
컴파일 시점에 호출될 함수를 결정하여, 런타임 시 그대로 실행시킨다.
이는 컴파일 시점에 이미 결정이 되기 때문에 성능 상 이점이 있다.
런타임 시점에 호출될 함수를 결정하여, 실행시킨다.
함수 호출 과정에서 vtable을 통해 간접호출되기 때문에 Static Dispatch보다 느리다. (문서)

가상 메소드 테이블(virtual method table)로,
메소드 오버라이딩에 따라 실행 시점에 상위 클래스의 메소드, 하위 클래스 메소드 중 어떤 메소드를 실행할지 결정한다.
Static Dispatch - 컴파일 시점에 호출될 함수를 결정, 빠름
Dynamic Dispatch - 런타임 시점에 호출될 함수 vtable을 통해 결정, 느림
기본적으로 클래스는 final을 붙이지 않으면 오버라이딩의 가능성이 있기 때문에 무조건 Dynamic Dispatch로 실행된다.
그렇지만 final을 붙이게되면 오버라이딩을 제한하기 때문에 Static Dispatch로 실행되며 컴파일 시점에 호출될 함수가 결정되면서 자연스럽게 성능 향상이 이루어 진다.
성능 향상의 관점에서 final이 아니더라도 클래스와 구조체 중 어느 것이 더 나을지를 고민해보는것도 좋을 것 같다.