본문 바로가기
  • 1+1=3
개발삽질/SSAFY하는 동안 기록

[SWEA]자바 초급(2) - 5차시, 6차시: 상속, 내부클래스, 객체의 형변환

by 여스 2021. 12. 29.
반응형

상속

공통된 기능이 있다고 해서 모두 상속할 순 없다. 부모클래스와 자식클래스의 관계가 일반화와 특별화의 관계('is a')관계에 있어야 함.

 

is a 관계란?

레이저프린터(자식클래스)는 프린터다(부모클래스)가 논리적으로 성립되어야 한다. 

 

 

-부모클래스 생성자 자동호출

자식클래스 생성될때 부모클래스가 먼저 생성되면서 생성자가(기본생성자) 호출됨. 부모가 먼저 호출되는거 주의!!! 

단, 명시적으로 지정한 부모생성자가 있다면 걔가 호출되고 기본생성자는 호출 안됨.

실행결과:

SuperClass 객체 생성

SubClass 생성

100

10000

 

단, 부모클래스에 기본생성자가 없다면 컴파일이 되지 않음.

아래예시에서 SuperClass라는 생성자를 하나 따로 만들었기 때문에 기본생성자가 자동으로 안생겨서 오류가 남.

 

super()

this()는 클래스 안에서 오버로딩 된 또 다른 생성자를 호출하기 위해 사용했었음.

super()는 부모클래스의 생성자를 명시적으로 호출할 때 사용됨. 부모클래스의 생성자가 오버로딩되어 여러개 존재하는 경우 특정 생성자를 호출하기 위해 사용됨.

 

 

예시) 아래예시는 super(x,y) 사용하는 경우

실행결과: 200,500 좌표에 반지름이 100인 원을 그린다.

 

 

예시) 아래예시는 super(x,y) 사용 안하는 경우. 즉, 기본생성자인 super()가 호출되는 경우

Shape클래스의 기본생성자가 호출되어 x,y좌표는 0으로 초기화됨

실행결과: 0,0 좌표에 반지름이 100인 원을 그린다.

 

 

- super()생성자 호출위치

항상 생성자의 첫번째 라인에 위치해야 함. 안그럼 컴파일오류난다. 왜냐면 부모클래스의 생성자가 자식클래스 생성자보다 먼저 수행되는게 원칙이기 때문임

 

상속과 멤버

 

- 변수의 상속

private으로 정의된 변수는 상속되지 않는다.

부모클래스가 가진 변수와 같은 이름의 변수를 선언하면, 상속되지 않고 자식클래스에서 정의한 변수가 사용됨(ex. 부모에선 String score였는데 자식클래스에선 int score면 int로만 사용된다.

 

 

- 오버라이딩

부모클래스의 메서드를 재사용하지 않고 새롭게 정의하여 사용하는 것.

자식클래스에서 재정의된 메서드는 부모클래스의 메서드와 메서드이름, 매개변수의 유형과 개수가 동일해야 함.(매개변수가 다르면 오버라이딩 되지 않음 그냥 서브클래스에는 부모클래스로부터 상속된 메서드 하나랑 지금 새로 만든 메서드 하나 이렇게 두개가 있게 되는 것임)

 

 

-메서드 오버라이딩 시 super예약어 활용

오버라이딩하면 메서드를 자식이 새롭게 재정의하는 것이기 때문에 부모가 가진 메서드가 상속되징 않음.

만약, 메서드를 오버라이딩하면서 부모클래스의 메서드를 상속도 하고 싶다면?

자식객체의 takePicture()를 실행하면 "~로 ~번 사진을 찍는다"도 함께 출력된다. super.takePicture()덕분에!

 


6차수: 추상클래스와 객체의 형변환

추상클래스는 패스~

내부클래스

내부클래스는 정의되는 위치에 따라서 멤버클래스와 지역 클래스로 나뉜다.

주의: 내부클래스가 생성되기 위해선 외부클래스의 객체가 반드시 필요함.

 

- 멤버클래스

멤버변수와 동일한 위치에 선언된 내부클래스.

동일한 클래스 뿐 아니라 다른 클래스에서도 활용될 수 있음.

클래스의 멤버변수와 성격비슷.

인스턴스 멤버 내부클래스와 스태틱 멤버 내부클래스로 나뉨.

 

- 지역 클래스

메서드 내에 크래스가 정의되어 있는 경우.

지역클래스와 무명클래스로 나뉨.

활용범위가 메서드 블록 내부로 제한되는 특징을 갖는 등 지역 변수와 성격이 비슷함.

 

-익명클래스

 

 

 

객체의 형변환

클래스의 형변환은 기본적으로 상속관계가 아닌 클래스 사이에는 발생하지 않음.

자식 클래스의 객체는 부모 타입의 참조변수에 할당될 수 있음(묵시적 형변환)

 

 

- 객체의 형변환 적용

프로그램을 좀 더 유지보수가 편한 구조로 변경할 수 있음.

아래코드는 TV객체가 변경될 때마다 객체 생성코드를 수정해야만 함.(아래 예시에서 주석처리 한것처럼..)

위의 불편함을 아래처럼 객체의 형변환 사용하여 해결가능함.

특히, 리턴타입에서 TV 가 중요함. S_TV나 L_TV 모두 TV타입으로 묵시적 형변환되어 리턴된다.

위 TVFactory를 적용해보자

명령행 매개변수가 "A사"이면 S_TV객체가 리턴되고, "B사"이면 L_TV객체가 리턴됨.

모든 TV클래스는 TV클래스의 자식클래스임. 따라서 최상위 부모인 TV타입의 변수로 받을 수 있음. 

"명령행 매개변수가 무엇이닞에 따라 다른 TV객체가 실행되고, 소스코드의 수정은 발생되지 않음"

 

 

- 묵시적 형변환의 경우 예상과 다른 출력... 이거 이상함. 틀렸음 ㅠㅠㅠ

class Parent[
	int num = 10;
    void printNum(){
    	System.out.println(num);
    }
}

class Child extends Parent[
	int num = 20;
    void printNum(){
    	System.out.println(num);
    }
}

public class Test{
	public static void main(String args[]){
    	Parent p = new Child(); //Child객체를 생성하여 부모클래스인 Parent타입의 변수에 할당함
        p.printNum();
        System.out.println(p.num);
    }
}

실행결과:

20   -> 변수에 대한 접근은 객체의 유형에 의해 결정됨(그니까 변수는 new 한 애를 따르고)

10   -> 메서드 호출은 할당되는 인스턴스에 의해 결정됨(메서드는 할당하는 타입을 따른다는 거네)

위 현상은 객체참조변수가 변수나 메서드를 참조하는 경우, 참조관계를 결정하는 시간이 다르기 때문에 나타나는 차이임.

반응형

댓글