개념 정리/Java

[JAVA] 상속, 업캐스팅, 오버라이딩, super, 추상클래스, 인터페이스

ChamOx 2023. 10. 19. 03:57

1. 상속

- 다중상속 지원 X.

[슈퍼클래스]

= 부모 클래스

class SuperClass {...}	// 슈퍼클래스

 

[서브 클래스]

= 자식 클래스. extends를 사용

class SubClass extends SuperClass {...}  // SuperClass를 상속받는 자식클래스

 

[서브 클래스 객체 생성]

- 서브클래스의 객체 생성하면 이 객체는 슈퍼 클래스의 멤버와 서브 클래스의 멤버를 모두 가지게 됨.

- 단, 자식클래스는 부모클래스의 private 속성에는 접근 불가

SubClass sub = new SubClass();	// 서브 클래스 객체 생성

 

[슈퍼클래스 접근지정]

서브클래스에서 접근 가능한 속성: public / protected / 같은 패키지 내의 디폴트 속성

 

[생성자]

- 서브클래스 객체 생성 시, 슈퍼클래스 생성자 → 서브클래스 생성자 순으로 실행됨. (두 생성자 모두 실행됨)

- 슈퍼클래스의 생성자는 기본적으로 기본생성자가 선택됨. (서브클래스의 생성자에 매개변수가 있더라도)

 

 

[super( )]

슈퍼클래스 생성자 명시적 선택.

* 반드시 생성자의 첫 라인에 사용되어야 함.

 

2. 업캐스팅, 다운캐스팅

[업캐스팅]

- 서브클래스 타입을 슈퍼클래스 타입으로 변환. (슈퍼클래스의 레퍼런스가 서브 클래스 객체를 가리키도록 치환되는 것.)

- parents은 슈퍼클래스의 멤버에만 접근 가능. child는 슈퍼클래스+서브클래스 멤버 모두 접근 가능.

- 서브클래스 관리 용이하게 하기 위해 사용. ( https://whitehairhan.tistory.com/224 참조 )

Parents parents;			// 슈퍼클래스
Child child = new Child();	// 서브클래스

parents = child;		// ex1. 업캐스팅
parents = (Parents)child;	// ex2. 업캐스팅
Parents parents = new Child();	// ex3. 업캐스팅

 

[다운캐스팅]

- 슈퍼클래스 타입을 서브클래스 타입으로 변환. 업캐스팅의 반대

- 명시적 타입변환

Child child = (Child)parents;	// 다운캐스팅

 

[instanceof 연산자]

- 레퍼런스가 가리키는 객체가 해당 클래스 타입이면 true, 아니면 false 반환.

- 레퍼런스가 가리키는 객체의 클래스 타입 구분을 위해 사용

class Parents { }
class Child extends Parents { }
class GrandChild extends Child { }

Parents parents1 = new Child();		// 업캐스팅
Parents parents2 = new GrandChild();	// 업캐스팅

if(parents1 instanceof Parents)	// true
if(parents1 instanceof Child)	// true
if(parents2 instanceof Child)	// true. GrandChild는 Child타입이기도 하므로.

3. 메소드 오버라이딩

- 슈퍼클래스의 메소드를 무시하고 서브클래스에서 오버라이딩된 메소드가 실행되도록 함
- 슈퍼클래스의 메소드와 동일형태로 작성하기.(매개변수타입, 이름 등 변경 X)
- 슈퍼클래스 메소드의 접근지정자보다 범위 좁힐 수 X
- static / private / final 메소드는 오버라이딩 X
- @override 주석문 사용해 오버라이딩이 정확한지 컴파일러에게 확인하도록 지시

 

[오버라이딩 메소드 호출]

class Parents {
	public void name() { System.out.println("parent"); }
}
class Child {
	@override	// 오버라이딩 주석문. 오버라이딩이 정확한지 컴파일러가 확인
	public void name() { System.out.println("child"); }
}

  

Child child = new Child();
child.name();	// "child" (Child클래스의 name()호출)

 

업캐스팅 시, 오버라이딩된 메소드(자식클래스의 메소드) 호출. 동적바인딩.

Parents parents = new Child();	// 업캐스팅
parents.name();	// "child" (Child클래스의 name()호출)

 

 

[동적바인딩]

- 실행할 메소드를 실행시에 결정(run-time).

- 오버라이딩된 메소드가 항상 실행되도록 보장.

class Parents {
    public void run() { name(); }
    public void name() { System.out.println("parents"); }
}
class Child {
	public void name() { System.out.println("child"); }
}

Parents parents = new Child();
parents.name();		// 동적바인딩 -> Child의 name()이 호출됨

 

[super 키워드]

슈퍼클래스의 멤버에 접근

super.name();	// Parents의 name() 호출됨

4. 추상클래스

- 선언만 되어있고 코드 구현 안된 코드. 원형만 작성. 설계와 구현 분리.
- abstract 키워드 이용
- 추상클래스는 객체 생성 X
- 구현은 서브클래스에서

 

추상 메소드를 가지고 있으면 무조건 추상 클래스로 선언해야 함. (추상메소드 없어도 추상클래스로 선언해도 됨)

abstract class Parents {		// 추상 클래스 선언
    public void run() { name(); }
    abstract public void name();	// 추상 메소드 선언
}

 

추상클래스를 상속'만' 받는 자식클래스에도 추상클래스임을 명시해야 함. (메소드 오버라이딩하지 않을경우)

abstract class Child extends Parents { }

5. 인터페이스

- 인터페이스는 객체 생성 X
- 멤버변수(필드) 생성 X
- 인터페이스끼리 상속 O
- 인터페이스 상속받아 클래스 작성 시, 인터페이스의 모든 추상 메소드 구현해야 함.
- 상수, 추상메소드(public abstract), default 메소드, private 메소드, static 메소드 로 구성

 

[인터페이스 선언]

interface Phone {		// 인터페이스 선언
    public abstract void sendCall();	// 추상메소드. public abstract 생략가능
}

 

[인터페이스 구현]

- 인터페이스의 모든 추상 메소드를 구현한 클래스 작성하는 것.

- implements 키워드 사용

class Samsung implements Phone {	// 인터페이스 구현
    @Override
    public void sendCall() {
    	System.out.println("따르릉");
    }
}

Samsung samsung = new Samsung();
samsung.sendCall();

 

[인터페이스 상속]

- 다중상속 허용

interface Mobile extends Phone, MP3interface { }

 

 

* 추상클래스 : 서브클래스에서 사용할 대부분의 기능을 구현해두고, 몇 개만 추상메소드 선언해 서브클래스에서 구현하도록 하는 목적.

* 인터페이스 : 인터페이스를 상속받는 클래스의 목적에 따라 인터페이스의 모든 추상 메소드를 만들도록 함. 인터페이스는 스펙을 주고 클래스들이 그 기능을 서로 다르게 구현할 수 있도록 함.

 

 

 

 

명품 JAVA Programming 참고