본문 바로가기
코딩

2022.02.16_8일차_상속과 오버라이딩

by 흥뷰자 2022. 2. 22.

08일차 학습내용

1. static 키워드
2. final 키워드
3. 상속 inheritance
4. 상속과 접근제어자
5. 상속과 생성자
6. 오버라이딩 overriding

 

 


1. static 키워드 : this키워드와 함께 하실 수 없습니다~~~

  
메서드와 변수앞에 붙어서 클래스변수 클레스메서드를 만듭니다. 
(캡슐화 클래스 안에 담아서 공개범위 지정, 무분별한데이터 훼손 방지위해 우회하게도록 유도, 프로그램 내 접근)
모든 아이들에게 전체 공개 해서 쓸 때 static 붙입니다. 

static이 붙으면 별도로 객체 생성없이 사용 가능합니다. 그래서 클래스 내부 매서드 또는/ 객체를 생성했을 때 사용하는 생성자 내부의 this키워드는 쓸일이 없죠. 

 

static은 왜 객체생성없이 사용가능하냐? 바로 static이 붙은 아이들은 프로그램이 시작되면 호출하지 않아도 가장 먼저 메모리에 올라가기 때문입니다. static이 붙지 않은 인스턴스 멤버는 생성하지 않으면 존재하지도 않기 때문에 해당 멤버가 담긴 객체가 생성도 되기 전에 접근은 불가합니다.  

 

 

코드를 작성할 때, 언제 static을 붙이나요?

* 코드를 작성하는 순서. 

어떤 변수 메서드에 어떤 접근지정자, 로딩순서, 출력, 입력값을 어떻게 붙여야 하는지 난감할 수 있습니다. 딱 제 얘기입니다. 이 때 따라야 할 절차입니다.
> 코드 짤때 클래스 내 메서드 안에 다 써본다. 메서드는 기능별로 작성. 지역변수로 다 만든다
> 클래스끼리 함께 써야하는 변수를 위로 뺀다 
> 프로그램시작부터 모두 공유해야 하는 변수를 static를 앞에 붙인다

 



2. final 상속에서.... / 세 군데에서 붙일 수 있습니다.

 

1) final 클래스
클래스 앞에 붙으면, 상속 할 수 없음을 지정합니다. 부모클래스가 될 수 없죠.

final class FinalClass {  }

2) final 메서드
메서드 앞에 붙으면, 오버라이딩을 할 수 없음을 선언합니다. 더이상 이 코드를 수정하지 말아라~~~

final int finalMethod () { ... }

3) final 변수
변수 앞에 붙으면, 상수가 됩니다.  상수는 한 번 초기화되면 값을 변경할 수 없습니다. 

(선언만 한 경우라면 외부값을 받아서 넣을 수는 있습니다.) final int ROW;

 

final int row = 10; // 상수선언 + 초기화
row = 20; (X)

코드로수정불가한데, 이름만 봐서는 변수인지 상수인지 구분이 안가는 문제가 생깁니다. 
//so 관례적으로 상전체 대분자로 써줍니다.

 

final int ROW = 10;
ROW = 20; 

public static final double PI = 3.14...; // Math클래스에 있는 상수 예시 




3. 상속 inheritance   


1) 클래스와 클래스 사이(1:1)의 부모자식 관계를 만드는 것입니다.
2) 자바는 다중상속 X (파이썬은 O) (다중상속이 안되니까 손녀로 내려가면 같은 효과가 납니다.)  
3) 상속은 부모의 변수, 메서드를 물려받는 것인데, 이 때 메모리 점유한 객체 사이의 상속이 아닌 설계도(클래스 정의부분)를 상속하는 것을 의미합니다. 
4) 상속 시, 생성자와 초기화 블럭은 제외됩니다. 부모는 부모거 따로 가져있고 자식은 자식것. 가져다 쓸수는 있으나 물려받지는 않습니다. 자식이 부모를 상속해서 객체생성이 된나면 상속 기능을 온전히 실행시켜야 하기 때문에 부모의 초기화 블럭도 함께 실행됩니다.
5) 상속 키워드 : extends (확장 , 부모의 성질 + 내 고유 멤버 추가)
6) 상속 받으면 부모의 멤버들을 자식이 담게됩니다. (눈에는 안보이지만) -> 자식은 부모의 것과 함께 자식만의 변수와 메서드를 갖게 됩니다. 자식으로 객체를 생성하고 덮어쓰기를 한다면, 부모의 객체를 생성하면 동일 멤버도 다르게 나타납니다.
7) 필요한 이유: 코드 중복을 제거, (가독성) 유지보수 편의성, 소프트웨어 생산성 향상.

