Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 스프링 고급 - 스프링 aop
- 자바의 정석 기초편 ch11
- 자바 기본편 - 다형성
- 자바 중급1편 - 날짜와 시간
- 자바의 정석 기초편 ch9
- 2024 정보처리기사 수제비 실기
- 스프링 db1 - 스프링과 문제 해결
- 스프링 db2 - 데이터 접근 기술
- 스프링 mvc1 - 서블릿
- 자바의 정석 기초편 ch4
- jpa 활용2 - api 개발 고급
- 게시글 목록 api
- 스프링 mvc2 - 검증
- 스프링 mvc1 - 스프링 mvc
- 자바의 정석 기초편 ch6
- 코드로 시작하는 자바 첫걸음
- 2024 정보처리기사 시나공 필기
- 자바의 정석 기초편 ch5
- 자바의 정석 기초편 ch8
- 자바의 정석 기초편 ch14
- @Aspect
- 스프링 mvc2 - 로그인 처리
- 자바의 정석 기초편 ch7
- 자바의 정석 기초편 ch2
- 스프링 mvc2 - 타임리프
- 스프링 입문(무료)
- 자바의 정석 기초편 ch13
- 자바의 정석 기초편 ch12
- jpa - 객체지향 쿼리 언어
- 자바의 정석 기초편 ch1
Archives
- Today
- Total
나구리의 개발공부기록
자바의 정석 기초편 ch7 - 10 ~ 16[참조변수 super, 생성자super(), 패키지, 클래스 패스, import문, static import문] 본문
유튜브 공부/JAVA의 정석 기초편(유튜브)
자바의 정석 기초편 ch7 - 10 ~ 16[참조변수 super, 생성자super(), 패키지, 클래스 패스, import문, static import문]
소소한나구리 2023. 11. 23. 18:061) 참조변수 super
- 객체 자신을 가리키는 참조변수이며 부모클래스(상위 클래스)의 멤버에 접근할 때 사용함
- 부모클래스의 멤버(super)와 자기자신의 멤버(this)를 구분할 때 사용함
- this가 자기 자신의 인스턴스 멤버를 가리킨다면 super는 부모 클래스의 인스턴스를 가리킨다고 보면 됨
- 인스턴스 메서드나 생성자에서만 사용할 수 있으며 스태틱 메서드에는 사용할 수 없음
class ex7_2 {
public static void main(String args[])
Child c = new Child();
c.method();
}
}
class Parent { int x = 10; } // super.x
class Child extends Parent {
int x = 20; // this.x
void method() {
System.out.println("x=" +x); // 가까운 참조변수 x 값 출력
System.out.println("this.x=" +this.x); // this.x 값 출력
System.out.println("super.x=" +super.x); // super.x 값 출력
}
}
출력값
x=20
this.x=20
super.x=10
(1) 예제1
- 자손 클래스에 선언된 멤버가 없는 경우 this, super 모두 같은값을 가리킴
- 상속받은 Child 클래스에 x변수가 없으므로 this를 사용해도 상속받은 부모클래스의 멤버를 가리킴
class ex7_2 {
public static void main(String args[])
Child c = new Child();
c.method();
}
}
class Parent { int x = 10; } // super.x , this.x 둘다 가능
class Child extends Parent {
void method() {
System.out.println("x=" +x); // 가까운 참조변수 x 값 출력 -> 상속클래스의 x 값을 가르킴
System.out.println("this.x=" +this.x); // this.x 값 출력
System.out.println("shper.x=" +super.x); // super.x 값 출력
}
}
출력값
x=10
this.x=10
super.x=10
2) super()
- 조상의 생성자를 호출할 때 사용
- 상속은 조상의 생성자와 초기화블럭이 상속 되지 않기 때문에 조상의 생성자를 호출할 경우 super()로 호출해야 함
- 자손의 클래스에서 조상의 멤버를 직접 초기화 하는 방식보다 super()를 호출해서 초기화 하는 방식을 권장함
(1) 예제
- Point3D클래스에서 직접 조상의 멤버를 Point3D 생성자로 초기화려고하면 에러가 발생함
- 정상적으로 조상의 멤버를 초기화 하려면 조상클래스에 생성자를 정의해두고 자손 클래스에서 super()로 조상 클래스의 생성자를 호출하여 멤버를 초기화 해야함
class Point {
int x, y;
Point(int x, int y) {
this.x = x;
this.y = y;
}
}
// 조상의 멤버를 초기화 할 때 아래처럼 하면 에러 발생
class Point3D extends Point {
int z;
Point3D(int x, int y, int z) {
this.x = x; // 에러 발생, 이유는 아래에서 설명
this.y = y; // 위와 동일
this.z = z;
}
}
// 정상적인 조상 멤버 초기화 방법 -> super() 조상의 멤버를 호출
class Point3D extends Point {
int z;
Point3D(int x, int y, int z) {
super(x,y); // 조상의 생성자 Point(int x, int y)를 호출
this.z = z;
}
}
(2) 추가조건(중요)
- 생성자의 첫 줄에 반드시 생성자를 호출하지 않으면 컴파일러가 생성자의 첫 줄에 super();를 자동으로 삽입함
- 조상 클래스에 기본생성자가 없이 매개변수가 있는 생성자만 만들고 자손 클래스에서 생성자를 만들면 마찬가지로 컴파일러가 super()를 자동으로 호출함
- 그러나 조상클래스에 기본생성자를 만들어 주지 않았으므로(매개변수가 있는 생성자를 직접 만들면 컴파일러가 자동으로 기본 생성자를 생성하지 않음) 자손 클래스의 생성자에서 직접 조상 클래스의 멤버에 값을 초기화하려고하면 에러가 발생함
- 이것이 자손 클래스에서 조상 클래스 멤버를 초기화할 때 직접 초기화 하지말고 super()를 사용하라는 이유이며, (1)번 예제의 컴파일 에러가 발생한 이유임
(3) 문제해결
- 1. 조상 클래스에 기본 생성자를 생성하여 컴파일 에러가 발생하는 문제를 해결하면 직접 조상의 멤버에 값을 초기화 할 수 있음
- 2. 자손 클래스에서 super(x, y);로 조상 클래스의 매개변수가 있는 생성자를 호출하여 초기화하면 조상 클래스의 기본 생성자가 없어도 동작함
- 최종적으로 super()를 사용하여 조상 클래스의 멤버에 값을 초기화 하더라도 기본적으로 매개변수가 있는 생성자를 생성할 경우 기본 생성자를 만드는 습관을 들이는 것을 권장함
class TestPoint4 {
int x;
int y;
// TestPoint4() {} // 문제해결: 1. 조상 클래스에 기본 생성자 생성
TestPoint4(int x, int y) {
// super(); // 생략 됨, 컴파일시 오브젝트 클래스의 기본생성자를 자동으로 호출 -> OK
this.x = x;
this.y = y;
}
String getLocation() { // 메서드
return"x:" + x + ", y:" + y;
}
}
class TestPoint3D extends TestPoint4 { // Point클래스 상속
int z;
TestPoint3D(int x, int y, int z) {
// super(); // 생략 됨, 컴파일시 조상의 기본생성자를 자동으로 호출함 -> 에러발생
// this.x = x; 조상 멤버는 직접 초기화 불가능
// this.y = y;
super(x,y); // 문제해결: 2. 생성자 super(x,y)로 조상의 매개변수 있는 생성자를 호출하여 초기화
this.z = z;
}
String getLocation() { // 메서드 오버라이딩
return"x:" + x + ", y:" + y +", z:" +z;
}
}
public class superTest {
public static void main(String[] args) {
TestPoint3D p = new TestPoint3D(1,2,3);
System.out.println(p.getLocation());
}
}
해결방법
1. TestPoint4 클래스에 기본생성자 입력 -> 참조 코드 확인
2. super()사용 (조상의 생성자 호출) -> 참조 코드 확인
3)패키지(package)
- 서로 관련된 클래스의 묶는 단위
- Java8 기준으로 약 4000개 내장 클래스가 있음
- 컴파일하면 클래스는 파일이름.class로, 패키지는 폴더로, 하위 패키지는 하위 폴더로 생성됨
- 클래스의 풀네임은 패키지를 포함하여 작성됨
- ex) String 클래스의 풀네임 = java.lang.String
(1) 패키지 선언
- 패키지는 소스파일의 첫 번째 문장으로 단 한번 선언
- 같은 소스 파일의 클래스들은 모두 같은 패키지에 속하게 됨
- 패키지 선언이 없으면 이름없는 패키지(unnamed, 이클립스,인텔리제이에서는 default package)에 속하게 됨
- 선언방법
- Package 패키지 경로 (com.codechobo.book)
(2) 클래스 패스
- JVM이나 Java 컴파일러가 사용할 클래스 파일의 위치를 알려주는 경로
- 터미널, cmd 창에서 class파일을 찾아 실행 하고자 할 때 경로를 미리 지정 하지않고 실행할때도 사용함
- 환경변수(OS) classpath로 관리하면 windows의 경우 경로간의 구분자는 세미콜론(;) 를 사용하고 Unix기반 시스템은 콜론(:)을사용하며 경로를 여러개 설정할 수도 있음
- 맥에서의 클래스 패스 설정은 별도의 검색이 필요
- 윈도우에서는 제어판 -> 환경변수 -> 시스템 변수를 이용
4) import문
- 클래스를 사용할 때 패키지이름을 생략 할 수 있음
- 컴파일러에게 클래스가 속한 패키지를 알려주는 구문
- 이클립스 단축키: 커맨드 + 쉬프트 + O , 인텔리제이 단축키 : 옵션 + 엔터 / 맥 기준 단축키 설명
- import문을 작성하지 않으면 객체를 생성하고자 할때 경로를 전부 작성해줘야함
// import문을 작성 안하면 객체 생성 시 클래스 앞에 패키지 이름을 써 줘야 함,
class ImportTest [
java.util.Date today = new java.util.Date();
}
// import문을 작성 하면 아래처럼 패키지 이름을 생략 가능
import java.util.Date;
class ImportTest {
Date today = new Date();
}
(1) java.lang패키지(기본패키지)의 클래스는 import하지 않고도 사용할 수 있음
- String, Object, System, Thread... 등등
(2) import문 작성 방법
- import java.패키지명.클래스명;
- import java.패키지명.*; -> 모든 클래스를 사용
- *으로 할경우 코드의 명확성이 떨어질 수 있음
- 패키지 문과 클래스 선언 사이에 선언
- import문은 컴파일 시에 처리되므로 프로그램의 성능에 거의 영향이 없으므로 사용하고자 하는 클래스는 가급적 선언해서 사용하는 것을 권장함
import java.util.*; // utill 패키지의 모든클래스
import java.text.*; // text 패키지의 모든클래스
- 서로 다른 패키지에 속했지만 이름이 같은 클래스를 import하는 것도 가능
- 클래스 앞에 패키지 명을 붙여주면 코드가 명확해짐
// 패키지는 다른데 클래스가 동일 할 경우
import java.sql.Date;
import java.util.Date;
// 두개의 Date클래스를 모두사용 가능하지만 클래스 앞에 패키지 이름을 직접 적어주면 구분이 명확하게 됨
public class ImportTest {
public static void main(String[] args) {
java.util.Date today = new java.util.Date();
}
}
(3) static import문
- static멤버를 사용할 때 클래스 이름을 생략할 수 있게 해줌
- 클래스나 static멤버의 이름이 길 경우 코드가 길어지는데 static import문을 사용하면 코드의 길이를 줄일 수 있음
- 단, 코드의 명확성이 줄어들 수 있음(어떤 클래스의 메서드를 쓰는지..)
// Integer클래스의 모든 static메서드를 실행할 때 클래스명을 생략 가능
import static java.lang.Integer.*;
// Math클래스의 random메서드를 호출할 때 클래스명을 생략할 수 있음
import static java.lang.Math.random;
// 출력메서드를 사용할 때 System을 생략할 수 있음
import static java.lang.System.out;
out.println(random()); // System.out.println(Math.random());의 코드 길이가 줄어듦
** 출처 : 남궁성의 정석코딩_자바의정석
'유튜브 공부 > JAVA의 정석 기초편(유튜브)' 카테고리의 다른 글
자바의 정석 기초편 ch7 - 22 ~ 23 [캡슐화, 다형성] (1) | 2023.11.24 |
---|---|
자바의 정석 기초편 ch7 - 17 ~ 21 [제어자, static, final, abstract, 접근제어자] (0) | 2023.11.24 |
자바의 정석 기초편 ch7 - 5 ~ 9[단일상속, Object클래스,오버라이딩, 오버로딩 vs 오버라이딩] (3) | 2023.11.23 |
자바의 정석 기초편 ch7 - 1 ~ 4[상속, 클래스간의 관계, 상속과포함] (6) | 2023.11.22 |
자바의 정석 기초편 ch6 - 32 ~ 41[생성자, 기본 생성자,생성자this(), 참조변수 this, 변수의초기화, 멤버변수의 초기화] (1) | 2023.11.20 |