상속(inheritance), 메서드 재정의, 부모 생성자 호출, 부모 메서드 호출, 컴포지션

kmb·2022년 2월 3일
0

자바

목록 보기
12/31
post-thumbnail

상속

부모클래스(상위클래스)의 필드(field)메서드(method)를 자식 클래스(하위 클래스)가 물려 받아서 그대로 사용 할 수 있는것.

  • 클래스 상속의 선언

자식 클래스가 extends 키워드를 사용하여 상속할 부모 클래스를 지정한다.

class 자식클래스 extends 부모클래스 {
	
    // 필드
    // 생성자
    // 메서드
}

 

  • 상속의 특징
  1. 부모 클래스에서 private 접근 제한을 갖는 필드, 메서드는 상속 대상에서 제외.
  2. 부모 클래스와 자식 클래스가 다른 패키지에 존재한다면 default 접근 제한을 갖는 필드, 메서드는 상속 대상에서 제외. (그 이외의 경우에는 모두 상속 가능)
  3. 다중 상속 불가능. (여러개의 부모클래스를 상속 할 수 없다)

 

  • 상속의 목적
  1. 추상화
  2. 필드(field)메서드(method)를 물려받아서 유지 보수를 쉽도록 하기 위함.
    (단 타입이 일치되어야 한다. 겹치지않는 상태만 물려받는다.)

 

  • 부모 생성자 호출

자식 클래스를 이용해서 자식 객체를 생성하면, 내부적으로 부모 객체가 먼저 생성되고 자식 객체가 그 다음에 생성된다.

자식 클래스의 객체를 생성할때 생성자가 명시적으로 선언되어있지 않다면 컴파일러는 super( ) 메서드를 사용하여 부모 클래스의 기본 생성자를 생성한다. 이때 super( ) 메서드는 반드시 자식 생성자 첫 줄에 위치해야한다.

자식클래스 인스턴스변수 = new 자식클래스();

public 자식클래스() {
	super();
}

public 부모클래스() {

}

 

ex) 부모 생성자 호출 예시

public class CellPhone {  // CellPhone : 부모클래스
	
    public String name;
    public String number;
    
    public CellPhone(String name, String number) {
    	this.name = name;
        this.number = number;
    }
}

public class DmbCellPhone extends CellPhone {  // DmbCellPhone : 자식클래스
	
    public int price;
    
    public DmbCellPhone(String name, String number, int size) {
    	super(name, number);
        this.price = price;
    }
}

public class DmbCellPhoneEx {
	
    public static void main(String[] args) {
    	
        DmbCellPhone dcp = new DmbCellPhone("갤럭시", "010-1111-2222", 1000);
        
        System.out.println("name = " + dcp.name);		// name = 갤럭시 (부모클래스에서 상속받은 필드 출력)
        System.out.println("number = " + dcp.number);   // number = 010-1111-2222 (부모클래스에서 상속받은 필드 출력)
        
        System.out.println("price = " + dcp.price);     // price = 1000
    }
}



메서드 재정의

부모 클래스에게 물려받은 메서드를 자식 클래스에서 @Override 를 이용하여 다시 수정하는것.

메서드가 오버라이딩 되었을때 자식 객체에서 메서드를 호출하면 된다면 부모 객체의 메서드는 숨겨지고 자식 메서드가 호출된다.

 

  • 메서드 오버라이딩(@Override) 특징

1) 오버라이딩된 자식 메서드는 부모 메서드와 동일한 시그니처(반환타입, 메서드이름, 매개변수)를 가져야한다.

2) 접근 제한자를 더 강하게 오버라이딩 할 수 없다. (반대는 가능)

ex1) 부모메서드가 public 접근제한을 갖고 있을 때 오버라이딩된 자식메서드는 default나 private 접근제한을 가질 수 없다. (x)
ex2) 부모메서드가 default 접근제한을 갖고 있을 때 오버라이딩된 자식메서드는 default나 public 접근제한을 가질 수 있다. (o)

3) 새로운 예외(Exception)를 throws 할 수 없다.

 

  • 부모 메서드 호출(super)

자식 클래스에서 부모 클래스의 메서드를 오버라이딩하게 되면, 부모 클래스의 메서드는 숨겨지고 오버라이딩된 자식 메서드만 사용된다.
그런데 만약 자식 클래스 내부에서 부모 클래스의 메서드를 호출해야 한다면 super.부모메서드( ); 로 부모 메서드를 호출 할 수 있다.

public class Airplane {	    // Airplane : 부모클래스
	
    public void land() {
		System.out.println("착륙한다");
	}
    
    public void fly() {
    	System.out.println("일반 비행한다");
    }
    
    public void takeOff() {
    	System.out.println("이륙한다");
    }
}

public class SupersoicAirplane extends Airplane {   // SupersoicAirplane : 자식클래스
	
    public static final int NORMAL = 1;
    public static final int SUPERSONIC = 2;
    
    public int flyMode = NORMAL;
    
    @Override
    public void fly() {
    	
        if(flyMode == SUPERSONIC) {
        	System.out.println("음속 비행한다");
        }else {
        	super.fly();  // Airplane 부모클래스의 fly() 메서드 호출
        }
    }
}

public class SupersoicAirplaneEx {
	
    public static void main(String[] args) {
    	
        SupersoicAirplane sa = new SupersoicAirplane();
        sa.takeOff();  // 이륙한다
        sa.fly();  // 일반 비행한다
        sa.flyMode = SupersoicAirplane.SUPERSONIC;  
        sa.fly();  // 음속 비행한다
        sa.flyMode = SupersoicAirplane.NORMAL;
        sa.fly();  // 일반 비행한다
        sa.land(); // 착륙한다
        
    }
}

 


컴포지션

다른객체의 인스턴스를 자신의 인스턴스 변수로 포함해서 메서드를 호출하는것

 
상속과 컴포지션의 예시

class Engine {
	int power = 2000;
	
}

class Car {
	
	Engine e;	// 가져와서 사용하는것 -->  컴포지션 (=결합)
	
	public Car(Engine e) {	// 생성자
		this.e = e;
	}
}

class Hamburger {
	String name ="기본햄버거";
	String material1 = "양상추";
	String material2 = "패티";
}

class CheeseHamburger extends Hamburger {	 //  상속가능 (상태, 행위 물려받을수 있음.  타입이 일치해야된다.)
	String name = "치즈햄버거";
}

class ChickenHamburger {
	
	Hamburger h;  // 가져와서 사용하는것 -->  컴포지션 (=결합)
	String name = "치킨햄버거";
	
	public ChickenHamburger(Hamburger h) {	// 생성자
		this.h = h;
	}
}

public class OOPEX02 {

	public static void main(String[] args) {
		Engine e1 = new Engine();
		Car c1 = new Car(e1);
		System.out.println("자동차 엔진 마력 : " + c1.e.power);
		
		CheeseHamburger ch1 = new CheeseHamburger();
		System.out.println("햄버거 이름 : " + ch1.name);
		System.out.println("재료들 이름 : " + ch1.material1 + ", " + ch1.material2);
		
		Hamburger h1 = new Hamburger();
		ChickenHamburger ckh1 = new ChickenHamburger(h1);
		System.out.println("햄버거 이름 : " + ckh1.name);
		System.out.println("재료들 이름 : " + ckh1.h.material1 + ", " + ckh1.h.material2);
	}
}

타입이 일치할 경우 상속을 받거나 컴포지션을 통해서 재사용 할 수 있다.

 

출처

  • 이지업 컨텐츠 내의 데어프로그래밍 자바강의
  • 이것이 자바다 (책)
profile
꾸준하게

0개의 댓글