부모클래스 = super = parent = base
자식클래스 = sub = child = derived

class Object {} // 인류의 조상님. 클래스라면 오브젝트를 다 상속받는다.
class Parent {} /// final만 안붙으면 부모도 자식도 다 될 수 있다.  // 할미할비 : x
class Child extends Parent {} // 엄마아빠 : x, y
class Child2 extends Parent {} // 이모나 삼촌 (남이다) : x, a
class GrandChild extends Child {} // 아들, 딸 : x, y, 가나다

내가 작성하지 않은 메서드들

우리가 코드를 작성할 때 객체를 생성하고 그 내부 멤버에 접근하려는 때, 우리가 만든적 없는 메서드들이 나오는 이유?

Object클래스에서 물려받은 것들이 그대로 나한테 들어와 있기 때문입니다. 


8) Object 클래스 : 모든 클래스의 조상 

Object의 11개 메서드 설명 
노티파이 웨이트 쓰레드에서 쓰레드를 제어할 때 사용. 
equals toString 필요한 거 오버라이딩해서 쓰라고 만들어 놓은것.

9) package : 프로그램에서 폴더/ 디렉토리들 말함.
보통 패키지는 3수준까지 내려가는 폴더 이름을 작성

java.awt.color.클래스

10) java.lnag : 자바표준API에서 많이 쓰는것들을 묶어놓은 것. 가장 기본적인 package 
모든 클래스의 최고 부모. 해당 패키지에 있는 건 임포트 없이 쓸 수 있음



상속받으면 접근제어자 어떻게되나? <12:40 



4. 상속과 접근제어자


1) 수퍼클래스의 private 멤버
서브클래스 포함 다른클래스에서 접근X // 부모 안에서만 쓸수 있는것
2) 수퍼클래스의 default 멤버
서브클래스라도 다른 패키지면 접근X // 우선순위가상속과 관계없이 접근제어제쓰면됨
3) 수퍼클래스의 public 멤버 
모두 접근 가능
4) 수퍼클래스의 protected 멤버
같은 패키지의 모든 클래스 접근 가능
패키지 상관없이 서브클래스 접근 가능




5. 상속과 생성자  


1) 서브 수퍼클래스의 생성자 호출 및 실행
상속받으면 서브클래스의 생성자도 실행하고, 부모클래스의 생성자도 실행해야 
즉 객체를 초기화해야 객체 온전히 쓸수 있으니까 둘다 실행됩니다~~   

2) 서브클래스에서 수퍼클래스 생성자를 선택할 수도 있고 안 할 수도 있는데
수퍼클래스의 생성자가 여러개 있는 경우,
개발자가 자식생성자에서 특정 부모생성자를 명시적으로 지정하지 않은 경우,
부모의 기본생성자를 자동으로 실행시킵니다. (부모의 기본생성자 실행되도록 컴파일됨)

분명하게 수퍼클래스의 어떤 상속자를 호출할지 지정하거나, 안할거면 부모클래스에 기본생성자를 작성해야합니다.

#1. 이 때, 수퍼클래스의 기본생성자가 자동으로 선택되는 경우
-> 이때 부모 클래스에 기본생성자가 없으면 에러가 나겠죵. 

#2. 부모의 생성자를 개발자가 명시해서 실행하고 싶을 경우  ////상속은 생성자를 못받으니까 딱 지칭해줘야합니다.
super();를 이용하여 명시해줄 수 있다. / 원래는 기본생성자라도 적는게 원칙입니다. 

 

