본문 바로가기
Back-End/Java

TIL 230525 : @오버라이드 super. this.

by 우인입니다 2023. 5. 25.

지난 시간에

안에 "Hyundai"는 중간에 "KIA"로 바뀝니다.

 

위와 같이 Car 클래스와 Tire, Handle, Door 클래스를 각 객체로 생성해서 포함하는 걸 만들었었다.

 

 

 

그리고 각 클래스에는 생성자에 sout으로 생성자가 실행됐음을 표시해두었고 결과로도 확인할 수 있었다.

Car car = new Car();

Car 객체를 생성해서 포함된 객체들도 생성되는지 확인해보자.

추가적으로, 내부 객체들이 먼저 윗줄부터 생성되고, 마지막으로 Car객체가 생성되는 걸 확인할 수 있었다.


상속.

부모로부터 모든 걸 물려받을 수 있는 금수저 클래스같달까.

이번엔 Car 클래스로부터 상속받아 SuperCar클래스를 생성해보았다.

마찬가지로 SuperCar에도 생성시 sout되게 해두었다.

실행해보자.

Car 객체까지 생성되는 걸 확인했다. 살짝 예상못한 친구였는데, 생각해보면 Car의 멤버를 다 가져다 쓸수 있는거라 하니 이게 당연하기도하다.

 

내친김에 Car와 상속관계에 있는 SuperCar클래스의 각 model 필드를 호출해봤다.

 

.....

 

'Car는 내가 따로 생성하지 않았는데? 변수명이 없는데..?'

 

그래서 각각 같은 변수명인 String model에 다른 값을 할당하고 Main 클래스에서 호출해봤다.

 

superCar.model을 출력하면 뭐가 나올까.

Car객체와 SuperCar객체까지 다 생성이 됐고, 그리고 model값은 superCar의 필드값이 나왔다.

그래도 Car객체가 생성되었는데, 우리의 티볼리를 만날 수 있을까 싶어서, Car클래스 내에 모델값을 출력하는 getModel()메소드를 실행해보았다.

 

Car클래스 내에 있는 model값을 가져오는 getModel메소드라 그런지 티볼리가 나왔다.

여기서 SuperCar클래스에도 같은 이름의 getModel 메소드가 있다면 뭐가 나올지 궁금해졌다.

 

출력값에 model변수명과 각각 클래스이름도 같이 출력하게 해줬다.

 

결과는 SuperCar가 실행됐다.

혼자서 밥도 먹을 줄 알게되면 스스로 먹게하는 부모님과 같은걸까. 같은 메소드를 할 줄 알면 상속받은 클래스 메소드를 쓴다.

 


@오버라이드

위에서 SuperCar클래스의 getModel()메소드를 따로 정의한 것이 '오버라이딩'의 개념이었다.

상속받아서 그에 맞게 재정의해서 활용할 수 있는 것.

문법상 @Override를 표기해줘야하는데, 그런것도 모르고 제멋대로 사용했는데 문제 없이 작동했다.

알아보니, @Override라는 annotation은 개발자들끼리 잘 알아보기 위해 표기하는 것이라고 한다.

 

그렇다면 이제 한 메소드안에서 매개변수를 Car에 있는 것과 SuperCar에 있는 것에 동시에 할당할 수는 없을까?

 


Super. this.

 

부모 - 자식 클래스에서 부모를 지칭하여 접근할 수 있는 것이 super.이다.

Car에는 model, company 필드를, Car를 상속받은 SuperCar에는 model 필드가 할당되어있는 상태이다.

여기서, model, company를 출력해보면,

getModel()은 오버라이드되서 SuperCar객체의 메소드를 실행. 그곳에 있는 model값을 출력했고, superCar.model 또한 마찬가지이다. Car 객체가 생성됐을 때는 model값이 "Tivoli"로 초기화 됐겠지만, 그 이후에 SuperCar객체가 생성되서 다시 초기화되어서 이렇게 된것 같다.

 

Car.model값을 출력할 수 있는 메소드를 하나 더 심어두면 뭐가나올까..? 초기화가 되려나. 아니면 Car 객체만의 model 값이 남아있으려나.

         Car.model 값도 할당은 받아있는데, 상속받으며 Supercar.model값을 그냥 따로 또 할당하는듯 하다.

 

 

다시 돌아와서, 이번에는 Super 클래스의 생성자에 Car의 변수와 SuperCar의 변수에 매개변수를 한번에 할당해보자.

이때 SuperCar클래스의 부모 클래스 내에 있는 필드에 접근하고자 할때 super. 를 본인의 필드에 접근할때 this.을 사용하게 된다. this.를 사용해야 매개변수로 받는 값과 해당 클래스 내의 변수명이 같은 경우 섞이지 않고 제대로 값을 할당해 줄 수 있다. 문법적으로는 문제없으나 제대로 동작하지 않게 됨. (매개변수 자신에게 자신을 할당해버림)

 

두 매개변수를 받는 생성자로 바꾸고, 그에 맞게 생성뒤 두 값을 출력해봤다.

 

최종결과

1. 상속해주는 Car클래스내의 객체 먼저 생성

2. Car클래스 객체 생성

3. SuperCar클래스 객체 생성.

4. 이때 받은 매개변수를 본인 클래스와 부모클래스에 할당함.

5. Car클래스 내에 있던 model변수는 그대로이다.

6. 같은 이름의 메소드는 Override 되어 실행됨.

 

 

 


꽤나 이해하기 힘들었는데, 이리저리 실험해보니 개념이 온다.
대부분의 모든 기능들은 추후 1억개의 객체를 관리할 때, 라이브러리가 업데이트 되거나 협업 등
유지 보수 및 많은 사람들과 협업을 위해 생겨난 기능들이 많다는 느낌이 강하게 들었다.
이를 염두하며 계속 생각하며 학습해야겠다.