Media Log

this 와 this() 는 다르구요, super와 super() 역시 다릅니다.


this 는 현재 클래스의 인스턴스, 그러니까 지금 실행상태에 있는 인스턴스의 특정 필드를 지정할때 사용합니다.



 class Test {


 int age;

 public void setAge(int age){

 this.age = age;

       }
 }



머 이렇다구 치구... 다른 객체에서 

Test test = new Test();

test.setAge(20);

이라고 하면 위에있는 setAge(int); 메소드가 작동을 하겠죠...

setAge(int age); 메소드를 보면 파라미터로 전달된 int 의 이름인 age와 Test 클래스의 필드값이 age가 같은 이름이거든요...

이럴때 this. 를 붙여주면 

this.age

는 "이 age는 지금 메소드(setAge)의 파라미터인 age 값이 아니라 클래스의 필드인 age다" 라는걸 나타냅니다. (헷갈리지 않게..)

그리고 두번째로는 뭐랄까... 강조하는 의미에서 사용하는 경우도 있습니다.

this.name = "용가리";

라고 하면 여기서 name 은 클래스의 필드라는것을 명확하게 나타냅니다. 위 문장이 메소드안에 존재하더라도 name 은 클래스의 필드임을 확실히 해두기 위해서 사용됩니다.


this(); 는 생성자를 부르기 위해서 사용되거든요..


 class Person{


 int age;
 String name;
 String address;

 public Person(){
 this(0, null, null);
 }

 public Person(int age){
 this(age, null, null);
 }

 public Person(int age, String name){
 this(age, name, null);
 }

 public Person(int age, String name, String address){
 this.age age;
 this.name name;
 this.addressaddress;
     }
 }


한사람에 대한 나이, 이름, 주소를 저장하는 클래스인데 생성자를 함 잘 살펴보세요.

점차 파라미터(넘겨받는 값)가 늘어나고 있죠...

다른 클래스에서

Person jane = new Person(23, "jane", "America");
Person jane = new Person(23, "jane");
Person jane = new Person(23);
Person jane = new Person();

위와같이 다양한 방법으로 인스턴스를 생성할 수 있도록 여러종류의 생성자를 마련했을때 this(); 가 유용하게 쓰일 수 있습니다.

생성자끼리도 서로가 서로를 호출할 수 있는(객체지향 프로그래밍에서는 메시지를 전달한다고 하는데 그냥 편하게 호출한다고 할께요..) 방법이 바로 this() 를 활용하는 겁니다. 

위에서 두번째, 세번째, 네번째 모두 결국은 첫번째 생성자

Person jane = new Person(23, "jane", "America");

를 호출해서 인스턴스를 만들거든요.... 뭐 이런식으로 쓰인다고만 아시면 되겠습니다.

같은 방식으로 super(); 는 현재 자식클래스가 자신을 생성할때 부모 클래스의 생성자를 불러서 함 초기화 해주고나서 자신을 초기화하는 것입니당.

class A extends B

라고 하면 클래스 B는 A의 부모 클래스죠.

A 를 생성한다고 하면 우선 B를 생성해야 합니다. 왜냐하면 A는 B를 상속하므로 A를 완전하게 만들려면 B부터 만들어야 하거든요. ^^;;(부모없이 자식이 존재할 수 없는것과 같습니다.)

class B{

public void setAge(int age)
{
...
}

}

class A extends B {

public void setAge(int age)
{
...
}

}

이렇다고 하면 

A a = new A();

로 인스턴스를 만들면 그냥 A 가 만들어지는게 아니라 

1. A 를 만들기 위해서 A의 생성자를 찾아간다.
2. 가서 보니까 A가 B를 확장하고 있네...
3. 그럼 B부터 만들어야겠군...
4. 그럼 B의 생성자를 찾아가야지..
5. B를 만들었으니..
6. 이제 A를 만들자.
7. 다 만들었다!!!

이렇게 됩니다. ^^;;

위에서 클래스 B를 

class B{

public B (int a){
;
}
}

로 하믄 어떤일이 벌어질까요..

에러가 발생합니다. 왜냐하면 3번에서부터 문제가 발생합니다.

3. 그럼 B부터 만들어야겠군...
4. 그럼 B의 생성자를 찾아가야지..
5. 헉! 알맞는 B의 생성자가 없다
6. 에러다!

왜 없다고 하나면 A 클래스에 대한 생성자가 없으니까 디폴트로

public A() { ; }

와같이 생성자를 만듭니다.

그런데 B에서는 int 값을 전달받는 생성자를 명시적으로 적어줬으니 

public B() { ; }

이런 생성자가 없게 됩니다.(필요하다면 적어줘야함)

A 가 B 를 상속하니까 B를 만들어야 되는데 A의 생성자에서 명시적으로 B의 생성자를 적어주지 않았으므로 역시 디폴트로 

super();

를 부릅니다. super(); 를 부른다는 것은 부모 클래스의 

public B(){;}

를 실행하라는 말입니다. 그런데 저런 생성자가 없으니 에러가 납니다.

이럴때는 A에서 

class A extends B {

public A(){
super(20);
}

}

요렇게 부모 클래스의 생성자를 불러주면 잘 작동합니당. ^^;;;

이게 바로 super(); 의 쓰임새입니당..^^;;


super는 뻔하겠죠. 부모클래스의 필드값이나 메소드를 직접 부를 때 붙여넣는 겁니다.

위에서 A나 B나 둘다 모두 setAge(int); 메소드가 있습니다. 자식 클래스인 B에서 부모클래스 A의 setAge(int); 메소드를 부를 일이 생겼다고 치죠. B에서 그냥

setAge(20);

을 부르면 B 클래스에 있는 메소드를 부르게 됩니다. B 클래스에 setAge(int) 메소드가 없었다면 부모 클래스에 있는지 자동으로 찾아보게 됩니다.

하지만 B에는 setAge(int) 가 있으므로 부모 클래스의 setAge(int) 를 찾지 않고 B의 메소드를 사용하게 됩니다.

우리가 원하는 것은 부모클래스의 setAge(20) 을 부르고 싶기 때문에

super.setAge(20);

을 해야 합니다. super 는 "나에게 있는 메소드나 필드를 찾지 말고 내 부모 클래스에 있는 필드나 메소드를 사용해라" 라는 의미로 붙여주는 예약어입니다.




 
수타~면~
신고
  1. 남준호 at 2015.03.04 02:04 신고 [edit/del]

    와 쉬운 설명 감사합니다.
    super에 대해 잘 숙지하고 갑니다!!

    Reply
  2. 김서연 at 2015.05.24 15:09 신고 [edit/del]

    설명 정말 잘하시네요.. this의 쓰임새가 몰라서 들어왔는데, super까지 알고 가네요. 좋은 글 감사합니다!

    Reply
  3. 강건마 at 2016.10.06 19:21 신고 [edit/del]

    잘 보고 갑니다.

    Reply
  4. 이신기 at 2016.12.26 04:37 신고 [edit/del]

    설명좋아요~!

    Reply
  5. gentacle at 2016.12.28 22:02 신고 [edit/del]

    쉬운설명 감사합니다.

    Reply

submit

티스토리 툴바