여니의 성장 diary
article thumbnail
728x90
반응형

휴일이 3일이나 되는데 이번 휴일동안은 나태해져서 공부 하나도 안한 나 자신 반성중...

덕분에 바이오리듬 깨져서 늦게 잠들고 아침에 늦잠자고 난맄ㅋㅋㅋㅋㅋ

이번주부터는 다시 마음 다잡고 틈틈히 복습하고 열심히 공부하는걸로 :)

 

이번주부터는 내용이 조금씩 더 어려워질 예정,,, 먼저 상속에 대해 배워보았다!

 

07
상속
상속(Inheirtance)

상속이란 하위 클래스가 상위클래스의 특성을 그대로 가진 상태에서 그 기능을 확장하는 것인데,

상위 클래스를 슈퍼 클래스, 부모 클래스라 하고, 하위 클래스를 서브 클래스, 자식 클래스라고 한다.

 

상위 클래스로 먼저 생성하고, 이에 상속되는 하위 클래스를 생성할 때에는

"extends"를 사용하여 상위 클래스에 상속되는 클래스임을 표시해준다.

 

상속의 대상이 되는 멤버는 필드, 메소드이고, 비정적 멤버에만 해당된다.

또한 생성자는 상속의 대상이 되지 않는다. 이를 확인하기 위한 코드를 작성해보았다!

 

 

먼저 상위 클래스 Cellphone 을 생성하여 필드와 메소드를 선언해준다.

그리고 Cellphone에 상속되는 DmbCellphone 클래스를 만들어 생성자를 정의해주고(Line 8 -),

추가적으로 필드와 메소드를 선언해주었다. (Line 6-, 14-, 18-, 23-)

 

DmbCellphone 클래스는 Cellphone 클래스를 상속(확장, extends)하였기 때문에

Cellphone 클래스 내의 필드 model, color, 메소드 powerOn, powerOff, bell, sendVoice, receiveVoice, hang Up등

Cellphone 클래스의 기능을 모두 그대로 사용할 수 있고 이 기능들을 확장하여

필드 channel, 메소드 turnOnDmb, changeChannelDmb, turnOffDmb 기능을 갖는것이다.

 

 

다음으로 메인메소드를 실행시킬 DmbPhoneExample 클래스를 생성해준다.

메인메소드 내에 DmbCellPhone(하위클래스) 객체를 새로 생성해주고, 동시에 초기화(값 할당)를 해준다.

 

그리고 상위 클래스의 메소드(Line 11-16) 와 하위 클래스의 메소드(Line 20-22)를

각각 모두 호출해보면 오류없이 정상적으로 모든 값이 출력되는 것을 확인할 수 있다.

 

이처럼 하위 클래스의 객체를 새로 생성한 경우, 하위 클래스는 상위 클래스를 상속하고 있으므로

하위 클래스의 객체는 상위 클래스의 모든 기능을 수행할 수 있다.

 

 

다음으로 패키지를 새로 생성해 Cellphone 클래스를 상속하는 SmartPhone 클래스를 생성하여

메인메소드에서 상위 클래스의 메소드 기능을 사용할 수 있는지 확인해보았다.

 

SmartPhoneExample 클래스의 메인메소드에서 Smartphone 객체를 생성한 다음

appExecute() 메소드를 호출하면 정상적으로 수행되어지는 것을 확인할 수 있다.

그러나 가장 상위 클래스에 있는 powerOn() 메소드 기능은 컴파일 오류가 발생하는데,

이것은 메소드에 부여된 접근 제한자에 따라 상속의 범위가 제한되기 때문이다.

 

Cellphone의 powerOn() 메소드는 접근제한자 protected를 가지고 있기 때문에

직접 상속되는 클래스에서 수행하거나 동일 패키지 내에 있는 클래스에서만 기능을 활용할 수 있다.

그렇기 때문에 상속하고있는 Smartphone 클래스에서는 기능을 사용할 수 있지만

외부 클래스에 있고, Cellphone 클래스를 직접 상속하지 않는 SmartPhoneExample 클래스에서는 수행이 불가한 것이다.

 

[접근제한자에 따른 상속의 범위]
public : 동일 패키지, 외부 패키지의 모든 클래스에서 모두 접근 가능
protected : 동일 패키지에 있는 클래스이거나 외부 패키지의 클래스는 상속클래스만 접근 가능
default : 동일 패키지에 있는 클래스에서만 접근 가능
private :  모든 클래스에서 접근 불가능 (상속 불가)

boolean 타입의 Getter 메소드

 

지난 수업시간에 getter 메소드를 생성할 때에는 접두사 get + 필드명으로 사용한다고 했었는데,

필드의 타입이 boolean일 경우에는 접두사 get 대신에 접두사 is를 사용한다는 것을 알아두어야한다 :)


클래스 상속

 

클래스 상속을 좀 더 구체적으로 보완해서 확인해보았다!

 

