DAY06(2) - 상속성 , 다형성

은나현·2023년 1월 30일
0

📌 1. 상속성

📍 1-1. 클래스 간의 상속이란?

  • 클래스간에는 부모 - 자식의 상속 관계를 설정할 수 있다.
    • 부모 클래스 A를 자식 클래스 B가 상속받을 때, B는 A의 모든 멤버변수와 메서드를 자신의 것으로 상속받게 된다.
    • 상속 가능 여부 : public, protected
      • B는 A의 public, protected 기능들을 직접적으로 코딩하지 않더라도 자신의 것으로 사용할 수 있게 된다.

📍 1-2. 상속 정의 방법

  • extends 키워드를 사용하여 부모 클래스의 이름을 명시한다.

    public class 자식클래스 extends 부모클래스{...}

📍 1-3. 클래스 다이어그램을 통한 상속 표현

  • 클래스의 구조를 표현하는 클래스 다이어그램에서, 상속은 자식 클래스가 부모 클래스를 가리키는 화살표로 표현한다.
  • 상속관계가 이루어질 때 부모 클래스를 super클래스라 한다.


📌 2. 다형성 - Override

📍 2-1. 오버라이딩(Override)이란?

  • 부모 클래스가 갖고 있는 기능을 자식 클래스가 재정의할 수 있다.
    • 부모 클래스에 정의된 것과 동일한 이름을 갖는 메서드를 자식 클래스가 정의한 경우, 부모 클래스의 기능은 자식에게 가려진다.
    • 이렇게 부모의 기능을 재정의하는 것을 메서드 Override라 한다.
  • 하나의 이름으로 다양한 효과를 얻을 수 있다.
    • 모든 자식 클래스가 동일한 이름의 메서드를 갖게 되므로 각 객체에 대하여 같은 이름을 사용하여 서로 다른 형태를 구현할 수 있게 된다.

📍 2-2. super 키워드

  • 클래스의 상속관계에서 자식 클래스가 부모 클래스를 가리키는 예약어

- 사용 방법

  • 멤버변수 이름 앞에 명시

    • 부모클래스의 멤버변수를 의미한다.
      하지만 부모클래스의 멤버변수는 이미 모두 상속되어 있기 때문에 이 경우에는 this키워드를 사용하는 것과 동일한 결과이므로 잘 사용하지 않는다.
  • 메서드 이름 앞에 명시

    • 부모 클래스의 메서드를 의미한다.
      - 재정의되지 않은 메서드 : 이미 상속되어 있기 때문에 this키워드를 사용하는 것과 동일한 결과를 갖는다.
      - 재정의된 메서드 : Override된 메서드 이름 앞에 사용하게 되면 재정의되기 이전의 원본 메서드를 의미한다.
    class Hello {
    	public void say(){
    		System.out.println("Hello");
    	}
    }
    class Korean extends Hello{
    	public void say(){
    		System.out.println("안녕하세요");
    	}
    	public void sayHello(){
    		super.say();
    		this.say();
    	}
    } 
    //출력결과-------------------------------------------------------------
    Hello
    안녕하세요
  • 키워드 자체를 메서드처럼 사용

    • 부모 클래스의 생성자를 의미
      - super();

📍 2-3. 상속 관계에서의 생성자 처리

  • 생성자가 정의된 클래스의 상속 제한
    • 생성자가 정의된 클래스는 객체 생성을 위해서 생성자 파라미터를 반드시 전달받아야 하기 때문에 파라미터를 갖는 생성자가 정의된 클래스를 상속받게 되면 에러가 발생한다.
      • 생성자가 정의된 클래스를 상속받은 경우에는 자식 클래스의 생성자를 통해서 부모 생성자를 강제로 호출해야 한다.
      • 부모의 생성자를 호출하는 방법은 super키워드를 메서드 이름으로 사용하는 것이다.

➕ @Override

  • 메서드 재정의 과정에서의 오타 방지 옵션
    • @Override는 키워드가 명시된 위치 아래에 정의되는 메서드가 부모 클래스에 존재하지 않을 경우 구문 에러로 처리한다.
    • 부모 클래스의 메서드를 재정의하고자 할 경우, 의도치 않은 실수를 예방하기 위한 오타방지 옵션이다.

📌 3. 다형성 - Overload

📍 3-1. 메서드 오버로드(overload)

  • 원칙적으로 하나의 클래스 안에서는 동일한 이름의 메서드가 두 개 이상 존재할 수 없지만, 이를 가능하게 하는 예외적인 처리 기법
  • 이름이 동일한 메서드를 정의하기 위한 조건
    • 메서드간의 파라미터가 서로 달라야 한다.
      • 파라미터의 데이터 타입이 다르다.
        (데이터 형이 동일하고 변수의 이름이 다른 경우는 동일한 파라미터로 인식된다.)
      • 파라미터의 개수가 다르다.
      • 서로 다른 데이터형을 갖는 파라미터들의 전달 순서가 다르다.
      • 리턴형이 다른 경우는 오버로드의 성립에 아무런 영향을 주지 않는다.

📍 3-2. 오버로드의 예시

  • 파라미터의 데이터 형이 서로 다른 경우
	public void foo(int a){}
	public void foo(long a){}
  • 파라미터의 개수가 서로 다른 경우
	public void foo(int a){}
	public void foo(int a, int b){}
  • 데이터형의 전달 순서가 다른 경우
	public void foo(int a, String b){}
	public void foo(String a, int b){}
  • 오버로드가 성립하지 않는 경우 (변수명만 다른 경우)
	public int foo(int a)
	public String foo(int x)

📍 3-3. 생성자의 오버로드

  • 생성자 역시 메서드의 한 종류이므로 오버로드Overload가 가능하다.
  • 생성자를 Overload할 경우, 해당 클래스에 대해 객체를 생성하는 방법을 다양하게 준비할 수 있게 된다.
    • 예시
    	public Member() {		
    	}
        ----------------------------------------------
    	public Member(int age) {
    		this.age = age;
    	}
        ----------------------------------------------
    	public Member(String job) {
    		this.job = job;
    	}
        ----------------------------------------------
    	public Member(String job, int age) {
    		this.job = job;
    		this.age = age;
    	}

📍 3-4. this 키워드를 사용한 생성자 오버로드

  • this 키워드를 메서드처럼 사용할 경우, 현재 클래스의 다른 생성자를 의미한다.
  • 이 키워드를 사용하여 생성자 Overload를 간결하게 처리할 수 있다.
    • 예시 코드
    class Hello{
    	public Hello(String msg){
    		System.out.println(msg);
    	}									
    	public Hello(){
    		this("Hello");				//아래줄 코드와 동일한 기능을 간결하게 처리할 수 있다.
    		//System.out.println("Hello");
    	}
    }

0개의 댓글