Java

접근지정자, 상속

무르뇌 2022. 7. 12. 12:48

기본적으로 package가 다르면 서로 접근이 불가능하다.

이것을 가능하게 하는 방법이 import 문을 사용하는 것이다.

문법:
import 패키지명.패키지명2.클래스명; ==> ex) com.google.Object (일반적으로 도메인을 거꾸로)

import 패지지명.패키지명2.*;   ==> * 에스크리터는 패키지 안 클래스 모두를 사용한다는 의미.// 권장하지 않음

why?  어떤 클래스를 사용하는지 모르기 때문.

 

패키지명을 안써도 디폴트 패키지가 자동으로 만들어진다.

api 문서를 보면 알 수 있겠지만, java.lang 패키지는 따로 import 시키지 않아도 된다. -> 많이 쓰여서 알아서 import 됨

패키지는 클래스 관리를 용이하기 위해 사용한다. -> 그만큼 파일을 잘 관리할 것.

 

패키지명이 다르면, 클래스명이 동일하더라도 사용 가능하다.(com.stu.student, com.stu1.student 은 사용 가능)

==> 단 클래스명이 동일할 경우, 하나는 import로 사용가능하지만, 나머지 하나는 다이랙트로 입력해줘야한다.

ex) Student 동일 클래스명으로 다른 패키지 stu1, stu2에 있을때

import stu1;

Student s1 = new Student();  -- stu1 패키지

stu2.Student s2 = new stu2.Student();  -- stu2 패키지

JAVA에서 제공하는 API 패키명이 java로 시작하기 때문에, 패키지명 작명 시 java로 시작하면 안된다.

 

접근지정자

1. public : + 제약x 서로 다른 패키지도 접근 가능.

2. protected #  같은 패키지만 접근 가능, 패키지가 달라도 접근 가능할 경우는 상속 관계여야한다.

3. default  같은 패키지만 접근 가능

4. private:  -  같은 클래스에서만 접근 가능

위 접근지정자 순으로 public -> private (1~4번순)으로 갈수록 제약이 커진다

 

static

클래스 작성의 경우 outer 클래스 및 inner 클래스가 있음

위 두가지 클래스를 동시 사용시 inner 클래스에서만 사용 가능하다.

메서드에서 사용할 시, 객체 생성 없이 메서드를 사용하기 위함.

변수: 프로그램 내에서 특정 데이터 값을 계속 유지할 목적이라면 static 변수가 적합.

static 키워드는 프로그램 실행 시 단 한번 생성됨. (method area 메모리 영역)

인스턴스 메서드 및 변수는 객체 생성(new)시 생성  -- heap 메모리 영역 , 객체 소멸시 삭제

static 키워드의 경우 클래스명으로 바로 접근 가능하다

인스턴스 키워드의 경우 객체 명으로 접근 가능하다.

static에서 힙쪽으로는 접근 x

힙에서는 static으로 접근 가능 

why?  static은 이미 생성이 돼있는 상태이고, 힙은 new 생성시 후에 만들어지기 때문이다.

 

메모리 구조

메소드 에어리어(method area)클래스 영역, static 영역, 상수 영역(final, contant) .. 으로 구성됨.}

 

객체의 소멸 ==> 자바의 가비지컬렉션(GC)가 더 이상 필요하지 않는 객체를 수집하여 메모리에서 제거시킴.

ex) Student s = new Student("홍길동");   ---> 아래 이순신으로 새로운 정보를 입혔으므로 GC가 삭제시킴.

      Student s = new Strudent("이순신");

 

기화 블럭

기본적으로 실행문은 블럭안에 있어야 한다.

ex) system.out.println();  == > 메서드 안에서나 생성자 안. 클래스 중괄호도 블럭이라고 생각할 수 있지만 안된다. 무조건 생성자 이상의 블록에서 실행 가능.

인스턴스 블럭은 호출하지 않으면 실행되지 않는다.

스태틱 블럭은 호출하지 않아도 실행된다.

상속(중요!)

JAVA 의 클래스 간 관계

{

has a 관계  ==>  멤버

is a 관계 ==  > 상속 

}

상속은 extends 키워드를 사용하여 부모클래스의 정보를 자식 클래스에서 사용하게 된다.

UML에서 상속 관계는 실선 화살표 심볼이다.

문법:

public class 자식클래스명 extends 부모클래스명{

}

부모 클래스에도 또 부모클래스가 있는데, Object 클래스(최상위 클래스)가 있다. 인스턴스 object와 다름.(대, 소문자)

=> A클래스가 B 클래스의 부모 클래스면, 실제로는 은연으로 extends Object 클래스가 삽입된다.

 ex) public class A (extends Object) {}; <- 소괄호 안은 은연으로 생략돼있음.

상속은 단일상속만 지원한다. 단, 상속 불가한 경우가 있다.

1. 부모 생성자 -> 자식은 부모 생성자를 상속 받을 수 없다.

2. private -> private는 애초에 자기 자신(멤버)만 쓸 수 있기 때문에 상속 관계에서도 자식클래스에서 사용할 수 없다.

 

+++상속 내용 추가

1. 클래스들간의 관계중 'is a' 관계이다.

2. 상속이 적용되면 부모의 요소 중 생성자 및 private으로 지정된 요소를 제외하고 나머지는 자식이 그냥 사용 가능하다.

3. 명시적으로 상속받지 않은 클래스는 자동으로 Object 클래스를 상속 받는다.(Object = 최상위 클래스)

    ====> Object 클래스는 모든 클래스의 부모이다.

4. 단일 상속만 지원

5. UML 표기법은 실선 화살표, 코드로는 extends 키워드를 이용한다. 부모 A < ㅡ 자식 B

6. 타입으로 따지면 부모가 더 큰 타입, 자식은 작은 타입

7. 항상 new 한 자식 클래스보다 부모의 기본 생성자를 먼저 생성한다.(자식 클래스가 부모 클래스의 생성자를 사용할 순 없지만, new 자식 클래스로 힙에 생성을 할 경우 부모 기본 생성자가 자동으로 생성되어 안에 내용을 실행한다.

-> 부모 클래스를 생성하는 코드가 자동으로 삽입됨. 그렇다고 new 부모클래스()는 아니다.. new 부모클래스()의 경우는 

    다른 클래스에서 사용하는 것이고, 자식에서는 super() 형식으로 부모 생성자를 호출하기 위해서 자동으로 삽입된다.

    super(); ==> 부모의 기본 생성자 호출 코드

*** 모든 클래스의 자식생성자 첫 라인에서 부모 생성자를 호출하는 코드가 자동으로 삽입된다. ==> super(); ***

    만약 super()를 명시적으로 작성한다면 반드시 첫 라인에서 작성할것. -> 이렇게 안하면 에러 난다.

   

*** 어떠한 클래스에서든 자기 자신(멤버)쪽에서 초기화 하는 것이 객체지향 관점에서 보기 좋다.***

-> 부모 클래스의 매개변수를 자식클래스에서 초기화를 해도 문법상 문제 없으나, 객체지향적으로  옳지 않다

 

상속을 쓰는 이유는 중복 코드의 발생을 최소화하기 위해서다.

1) 상속 x ==> 중복 코드 발생 높아짐

2) 상속 o ==> 중복 코드를 최소, 재사용성이 높아진다. => 부모 클래스에서 한 번만 만들어주면 되기 때문에