상속이란? 현실 세계에서 쓰이는 상속이란 말에 대해 생각해 보자 부모의 자산등을 자식에게 물려주는 의미로 많이 쓰는 단어 이다. 그렇다면 이 상속이 자바에서는 어떤 식으로 쓰이는지 한번 알아보도록 하자.
자바에서의 상속
객체 지향 프로그램에서 상속은 비슷한 의미로 작용한다. 현실 세계 처럼 부모가 자식에게 물려주는 의미로 부모 클래스의 멤버나 메소드를 자식의 클래스에게 물려줄수있다.
상속을 사용함으로 공통된 특징을 가지는 클래스에서 코드 중복을 줄여주고 부모 클래스의 멤버를 재사용 하면서 자식클래스의 간결함을 유지 시켜준다.
클래스간의 계층적 분리를 도와줘 분류, 관리의 이점이 있다.
상속의 특징
부모 클래스 → Super class
자식 클래스 → Sub class
자바는 다중 상속을 지원 하지 X → extends 뒤에는 하나의 부모 클래스만 올수 있다.
상속 횟수에 제한 X
자바의 최상위 클래스는 Object 이다. 즉 자바의 모든 클래스는 Object 의 자손
상속 방법
class 자식클래스 extends 부모클래스{
}
public class Tv {
String
public class Samsung extends Tv {
String tvType;
}
super 키워드란?
→ 이는 개발자가 따로 부모 객체의 생성자를 자식 클래스에 지정해 놓지 않았다면 컴파일러가
super()
를 통해 부모의 기본 생성자를 호출한다.
오버라이딩
public class Tv {
public void getInfo() {
System.out.print("티비 입니다.");
}
}
public class Samsung extends Tv {
@Override
public void getInfo() {
System.out.print(" 삼성 티비 ");
}
}
규칙
Dynamic Dispatch
런타임 시점에서는 어떤 메소드를 호출해야할지 모르고 추상 타입의 메소드를 호출하는 것만 알고 있는데 할당된 객체의 타입을 보고 메소드를 결정하는 것을 의미한다.
예를 보고 이해를 해보자
public class Tv {
public void view() {
System.out.println("티비를 보여줌");
}
}
public class Samsung extends Tv {
@Override
public void view() {
System.out.println("OLED 티비를 보여줌");
}
}
public class Main {
public static void main(String[] args) {
Tv tv = new Tv(); // Tv 참조 Tv 객체
Tv samsungTv = new Samsung(); // Tv 참조, 삼성 객체
tv.view(); //참조와 객체가 동일
samsungTv.view();// 참조와 객체가 다름 (상속) => 다이나믹 메소드 디스패치
}
}
Double Dispatch
Dispatch 가 연속적으로 이뤄지는것을 의미한다.
바로 예를 보도록 하자
public class Test {
public static void main (String [] args) {
Lists<SmartPhone> phoneList = Arrays.asList(new Iphone(), new Gallaxy());
Game game = new Game();
phoneList.forEach(game::play);
}
}
interface SmartPhone {
}
class Iphone implements SmartPhone {
}
class Gallaxy implements SmartPhone {
}
class Game {
public void play(SmartPhone phone) {
System.out.println(phone.getClass().getSimpleName());
}
}
class Game {
public void play(SmartPhone phone) {
if (phone instanceof Iphone)
System.out.println(phone.getClass.getSimpleName());
}
if (phone instancedof Gallaxy)
System.out.println(phone.getClass.getSimpleName());
}
}
따라서 다음과 같은 방법으로 수정해 줘야한다
public class Test {
public static void main (String [] args) {
Lists<SmartPhone> phoneList = Arrays.asList(new Iphone(), new Gallaxy());
Game game = new Game();
phoneList.forEach(game::play);
}
}
interface SmartPhone {
void game(Game game);
}
class Iphone implements SmartPhone {
@Override
public void game(Game game) {
System.out.println(this.getClass().getSimpleName());
}
}
class Gallaxy implements SmartPhone {
@Override
public void game(Game game) {
System.out.println(this.getClass().getSimpleName());
}
}
}
class Game {
public void play(SmartPhone phone) {
phone.game(this);
}
}
추상 클래스와 일반 클래스의 차이
ex)
àbstract class Tv {
public String tvName;
public void View() {
System.out.println("TvOn");
}
abstract void getMaker();
}
class Samsung extends Tv {
public void View() {
System.out.println("SamsungTv on");
}
void getMaker() {
System.out.println("Samsung");
}
}
추상 메소드의 접근 지정자로는 private 불가능
⇒ private 지정시 다른 클래스가 상속을 받을수 없다
추상 클래스는 다른 클래스에서 공통으로 가져야하는 메소드를 정의해준다.
어떤 추상클래스를 상속 받은 자식 클래스에서 추상 메소드를 구현 하지 않았다면 자식 클래스도 추상 클래스가 되어야함.
Final 클래스란?
Final 메소드란?
https://scshim.tistory.com/210
https://velog.io/@dion/백기선님-온라인-스터디-6주차-상속
https://multifrontgarden.tistory.com/133