728x90
이 글은 https://youtu.be/CXuA31XcBZ0 를 통해 개념 정리 후 복습용으로 정리한 글입니다.
문제시 바로 삭제하겠습니다.
super
- 객체 자신을 가리키는 참조변수. 인스턴스 메서드(생성자) 내에만 존재 -> static 메서드 내에 사용 불가
- 조상의 멤버와 자신의 멤버를 구별할 때 사용
Class ex{
public static void main(String args[]) {
Child c = new Child();
c.method(30);
}
}
class Parent { int x = 10; } // super.x
class Child extend Parent {
int x = 20; // this.x
void method(int x) {
System.out.println("x = " + x);
System.out.println("this.x = " + this.x);
System.out.println("super.x = " + super.x);
}
}
//결과
x = 30
this.x = 20
super
super() - 조상의 생성자 != super
- 조상의 생성자를 호출할 때 사용
- 조상의 멤버는 조상의 생서자를 호출해서 초기화
- 생성자의 첫 줄에 반드시 생성자를 호출해야 한다. 그렇지 않으면 컴파일러가 생성자의 첫 줄에 super();를 삽입한다.
class Point extends Object {
int x;
int y;
Point() {
this(0,0);
}
Point(int x, int y) {
super(); // Object();
this.x = x;
this.y = y;
}
}
예시
에러 나는 이유는 Point3D에서 super(); -> Point()를 호출하게 된다.
Point 클래스에는 기본 생성자가 없으므로 에러가 나게 된다.
클래스를 작성할 때는 기본 생성자 작성은 필수다
맞는 코드
Point3D(int x, int y, int z) {
super(x,y);
this.z = z;
}
패키지 - 폴더
- 서로 관련된 클래스의 묶음
- 클래스의 실제 이름(full name)은 패키지를 포함 (java.lang.String)
패키지의 선언
- 패키지는 소스파일의 첫 번째 문장으로 단 한번 선언
- 같은 소스 파일의 클래스들은 모두 같은 패키지에 속하게 된다.
- 패키지 선언이 없으면 이름 없는(unnamed) 패키지에 속하게 된다.
클래스 패스(classpath)
- 클래스 파일의 위치를 알려주는 경로(path)
- 환경변수 classpath로 관리하며, 경로 간의 구분자는
;
를 사용 - classpath에 패키지의 루트를 등록해줘야 함.
import문
- 클래스를 사용할 때 패키지이름을 생략할 수 있다.
- 컴파일러에게 클래스가 속한 패키지를 알려준다.
- java.lang패키지의 클래스는 import 하지 않고도 사용할 수 있다. ex) println, String...
inport java.util.Date;
class ImportTest {
Date today = new Date();
}
inport문의 선언
- import문을 선언하는 방법은 다음과 같다.
inport 패키지명.클래스명;
또는
inport 패키지명.*; -> 모든 클래스
- import문은 컴파일 시에 처리되므로 프로그램의 성능에 영향 없다.
- 다음의 두 코드는 서로 의미가 다르다
inport java.util.*;
inport java.text.*;
// 아래 코드와 의미가 다름
inport java.*; -> java 패키지의 모든 클래스(패키지는 포함안됨)
- 이름이 같은 클래스가 속한 두 패키지를 import 할 때는 클래스 앞에 패키지명을 붙여줘야 한다.
static import문
- static멤버를 사용할 때 클래스 이름을 생략할 수 있게 해 준다.
inport static java.lang.Math.random;
inport static java.lang.System.out; // System.out을 out만으로 참조 가능
System.out.println(Math.random()); -> out.println(random());
접근 제어자(access modifier)
private : 같은 클래스 내에서만 접근 가능
(default) : 같은 패키지 내에서만 접근이 가능
protected : 캍은 패키지 내에서, 그리고 다른 패키지의 자손 클래스에서 접근 가능
public : 접근 제한이 없다
접근 제어자 | 같은 클래스의 멤버 | 같은 패키지의 멤버 | 자식 클래스의 멤버 | 그 외의 영역 |
---|---|---|---|---|
public | O | O | O | O |
protected | O | O | O | X |
default | O | O | X | X |
private | O | X | X | X |
접근 제어자를 사용하는 이유 -> 캡슐화
- 외부로부터 데이터를 보호하기 위해서 -> 캡슐화
- 외부에는 불필요한, 내부적으로만 사용되는 부분을 감추기 위해
제어자(modifier)
- 클래스와 클래스의 멤버(멤버 변수, 메서드)에 부가적인 의미 부여
- 접근 제어자 public, protected, (default), private
- 그 외 static, final, abstract, native, transient, synchronized, volatile, strictfp
- 하나의 대상에 여러 제어자를 같이 사용가능(접근 제어자는 하나만)
-
public class ModifierEx { public static final int a; public static void main(){}; }
static - 클래스의 공통적인
제어자 | 대상 | 의미 |
---|---|---|
static | 멤버변수 | - 모든 인스턴스에 공통적으로 사용되는 클래스 변수가 된다 - 클래스 변수는 인스턴스를 생성하지 않고도 사용 가능하다. - 클래스가 메모리에 로드될 때 생성된다. |
static | 메서드 | - 인스턴스를 생성하지 않고도 호출이 가능한 static 메서드가 된다. - static메서드 내에서는 인스턴스멤버들을 직접 사용할 수 없다. |
class StaticEx {
static int a = 1; // 클래스 변수(static변수)
static int b = 2; // 클래스 변수(static변수)
static { // 클래스 초기화 블럭
// static변수의 복잡한 초기화 수향
}
static int max(int a, int b) { // 클래스 메서드(static메서드)
return a > b ? a : b; // iv, instance method 사용 불가
}
}
final - 마지막의, 변경될 수 없는
제어자 | 대상 | 의미 |
---|---|---|
final | 클래스 | 변경될 수 없는 클래스, 확장될 수 없는 클래스가 된다 그래서 final로 지정된 클래스는 다른 클래스의 조상이 될 수 없다. |
final | 메서드 | 변경될수 없는 메서드, final로 지정된 메서드는 오버라이딩을 통해 재정의 될 수 없다. |
final | 멤버변수 / 지역변수 |
변수 앖에 final이 붙으면, 값을 변경할 수 없는 상수가 된다. |
abstract - 추상의, 미완성의
제어자 | 대상 | 의미 |
---|---|---|
abstract | 클래스 | 클래스 내에 추상 메서드가 선언되어 있음을 의미한다. |
abstract | 메서드 | 선언부만 작성하고 구현부는 작성하지 않은 추상 메서드임을 알린다. |
//미완성 클래스 = 미완성 설계도
abstract class AbstractEx{ // 추상 클래스(추상 메서드를 포함한 클래스)
abstract void move(); // 추상 메서드(구현부가 없는 메서드)
}
AbstractEx a = new AbstractEx(); // 에러. 추상 클래스의 인스턴스 생성 불가
추상 클래스를 상속받아서 완전한 클래스를 만든 후에 인스턴스 생성 가능
다형성(polymorphism)
- 여러 가지 형태를 가질 수 있는 능력
- 조상 타입 참조변수로 자손 타입 객체를 다루는 것
- 객체와 참조변수의 타입이 일치할 때와 일피하지 않을 때의 차이?
- 자손 타입의 참조변수로 조상 타입의 객체를 가리킬 수 없다.
-
// Tv parent, SmartTv child Tv t = new SmartTv(); // ok SmartTv s = new Tv(); // 에러. 허용 안 됨
참조변수의 형변환
- 사용할 수 있는 멤버의 개수를 조절하는 것
- 멤버의 개수가 많은 쪽에서 작은 쪽으로 변환은 OK, 반대는 NullPointException 발생 위험 있음
instanceof 연산자
- 참조변수의 형변환 가능여부 확인에 사용. 가능하면 true 반환
- 현변환 전에 반드시 instanceof 연산자로 확인해야 함
void doWork(Car c) {
if (c instanceof FireEngine) {
FireEngine fe = (FireEngine) c;
fe.water();
}
...
}
참조변수의 형변환은 왜 하나요?
참조변수를 변경함으로써 사용할 수 있는 멤버의 개수를 조절하기 위해서 객체는 그대로, 값도 그대로 -> 멤버의 개수만 조절
instanceof 연산자는 언제 사용하나요?
참조변수를 형변환하기 전에 형변환 가능여부를 확인할 때
매개변수의 다형성
장점
1. 다형적 매개변수
2. 여러 종류의 객체를 배열로 다루기
다형적 매개변수
- 참조형 매개변수는 메세드 호출 시, 자신과 같은 타입 또는 자손타입의 인스턴스를 넘겨줄 수 있다.
class Buyer {
int money = 1000;
int bonusPoint = 0;
void buy (Product p) {
money -= p.price;
bonusPoint += p.bonusPoint;
}
}
// Product가 아니면
// class Tv extends Product {}
void buy (Tv tv)) {
money -= tv.price;
bonusPoint += tv.bonusPoint;
}
// 이런식으로 하나하나 다 만들어야한다.
// 이게 매개변수의 다형성의 1번 장점이다.
여러 종류의 객체를 배열로 다루기
- 조상타입의 배열에 자손들의 객체를 담을 수 있다.
Product p[] = new Product[3];
p[0] = new Tv();
p[1] = new Computer();
p[2] = new Audio();
- 대표적인 예로 장바구니
class Buyer {
int money = 1000;
int bonusPoint = 0;
Product[] cart = new Product[10]; //구입한 물건을 담을 배열
int i = 0; //장바구니 인덱스
void buy (Product p) {
money -= p.price;
bonusPoint += p.bonusPoint;
cart[i++] = p; //카트에 저장하고 i는 1증가
}
}
728x90
'Java' 카테고리의 다른 글
[Java] 내부 클래스(inner class) (0) | 2022.12.26 |
---|---|
[Java] 추상 클래스(abstract class), 추상 메서드(abstract method) (2) | 2022.12.24 |
[Java] Optional<T> (0) | 2022.12.08 |
[Java] 선언 위치에 따른 변수의 종류 (0) | 2022.12.05 |
[Java] Stream, 스트림 생성 (0) | 2022.11.30 |
댓글