상위 객체를 상속하는 하위 객체를 생성하였을 때, 하위 객체에 생성자를 정의하지 않는 경우

컴파일러가 자동으로 상위 객체의 기본생성자를 호출하는 기본 생성자를 정의하기 때문에

상위 객체에 기본 생성자가 없는 경우에는 컴파일 오류가 발생하게 된다.

 

또한 기본 생성자를 사용하지 않고, 매개변수가 있는 생성자를 사용할 경우

상위 객체의 생성자 중 매개변수의 타입과 갯수가 같은 생성자를 찾아 호출하기 때문에

매개변수의 타입과 갯수에 맞춰 파라미터를 입력해주면 컴파일 오류가 발생하지 않는다.

 

참고로 array[] 배열을 대신하여 List<>를 활용하였는데,  배열을 사용하여 정의할 때보다

이를 활용한 메소드와 조건식을 훨씬 더 수월하게 작성할 수 있었다 :)

List<>에 대한 자세한 내용과 활용 방법은 진도를 더 나가면 배우게 되니 skip 춍춍 ~

 


super() 메소드

 

다음으로 상속에서 빼놓을 수 없는 super() 메소드에 대해 알아보았다.

super() 메소드는 부모 생성자를 호출하는 기능인데, 명시하지 않는 경우 컴파일러가 자동으로 추가하기 때문에

생략해도 무방하지만 명시할 경우에는 반드시 생성자의 가장 첫 줄에 위치해야한다.

 


printf()

 

교재에서 다루지 않았던 printf()에 대한 내용도 살짝 참고용으로 학습해보았다!

printf()는 변수의 값을 여러가지 형식으로 변환해서 출력할 수 있는 메소드인데,

System.out.printf("출력 서식", 출력할 내용);

위와 같은 형태로 출력되고, 출력 서식은 아래와 같이 표현된다.

 

%s : 문자형 출력 / %d : 정수형 출력 / %f : 실수형 출력

%b : boolean 출력 / %o : 8진수 출력 / %x : 16진수 출력

%t : 날짜, 시간형 출력 / %e : 지수형 출력 / %n : 줄바꿈

 

그리고 print() 에서 \n은 줄바꿈이 가능한데, println()과 같은 기능을 한다.


메소드 Override

 

메소드를 오버라이딩 할 때 컴파일러에게 오버라이딩 의도를 전달하기 위해 "@Override 어노테이션"을 사용한다.

 

@Override 어노테이션을 이용한 메소드는 상위클래스에 정의된 메소드와 시그니처가 일치하지 않으면

상위 클래스에 존재하는 메소드인지 검사하고, 오타가 있을 경우 컴파일 오류가 발생하여 

메소드 선언 시 상위클래스의 메소드명과 일치하는지 확인하고 수정할 수 있도록 알려준다.

 

상위 객체의 메소드를 하위 객체에서 오버라이딩하여 사용할 때 주의해야할 점은

상위 객체의 접근제한자보다 제한이 더 강한 접근제한자를 하위 객체에서 사용할 수 없다는 것이다.

접근제한자를 제한 강도 순으로 나열하면 " public < protected < default < private " 순이다.

 


부모 메소드 사용(super)

 

상위 객체인 super를 활용해 "super.메소드명()" 으로 호출하게 되면

하위 클래스 내부에서 오버라이딩 된 상위클래스의 메소드를 호출해서 사용할 수 있다.

 

위의 코드에서는 Airplane이 상위 객체, SupersonicAirplane이 하위 객체인데,

상위 객체의 fly() 메소드를 하위 객체에서 오버라이딩하여 메소드를 호출할 수 있도록 해준다.

 

이때 하위 객체에서 상수와 flyMode를 정의해주고, 메인메소드에서 하위 객체를 새롭게 생성해주면

위의 코드에서처럼 상위 클래스의 fly()를 호출하여 활용할 수 있고, 그 외 public 메소드도 활용 가능하다.

 


toString() 메소드 오버라이딩

 

마지막으로 메소드 오버라이딩에서 자주 사용되는 toString() 메소드 오버라이딩을 활용해보았다.

참고로 toString() 메소드는 객체의 필드 정보를 출력하는데 사용되는 메소드이다

 

먼저 상위 객체에 private 접근자를 가진 필드를 선언해주고, getter와 setter를 생성해준다.

그리고  메인메소드에서 새로운 객체를 생성한 후 setter를 활용해 정보를 입력하여 값을 할당해주고,

객체의 정보를 출력해보면 "패키지명.클래스명@참조값"을 출력해준다.

 

그리고 toString() 메소드를 오버라이딩하여 return 값을 정의해주면 메인메소드에서 원하는 내용을 출력할 수 있다.

toString() 메소드는 Object 클래스에 정의되어있고, 모든 클래스는 암묵적으로 Object 클래스를 상속하고 있어

모든 객체는 Object에 정의된 메소드를 사용할 수 있는 것이다.

 

728x90
반응형
profile

여니의 성장 diary

@pponyo

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!