===== 정리 =====

부모클래스에 기본생성자가 없다? 자식 클래스는 매개변수 정확히 넣어서 부모생성자를 호출해야 하고

부모 클래스에 기본생성자가 있다? 자식클래스는 편하게 상속시켜 확장이 가능해집니다

 

이때 사용하는 키워드가 super() 메서드

7일 차 수업에서 this() 생성자 내부에서 자신 클래스에 오버로딩된 다른 생성자를 호출할 때 쓴다고 했는데요,

super()는 부모클래스의 생성자를 호출해주는 명령어가 됩니다.

즉, super()는 부모가 있는 상속받은 클래스에서만 사용 가능허다~~는 말이됩니다.  

super()도 this처럼 생성자 내부에서 첫번째 명령이 되어야 하니까 여러개를 쓸 수 없습니다.



6. 오버라이딩 overriding     // 6일차 배운 오버로딩이랑 다릅니다. 


1) 상속관계에서 성립합니다. 단순한 덮어쓰기를 의미하는 것은 아닙니다. 메서드 덮어쓰기!
2) 재작성, 덮어씌우기, 재정의한다~~
부모 클래스의 메서드가 맘에 안들어 내용을 변경해서 사용하는 것입니다. (변수 덮어쓰는 건 그냥  대입이라고 하지요)
3) 메서드 선언부는 똑같이, (선언부는 중괄호 전리기 전까지 부분, 중괄호 부분은 구현부)
영역{} 안 내용만 바꾸는 것이죠. 
4) 오버로드와 완전히 다른 것. 오버로딩는 여러개가 함께 공존하는것. 새로운 메서드를 만드는 것.  
오버라이딩은 내용물을 대체해서 마지막것만 존재. 덮어씌우기 (투스트링)
5) "동적바인딩" : 서브에 오버라이딩 메서드가 있으면,
수퍼클래스의 메서드를 무시하고, 서브클래스에서
오버라이딩된 메서드가 무조건 실행되도록 하는 것. // 자식이 오버라이딩 하면 부모거 무시됨.
//부모의 a 매서드 - 자식이 상속받으면, 오버라이딩 하면, 오버라이딩된 메서드 실행되면 자식의 메서드가 실행
// 부모객체로 a 실행되면 당연히 부모메서드로 실행되는거고.
6) 부모거를 그냥 쓸거면 키워드 super : 연산자
  super : 수퍼클래스에대한 레퍼런스 : 부모를 지칭하는 것.
  super.부모의메서드명()
서브클래스에 메서드 오버라이딩시, 동적바인딩으로 오버라이딩된 메서드가 자동으로 호출되는데,
수퍼클래스의 멤버를 호출하고자 할 때 사용되는 키워드 
이 키워드를 쓰면 동적바인딩(자동dynamic) 하지 않고 정적으로(수동static) 수클의 메서드에 접근이 가능해짐.

 

*
오버라이딩을 오타 없이 잘 하려면~

메서드명만 일부 입력 후 Ctrl + Space  < @어노테이션. 메서드별로 각각 달아줘야합니다.
가독성면과 오타 방지 위해 붙이는게 좋음. 자바한테 알려주는거니까~ 이름이 다르면 오타라고 알려줍니다. 안붙이면 새로운 메서드로 인식합니다.

 

 

오버라이딩을 실습에서 가장 많이 보는 것 중 하나가 toString()메서드에 오버라이딩을 하는 것입니다.

참조형 객체를 출력해보면 디폴트값으로 그거에 대한 대표로 주소값관련 정보를 돌려주게 되어있습니다. 이러한 디폴트값을 사용자가 정의해서 보고싶은 것으로 바꾸려면 클래스 아래에 toString()를 오버라이드해주어야합니다.

 




Test90 .contains()메소드 문자열이 갖는 내장 메소드인데 
이름이 동일한 메서드를 Rectangle클래스에 만들어 놓은 것. 








댓글