[Java] 메서드 오버라이딩(Overriding)

2022. 10. 5. 14:48Dev.Program/Java & Spring

728x90

< 단축키 정리 >

Getter / Setter 단축키

  • Alt + Shift + S → R 

생성자 단축키

  • Alt + Shift + S → O

Import 단축키

  • Ctrl + Shift + O

오버라이딩 단축키

  •  Alt + Shift + S → V

 

======== 오늘날짜 프로젝트 만들고 Ex.java 만들기

< 메서드 오버라이딩 = 재정의 >

p. 225

  • 슈퍼클래스로부터 상속받은 메서드와 시그니쳐(이름, 파라미터 등)가 완벽하게 동일한 메서드를 새롭게 재정의하는 것
    • ⇒ 기존의 부모의 메서드를 자식이 새롭게 수정하는 것
  • 오버라이딩 후 슈퍼클래스의 메서드는 은닉되어 보이지 않는다.

< 오버라이딩 규칙 >

  1. 상속이 전제되어야 함
  2. 메서드 시그니쳐(이름, 파라미터 타입, 파라미터 갯수, 리턴타입)가 동일해야함
  3. 접근제한자는 슈퍼클래스의 메서드와 같거나 넓어야 함(확대만 가능)
    • ⇒ (좁은)  private < default < protected < public  (넓은)
    • ex) 슈퍼클래스 메서드가 public 이면, 오버라이딩 메서드는 public 만 가능
  4. 예외클래스 사용 범위는 축소만 가능함
  5. private, static, final 키워드가 사용된 메서드는 오버라이딩 불가

 

메서드 오버라이딩(=재정의) / 메서드 오버로딩(=다중정의) 헷갈리지 않기! (개념 잘 익히기)

  • Ex.java

  • 오버라이딩 됨(덮어쓰기)
  • 출력창이 다르다!

 

class Animal {
	String name;
	int age;

	public void cry() {
		System.out.println("동물 울음 소리!");
	}
}
 
  • Animal 클래스 정의

  • Animal 클래스를 상속받은 Dog와 Cat 클래스 : 동물 울음 소리!

  • 오버라이딩 후엔 오른쪽 위 출력창이 뜸



  • 자바에서는 다중 상속 불가! (= 두개 이상의 슈퍼클래스를 가질 수 없다)

  • 대신 클래스 안에서 인스턴스를 만들어서 쓸 수는 있음!



 

======== Test.java 만들기 → 지난시간 Test.java 열어서 Account 클래스 복사해오기

> 출금(withdraw()) 메서드 오버라이딩

⇒ 잔고가 부족해도 무조건 출금을 수행하도록 오버라이딩

class ItwillBank extends Account { // 상속이 기본 전제조건!
    public int withdraw(int amount) { // 이름 똑같이 만들어야 함
        System.out.println("출금할 금액 : " + amount + "원");
        balance -= amount;
        System.out.println("현재잔고 : " + balance + "원");
        return amount;
    }
}​

 

  • 오버라이딩 자동 생성 단축키 : Alt + Shift + S → V

  • 체크
  • 자동으로 생성된다.

 

  • Car 클래스를 정의하고

  • Taxi 클래스 안에서 Alt + Shift + S → V 누르면 오버라이딩 자동 생성!

  • Truck 클래스도 똑같이 만들어줌.

  • 출력했을 때 오버라이딩 된 것을 확인할 수 있다!

 

< @ 어노테이션(Annotation) >

  • @Override 같은 @ 표시
  • JEE5(Java Platform, Enterprise Edition 5)부터 새롭게 추가된 요소
  • 데이터의 유효성 검사 등을 쉽게 알 수 있고, 이와 관련한 코드가 깔끔해 짐

@Override

  • 선언한 메서드가 오버라이드 되었다는 것을 나타냄
  • 만약 상위(부모) 클래스(또는 인터페이스)에서 해당 메서드를 찾을 수 없다면 컴파일 에러를 발생

 

> 229p 어노테이션

@override ← 자동생성 하면 생기는 얘가 하는 일이 없는게 아니다!

@override 라고 달려있으면, 여기는 override만 수행할 거라고 컴퓨터한테 알려주는거

  • @override 가 달려있을 때에는 override 만 해야하는데 저렇게 뒤에 String을 추가하는건 Overload의 기능! 그래서 에러남!

  • @Override 주석을 지워주면 오류 안나는 것을 확인할 수 있다(Overload가 된거)

 

======== Ex2.java 새 문서 만들기

p.229

< 레퍼런스 super >

  • 슈퍼클래스의 인스턴스 주소를 담는 참조변수(자동 생성)
  • 사용법은 레퍼런스 this 와 동일
  • 은닉된 멤버(변수 또는 메서드)에 접근할 때 사용
    • ⇒ 오버라이딩 시 슈퍼클래스의 멤버변수 또는 메서드가 보이지 않을 때 슈퍼클래스의 멤버에 접근하는 키워드
  • 단, 접근 범위는 1촌(부모)까지만 가능

