kotlin 에서 object 키워드 의 세 가지 사용 장면
object 는 Kotlin 의 중요 한 키워드 이자 자바 에 없습니다.object 는 주로 다음 과 같은 세 가지 사용 장면 이 있 습 니 다.
대상자 성명(Object Declaration)동반 대상자(Companion Object)
1. 개체 선언(Object Declaration)
문법 적 의미:클래스 의 성명 과 이 클래스 를 정의 하 는 단일 대상 을 결합 합 니 다(즉,object 를 통 해 단일 모드 를 실현 합 니 다)
기본 예시
object RepositoryManager{
fun method(){
println("I'm in object declaration")
}
}
클래스 키 워드 를 object 키워드 로 바 꾸 어 클래스 를 설명 하 는 동시에 대상 도 설명 합 니 다.이렇게 많은 코드 를 만 들 기만 하면 이 종 류 는 이미 하나의 예 이다.쓰다
a.Kotlin 에서:
fun main(args: Array<String>) {
RepositoryManager.method()
}
자바 에서 정적 방법(kotlin 에 정적 방법 이 없 음)을 호출 하 는 것 처럼 정 의 된 방법 을 호출 하지만 실제로는 Repository Manager 류 의 단일 대상 을 사용 하여 인 스 턴 스 방법 을 호출 합 니 다.이것 에 대해 아직 이해 하지 못 한다 면 자바 에서 사용 하 는 것 에 대한 설명 을 살 펴 볼 수 있다.b.자바 에서:
public class JavaTest {
public static void main(String[] args) {
RepositoryManager.INSTANCE.method();
}
}
다시 말 하면 object declaration 의 클래스 는 최종 적 으로 컴 파일 되 었 습 니 다.하나의 클래스 는 정적 구성원 을 가지 고 자신 에 대한 인용 을 가지 고 있 습 니 다.그리고 이 정적 구성원 의 이름 은 INSTANCE 입 니 다.물론 이 INSTANCE 는 하나의 예 이기 때문에 이렇게 사용 할 수 있 습 니 다.이 Repository Manager 를 자바 코드 로 설명 하면 다음 코드 가 있 습 니 다.
class RepositoryManager{
private RepositoryManager(){}
public static final RepositoryManager INSTANCE = new RepositoryManager();
}
4) 주의 점:일반 클래스 의 성명 과 마찬가지 로 속성,방법,코드 블록 초기 화 및 다른 클래스 를 계승 하거나 인 터 페 이 스 를 실현 할 수 있 지만 구조 기(메 인 구조 기 및 2 차 구조 기 포함)를 포함 할 수 없습니다.
그것 도 하나의 내부 에 정의 할 수 있다.
class ObjectOuter {
object Inner{
fun method(){
println("I'm in inner class")
}
}
}
fun main(args: Array<String>) {
ObjectOuter.Inner.method()
}
2.동반 대상(Companion object)동반 대상 을 논술 하기 전에 먼저 우 리 는 명확 하 게 해 야 한다.Kotlin 에 static 키워드 가 없다 는 것 은 정적 방법 과 정적 구성원 이 없다 는 것 을 의미한다.그러면 kotlin 에서 이러한 개념 을 나타 내 려 면 패키지 급 함수(package-level function)와 우리 가 여기 서 언급 한 동반 대상 을 대신 합 니 다.그것들 사이 의 차이 에 대해 서 는 급 하지 않 으 니,우리 나중에 다시 이야기 합 시다.
문법 형식:
class A{
companion object ( ){
//define method and field here
}
}
기본 예제:
class ObjectTest {
companion object MyObjec{
val a = 20
fun method() {
println("I'm in companion object")
}
}
}
사용:a.Kotlin 에서:
fun main(args: Array<String>) {
//
ObjectTest.MyObject.method()
println(ObjectTest.MyObject.a)
// ( )
ObjectTest.method()
println(ObjectTest.a)
}
여기 서 주의 하 십시오.정의(정의 할 때 동반 대상 이름 이 생략 되면 컴 파일 러 는 기본 이름 인 Companion 을 제공 합 니 다)와 호출 할 때 동반 대상 이름 은 생략 할 수 있 습 니 다.또한 방식 2 에서 호출 형식 에 주의 하 십시오.클래스 이름.방법 명()의 형식 을 통 해 이 루어 집 니 다.우 리 는 Object Test 류 를 생 성 하 는 대상 이 없 을 때 내부 동반 대상 에서 정의 하 는 속성 과 방법 을 호출 했 습 니 다.자바 의 정적 방법 과 유사 한 개념 입 니까?현상 을 통 해 본질 을 보다
javap 명령 을 통 해 생 성 된 바이트 코드 를 보 여 줍 니 다:
빨간색 상자 에서 이 MyObject 구성원 변수의 종 류 는 사용
MyObject 라 는 내부 클래스.이것 은 외부 클래스 의 인용 이 없 으 며 정적 내부 클래스 의 형식 으로 존재 한 다 는 것 을 주의 하 십시오.
우리 가 앞에서 남 긴 문 제 를 기억 합 니 다.자바 의 static 개념 을 대체 할 수 있 습 니 다.그러면 동반 대상 에서 정의 하 는 방법 과 가방 등급 함 수 는 어떤 차이 가 있 습 니까?
먼저 패키지 등급 함 수 를 포함 하 는 kt 파일 을 역 컴 파일 합 니 다(또는 클래스 라 고 합 니 다).
이 를 통 해 알 수 있 듯 이 ObjectTest 2.kt 파일 은 실제 적 으로 ObjectTest2Kt 라 는 클래스 를 만 들 고 이 kt 파일 에서 정의 하 는 최상 위 함수(패키지 급 함수)는 이러한 정적 방법의 형태 로 존재 합 니 다.
그러면 이 제 는 남 겨 진 질문 에 대답 할 수 있 습 니 다.사실은 평 급 류(우선)중의 정적 방법 과 정적 내부 류 중의 방법의 차이 입 니 다.정적 내부 류 중의 방법 은 외부 류 에서 정 의 된 static 방법 과 구성원 을 방문 할 수 있 기 때 문 입 니 다.private(개인 구조 기 포함)라 도.우리 가 자주 사용 하 는 정적 내부 클래스 를 바탕 으로 하 는 단일 사례 모델 은 바로 이 점 을 바탕 으로 하 는 것 이다).평 급 클래스 의 방법 은 현재 클래스 의 정적 인 private 구성원 에 접근 할 수 없다.만약 에 문자 가 이렇게 묘사 하 는 것 이 직관 적 이지 않다 고 생각한다 면 다음 그림 을 보 겠 습 니 다(Kotlin in action 에서 훔 친 것).
@JvmStatic 주해:우 리 는 앞에서 정 의 된 method 방법 에 이 주 해 를 추가 하고 다시 build 프로젝트 를 한 다음 에 ObjectTest 와 ObjectTest$MyObject 라 는 두 가지 종 류 를 역 컴 파일 하여 어떤 변화 가 있 는 지 봅 니 다.
이 정적 내부 클래스 의 경우@JvmStatic 주 해 를 추가 하거나 추가 하지 않 는 구 조 는 변화 가 없습니다.그러나 목표 클래스 에 있어 정적 인 방법 이 현저히 많아 졌 습 니 다.그러면 우 리 는@JvmStatic 주해 의 역할 을 이해 하기 어렵 지 않 습 니 다.동반 대상 클래스 에서 정의 하 는 인 스 턴 스 방법 과 속성 을 목표 클래스 에 추가 하고 정적 인 형식 으로 존재 합 니 다.
반생 대상 에 대해 마지막 으로 한 가지 보충 을 한다.한 가지 유형의 반생 대상 은 한 가지 만 있 을 수 있다.곰 곰 이 생각해 봐 도 이해 하기 쉬 워 요.동반 대상 의 이름 은 생략 할 수 있어 요.만약 에 여러 짝 꿍 대상 에 대응 할 수 있다 면 우 리 는 여러 짝 꿍 대상 에서 똑 같은 함 수 를 정 의 했 습 니 다.호출 할 때 도대체 어떤 짝 꿍 대상 을 사용 하 는 방법 입 니까?이 문법 규정 을 이해 하기 어렵 지 않다.
3.대상 표현 식(Object Expression)
자바 의 익명 내부 클래스 회고:
대상 표현 식 을 배우 기 전에 자바 의 익명 내부 클래스 를 살 펴 보 자.
interface Contents {
void absMethod();
}
public class Hello {
public Contents contents() {
return new Contents() {
@Override
public void absMethod() {
System.out.println("method invoked...");
}
};
}
public static void main(String[] args) {
Hello hello = new Hello();
hello.contents().absMethod(); // method invoked...
}
}
``` new Contents()
이 contents()방법 은 익명 내부 클래스 의 대상 을 되 돌려 줍 니 다.이 익명 내부 클래스 는 Contents 인 터 페 이 스 를 실현 합 니 다.이 코드 들 은 매우 익숙 해서 더 이상 말 하지 않 겠 다.지금 두 가지 제한 적 인 문 제 를 제기 합 니 다.a.익명 내부 클래스 에 속성 과 방법 을 새로 추가 하면 외부 에서 호출 할 수 없습니다.
return new Contents() {
private int i = 1;
public int value() {
return i;
}
@Override
public void absMethod() {
System.out.println("method invoked...");
}
};
public static void main(String[] args) {
Hello hello = new Hello();
hello.contents().absMethod();
hello.contents().value(); //Cannot resolve method 'value()'
}
이 value 방법 을 사용 하고 싶 을 때 컴 파일 러 가 잘못 보고 할 수 있 습 니 다.이해 하기 쉽다.다 태 적 인 지식 이다.부모 유형의 인용 은 하위 클래스 추가 방법의 존 재 를 알 수 없다.b.익명 의 내부 클래스 는 하나의 인 터 페 이 스 를 실현 하거나 하나의 클래스 를 계승 하 는 것 이 고 하나 일 수 밖 에 없다.수학 용어 로'있 고 하나 밖 에 없다'고 말한다.
2)문법 형식:
object[:인터페이스 1,인터페이스 2,유형 1,유형 2]{} //중 괄호 중 생략 가능
3)사용 예시:
a.인터페이스 또는 클래스 구현
interface AA {
fun a()
}
fun main(args: Array) {
val aa = object : AA {
override fun a() {
println("a invoked")
}
}
aa.a()
}
b.어떠한 인터페이스 와 클래스 도 실현 하지 않 고 익명 내부 클래스 에 방법 을 추가 합 니 다.
fun main(args: Array) {
val obj = object {
fun a() {
println("a invoked")
}
}
obj.a() // :a invoked
}
이 예 를 통 해 알 수 있 듯 이 앞에서 언급 한 자바 익명 내부 류 의 첫 번 째 한 계 는 Kotlin 에 존재 하지 않 고 새로 추가 하 는 방법 도 호출 할 수 있 습 니 다.c.여러 인터페이스 와 클래스 구현
fun main(args: Array) {
val cc = object : AA, BB() {
override fun a() {
}
override fun b() {
}
}
cc.a()
cc.b()
}
이 예 를 통 해 알 수 있 듯 이 앞에서 언급 한 자바 익명 내부 류 의 두 번 째 한계점 은 kotlin 에 도 존재 하지 않 는 다.4)사용 주의 점:
이것 은 Kotlin 공식 문서 의 한 단락 입 니 다.익명 의 대상 은 국부 변수 와 private 구성원 변수 로 정 의 될 때 만 실제 유형 을 나 타 낼 수 있 습 니 다.익명 의 대상 을 Public 함수 의 반환 값 이나 Public 속성 으로 볼 때 부모 클래스 로 만 볼 수 있 습 니 다.물론 어떤 유형 도 지정 하지 않 았 을 때 Any 로 생각 합 니 다.이 때 익명 의 대상 에 추 가 된 속성 과 방법 은 접근 할 수 없습니다.
다시 예 를 들 어 여러분 의 이 해 를 돕 겠 습 니 다.
class MyTest {
private val foo = object {
fun method() {
println("private")
}
}
val foo2 = object {
fun method() {
println("public")
}
}
fun m() = object {
fun method(){
println("method")
}
}
fun invoke(){
val local = object {
fun method(){
println("local")
}
}
local.method() //
foo.method() //
foo2.method() //
m().method() //
}
}
5)익명 의 대상 에서 같은 역할 로 정 의 된 부분 변 수 를 방문 하 는 문제:자바 에서 익명 내부 클래스 에서 외부 에서 정 의 된 부분 변 수 를 방문 하면 이 부분 변 수 는 final 키 워드 를 사용 하여 수식 해 야 합 니 다.왜 여러분 이 제 이전의 박문 을 볼 수 있 는 지 에 대해 서 는.Kotlin 에서 이 제한 이 없습니다.다음 의 예 를 보십시오.
var a = 1
val obj = object {
fun method() {
a++
}
}
obj.method()
println(a) // 2
다시 한 번 설명 하 겠 습 니 다.자바 에서 실제 method 방법 에서 사용 하 는 a 는 실제 적 으로 부분 변수 a 의 복사 입 니 다.그 자체 가 아 닙 니 다.Kotlin 에 서 는 결국 JVM 이 실행 할 수 있 도록 바이트 코드 로 컴 파일 해 야 하기 때문에 본질 적 으로 이 점 에 어 긋 나 지 않 습 니 다.그럼 얘 는 어떻게 처리 하 는 거 예요?방문 한 부분 변수 가 val 일 때 자바 와 마찬가지 로 복사 본 을 가지 고 있 습 니 다.그리고 가 변 변수(var)일 때 그 값 은 Ref 와 같은 인 스 턴 스 구성원 에 저 장 됩 니 다.Ref 변 수 는 final 이 고 그 중의 구성원 변 수 는 바 꿀 수 있 습 니 다.역 컴 파일 후 Ref 의 모습 을 볼 수 있 습 니 다.
여기에 재 미 있 는 코드 도 있어 서 여러분 께 붙 여 드 리 겠 습 니 다.
fun tryToCountButtonClicks(button: Button): Int{
var clicks = 0
button.setOnClickListener{
clicks++
}
return clicks
}
button 은 단추 입 니 다.이 코드 는 원래 Button 이 클릭 한 횟수 를 통계 하려 는 것 입 니 다.그러나 이 함수 의 반환 값 은 항상 0 입 니 다.아무리 여러 번 클릭 하 더 라 도.부분 변수 clicks 를 수정 할 가치 가 있 기 때문에 이 함수 의 반환 값 은 실행 할 때 확 정 된 것 입 니 다.바로 당신 의 값 이 아직 수정 되 지 않 았 고 함수 가 되 돌 아 왔 습 니 다.클릭 횟수 를 집계 하려 면 클릭 스 를 클래스 의 구성원 변수 로 정의 할 수 있 습 니 다.4.object declaration,Companion object 및 object expression 의 초기 화 시 기 를 비교 합 니 다.
a.object declaration:처음 방문 할 때 초기 화 되 며 게 으 름 초기 화 입 니 다.
b.Companion object:대응 하 는 클래스 가 불 러 온 후에 야 자바 의 정적 코드 블록 과 같이 초기 화 됩 니 다.
c.object expression:실행 되면 바로 초기 화 합 니 다.
이로써 Kotlin 의 object 키워드 사용 에 대해 소 개 를 마 쳤 습 니 다.많은 성 과 를 거두 시기 바 랍 니 다~
총결산
kotlin 에서 object 키 워드 를 사용 하 는 세 가지 장면 에 관 한 글 을 소개 합 니 다.더 많은 kotlin object 키 워드 는 장면 내용 을 사용 합 니 다.예전 의 글 을 검색 하거나 아래 의 관련 글 을 계속 찾 아 보 세 요.앞으로 많은 응원 부 탁 드 리 겠 습 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Kotlin의 실험, 에피소드 1a String 의 중심에 있는 문자를 반환하는 메서드를 작성하려는 경우 Java에서 가장 좋은 옵션은 유틸리티 클래스를 정의하는 것입니다. Kotlin을 사용하면 을 통해 기존 클래스에 새 메서드를 추가할 수 있습...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.