< 기본 문법 >

super.멤버변수
또는
super.메서드()
 

 

  • Child2에 아무것도 안하면, Parent2의 부모님 tv 시청! 이라고 나옴

  • 메서드 오버라이딩 시 출력창

  • 메서드와 멤버변수 둘 다 오버라이딩 시 출력창
  • 이제 Parent2 클래스의 String tv = “부모님 tv” 는 안보임. 

⇒ 이걸 은닉변수라고 이야기한다!



  • 평소에는 super()를 쓸 일이 없는데,
  • 오버라이딩 시 (은닉된)부모클래스를 받아올 때 super(); 로 받아올 수 있음!
  • this.tv ⇒ 내 티비
  • super.tv ⇒ 부모님 티비



< Ex2.java >

  • 결과 비교해보고 위 아래 차이 잘 보기!

 

> super.watchTv(); 는 이미 Parent2로 갔기 때문에 tv 도 부모님tv 를 가리킴.



< Ex2.java > → class Child2_2 extends Parent2_2 {}

  • 타입만 있으면 로컬변수
  • 클래스 이름까지 나오면 인스턴스변수
class Parent2_2 {
    String x = "parent";
}

class Child2_2 extends Parent2_2 {
    String x = "child";
    public void method() {
        String x = "method";
        System.out.println("x = " + x);
        System.out.println("this.x = " + this.x);
        System.out.println("super.x = " + super.x);
    }
}​
  • 출력창! 세가지 구분 잘 하기!!

 

  • 주석처리 하게되면
  • 가장 먼저 만나는 x 가 됨.  (교재 p231 참고)
  • 무조건 제일 가까운 x 를 찾아간다.

 

======== Ex3.java 만들기

p.232-233

< 생성자 super() >

  • 슈퍼클래스의 생성자를 명시적으로 호출
  • 슈퍼클래스의 멤버변수와 서브클래스의 멤버변수를 동시에 전달받아 초기화를 수행하려 할 때, 슈퍼클래스의 초기화 코드와 중복되는 경우 중복을 제거하기 위해 슈퍼클래스의 생성자를 호출하여 대신 초기화를 수행
    • ⇒ 자신의 멤버변수만 자신이 직접 초기화하여 중복 코드를 제거
  • 슈퍼클래스의 생성자 파라미터와 동일한 형태로 호출해야함
  • 반드시 생성자의 첫번째 라인에서 호출되어야 함
    • ⇒ 생성자 this() 와 생성자 super() 는 동시 사용 불가능
  • 생성자 내에서 생성자 this() 또는 생성자 super() 호출 코드가 없다면 컴파일러에 의해 슈퍼클래스의 기본 생성자가 자동으로 호출됨
    • ⇒ super(); 코드가 첫 줄에 자동으로 추가됨
  • 서브클래스 생성자에서 자동으로 슈퍼클래스의 기본 생성자가 호출될 때 슈퍼클래스에 기본 생성자가 존재하지 않으면 오류 발생!
    • ⇒ 따라서, 명시적으로 슈퍼클래스의 다른 생성자를 호출하거나 슈퍼클래스에서 기본 생성자를 정의하도록 해야한다!

< 기본 문법 >

--------생성자 내에서--------
super([파라미터...]);
--------형태로 사용--------​

 

this.name = name;

this.salary = salary;

⇒ Employee 와 중복되는 코드!

  • 파라미터 있는거 선택!

  • super(name, salary) 주석 처리 후 실행하면 원래  Employee() {} 안의 내용이 나옴
  • 주석처리를 풀면 출력창이 바뀜. ( 이제 Manager 꺼 초기화시킨 내용이 잘 나옴! )

  • super(name, String) 주석 처리한 상태에서 위에 Employee() {}까지 주석처리 하면 오류뜸! (빨간줄) ⇒ 오류창 내용 잘 보기
  • 위에 public Employee(String name, int salary) {} 가 있기 때문에 빈 Employee() {} 는 자동으로 생성 안해줌. 그래서 오류가 뜬다!

  • public Employee() {} 이렇게만 만들어줘도 오류 없어짐!
  • 근데 이 방법 보다는
class Manager extends Employee {
    String depart;
    public Manager(String name, int salary, String depart) {
        super(name, salary);
        this.depart = depart;
    }
}​
  • super(name, salary);
  • 이렇게 명시적으로 호출해주는 방법이 좋음! (똑같이 오류 없어짐)

# 명시적으로 이렇게 호출해주는 방법이 가장 좋지만 우리는 아직 배우는 단계라 헷갈릴 수 있으니(잘 모르니까) 처음에 public Employee() {}; 이렇게 빈 생성자만 만들어줘도 오류를 줄일 수 있다! (그치만 명시적으로 호출해주는 방법이 가장 좋음)

 

728x90