
(접근 제어자) class 클래스 이름{
멤버 변수;
메서드;
}
객체를 정의해 놓은 것
객체를 생성하는데 사용, 객체를 만들기 위한 설계도
인스턴스: 특정 클래스로부터 만들어진 객체(ex: TV인스턴스)
클래스 선언
- 객체 구상 후 클래스 이름을 결정
용도
클래스 멤버
public class ClassName {
// 필드 = 객체의 데이터가 저장되는 곳
int fieldname;
// 생성자 = 객체 생성 시 초기화 역할 담당
ClassName() { ... }
// 메소드 = 객체의 동작에 해당하는 실행 블록
void methodName() {...}
}
클래스(설계도) → 인스턴스화(제품 생성) → 인스턴스(객체, 제품)
클래스 == 데이터 + 함수
사용자 정의 타입 - 원하는 타입(클래스)을 직접 만들 수 있다.
public class Hello2 {
// 소스파일의 이름은 public class이름과 일치
// 하나의 소스파일에는 하나의 클래스만 작성하는 것이 바람직
// 하나의 소스파일에는 하나의 public class만 허용
public static void main(String[] args) {
System.out.println("Hello");
}
}
Tv t;
t = new Tv();
t.channel = 7;
t.channelDown();
System.out.println("현재 채널은 " + t.channel + " 입니다.");
객체 배열 == 참조변수 배열
Tv tv1, tv2, tv3; → Tv[] tvArr = new Tv[3];
Tv[] tvArr = new Tv[3]; // 길이가 3인 Tv타입의 참조변수 배열
// 객체를 생성해서 배열의 각 요소에 저장
tvArr[0] = new Tv();
tvArr[1] = new Tv();
tvArr[2] = new Tv();
Tv[] tvArr = { new Tv(), new Tv(), new Tv() };
필드 선언
[public] class() { }
클래스(매개변수선언, ...) {
// 객체의 초기화 코드
}
public class Car {
// 생성자
Car(String model, String color, int maxSpeed) {...}
}
Car myCar = new Car("그랜저", "검정", 300);
public class Korean {
// 필드
String nation = "대한민국";
String name;
String ssn;
// 생성자
public Korean(String n, String s) {
name = n;
ssn = s;
}
}
매개 변수 이름은 필드 이름과 유사하거나 동일한 것 사용 권장
필드와 매개 변수 이름 완전히 동일할 경우 this.필드로 표현
this.필드: 객체 자신의 참조. this라는 참조 변수로 필드를 사용하는 것과 동일함
this() 코드
클래스( [매개변수, ...] ) {
this(매개변수, ..., 값, ...); // 클래스의 다른 생성자 호출
실행문;
}
class Card {
String kind; // 무늬
int number; // 숫자
// 개별 iv
static int width = 100; // 폭
static int height = 250; // 높이
// 공통 cv
}
Card c = new Card(); // 객체 생성
c.kind = "HEART"; // 객체 사용
c.number = 5; // iv
Card.width = 200;
Card.height = 300; // cv - 객체 생성없이 사용 가능
메소드 선언부
리턴 타입: 메소드가 리턴하는 결과의 타입 표시
메소드 이름: 메소드의 기능 드러나도록 식별자 규칙에 맞게 이름 지음
매개 변수 선언: 메소드 실행할 때 필요한 데이터 받기 위한 변수 선언
메소드 실행 블록: 실행할 코드 작성
매개 변수의 개수를 모를 경우
매개 변수를 배열 타입으로 선언
int sum1(int[] values) { }
int[] values = {1, 2, 3};
int result = sum1(values);
int result = sum1(new int[] {1, 2, 3, 4, 5});
배열 생성하지 않고 값의 목록만 넘겨주는 방식
int sum2(int ... values) { }
int result = sum2(1, 2, 3);
int result = sum2(1, 2, 3, 4, 5);
int[] values = {1, 2, 3};
int result=sum2(values);
int result=sum2(new int[] {1, 2, 3, 4, 5});
리턴(return)문
리턴문이란? 실행 중인 메소드를 종료하고 호출한 곳으로 되돌아가게 함.
- 리턴값이 있는 메소드
- 메소드 선언에 리턴 타입 있는 메소드는 리턴문 사용하여 리턴값 지정
return 리턴값;
- return문의 리턴값은 리턴타입이거나 리턴타입으로 변환될 수 있어야 함.
- 리턴값이 없는 메소드: void
- void 선언된 메소드에서 return문 사용하여 메소드 실행 강제
`return;`
반환 타입이 void일 경우엔 생략 가능하고 컴파일러가 자동 추가된다.
반환 타입이 void가 아닐 경우엔 반드시 return문이 필요하다.
정의된 함수를 호출하는 것.
함수가 호출될 때, 메모리 공간 안에서는 함수를 위한 별도의 임시 공간이 생성된다.
함수에 정의한 매개변수의 형태에 따라 두가지로 결정된다.
Call-by-value
- 값에 의한 호출
- int, short, long, float, double, char, boolean, byte
Call-by-reference
기본 자료형을 입력매개변수로 전달하면 전달받은 메서드는 값을 복사해 사용한다.
참조 자료형을 입력매개변수로 넘겼을 때도 입력매개변수로 넘겨진 변수의 스택 메모리값이 복사돼 사용되는 것은 동일하지만, 참조 자료형은 스택 메모리에 객체의 참좃값(위칫값)을 저장하고 있으므로 실제 객체가 아닌 객체의 참좃값이 전달돼 복사된다.
메소드 내부에서 메소드 자신을 다시 호출하는 것.
재귀호출을 하는 메소드를 재귀 메소드라고 함.
대표적인 재귀호출의 예는 팩토리얼(factorial)을 구하는 것이다.
팩토리얼: 한 숫자가 1이 될 때까지 1씩 감소시켜가면서 계속 곱해나가는 것. ex) 5! = 54321 = 120
f(n) = n * f(n-1), 단 f(1) = 1
class FactorialTest {
public static void main(String args[]) {
int result = factorial(4);
System.out.println(result);
}
static int factorial(int n) {
int result = 0;
if ( n == 1 )
result = 1;
else
result = n * factorial(n-1); // 다시 메소드 자신 호출
return result;
}
}
메소드 시그너처(method signature): 메소드명, 입력매개변수의 자료형. 메소드를 구분하는 기준 역할.
오버로딩: 한 클래스 내에 같은 이름의 메서드를 여러 개 정의하는 것.
매개값을 다양하게 받아 처리할 수 있도록 하기 위함
외부에서 제공되는 다양한 데이터 사용하여 객체 초기화하려면 생성자 역시 다양화해야 함.
리턴 타입 메서드명 (자료형 변수명, 자료형 변수명, ...) {
}
// 메서드명, 자료형, 자료형 -> 메소드 시그너처
int sum (int a, int b) {
return 3;
} // sum, int, int -> 메소드 시그너처
인스턴스 멤버: 객체를 생성한 후 사용할 수 있는 필드와 메소드
정적(static) 멤버
클래스에 고정된 멤버로서 객체를 생성하지 않고 사용할 수 있는 필드와 메소드
객체와 상관없는 멤버, 클래스 코드(메소드 영역)에 위치
정적 필드 및 상수: 객체없이 클래스만으로도 사용 가능한 필드
정적 메소드: 객체가 없이 클래스만으로도 호출 가능한 메소드
static void Method3() {
ClassName obj = new ClassName();
obj.field1 = 10;
obj.method1();
}
정적 멤버 사용: 클래스 이름과 함께 도트 연산자로 접근
클래스.필드;
클래스.메소드(매개값, ...);
인스턴스 멤버와 정적 멤버 선택 기준
객체 내에서 인스턴스 멤버에 접근하기 위해 사용
생성자와 메소드의 매개 변수 이름이 필드와 동일할 경우, 필드임을 지정하기 위해 주로 사용
전체 프로그램에서 단 하나의 객체만 만들도록 보장하는 코딩 기법
싱글톤 작성 방법
private 접근 제한자 사용getInstance() 선언초기값이 저장되면 최종값이 되어 프로그램 실행 도중 실행 불가
final 필드의 초기값 주는 방법
인스턴트 final 필드
final 타입 필드 [= 초기값];
final String ssn; // 생성자에서 초기화
정적 final 필드 (모두 대문자로 작성)
static final 타입 상수 = 초기값;
static final double PI = 3.14159;
패키지의 물리적인 형태는 파일 시스템의 폴더
패키지는 클래스의 일부분으로, 클래스를 유일하게 만들어주는 식별자 역할
클래스 이름이 동일하더라도 패키지가 다르면 다른 클래스로 인식
클래스의 전체 이름은 패키지+클래스 사용해서 다음과 같이 표현한다.
상위패키지.하위패키지.클래스
com.mycompany.A
com.yourcompany.B
패키지 선언
클래스 작성 시 해당 클래스가 어떤 패키지에 속할 것인지를 선언
패키지 이름 규칙
package 상위패키지.하위패키지;
public class Classname {...}
package com.mycompany;
public class Car {...}
사용하고자 하는 클래스 또는 인터페이스가 다른 패키지에 소속된 경우
해당 패키지 클래스 또는 인터페이스를 가져와 사용할 것임을 컴파일러에 통지
import 상위패키지.하위패키지.클래스이름;
import 상위패키지.하위패키지.*; // 사용하고자 하는 클래스가 여러개라면 *로 표현
패키지 선언과 클래스 선언 사이에 작성
package com.mycompany;
import com.hankook.Tire;
public class Car {
Tire tire = new Tire();
}
하위 패키지는 별도로 import 해야 함
import com.hankook.*;
import com.kankook.project.*;
다른 패키지에 동일한 이름의 클래스가 있을 경우: import와 상관없이 클래스 전체 이름을 기술
클래스와 인터페이스 및 이들이 가진 멤버의 접근 제한
같은 패키지 내에서만 사용할 것인지 다른 패키지 내에서도 사용할 수 있도록 할 것인지 결정
필드 값을 외부로 리턴하는 메소드: Getter (getXXX(), isXXX())
외부에서 값을 받아 필드값을 변경하는 메소드: Setter (setXXX())
이미 개발된 클래스를 재사용하여 새로운 클래스를 만들기에 중복되는 코드를 줄임
부모 클래스의 한번의 수정으로 모든 자식 클래스까지 수정되는 효과가 있어서 유지보수 시간이 줄어듦.
public class A {
int field1;
void method1() { ... }
}
public class B extends A { // A를 상속
String field2;
void method2() { ... }
}
class 자식클래스 extends 부모클래스 {
//필드
//생성자
//메소드
}
class SportsCar extends Car {
}
부모 생성자 호출
자식 객체 생성할 때 부모 객체가 먼저 생성되고 그 다음 자식 객체가 생성됨
DmbCellPhone dmbCellPhone = new DmbCellPhone();
자식 생성자의 맨 첫 줄에서 부모 생성자가 호출됨
public DmbCellPhone() {
super();
}
public CellPhone() {
}
명시적으로 부모 생성자 호출하려는 경우
자식클래스( 매개변수선언, ... ) {
super( 매개값, ... );
...
}
부모 클래스의 메소드가 자식 클래스에서 사용하기에 부적합할 경우 자식 클래스에서 수정하여 사용
자식 클래스 내부에서 재정의된 부모 클래스 메소드를 호출해야 하는 경우
명시적으로 super 키워드 붙여 부모 메소드 호출
super.부모메소드();
여러 가지 형태를 가질 수 있는 능력
메소드 재정의와 타입 변환으로 구현
자동 타입 변환
Cat cat = new Cat();
Animal animal = cat; - 바로 위 부모가 아니더라도 상속 계층에서 상위 타입인 경우 자동 타입 변환 일어날 수 있음. 필드의 다형성
매개변수의 다형성
강제 타입 변환(casting)
instanceof 연산자
boolean result = 좌항(객체) instanceof 우항(타입)공통적인 특성(필드, 메소드)을 추출하여 선언한 것추상 클래스의 용도
추상 클래스 선언
abstract 키워드를 붙여야 한다.puclic abstract class 클래스 {
// 필드
// 생성자
// 메소드
}
추상 메소드
[public | protected] abstract 리턴타입 메소드이름(매개변수, ...);
인터페이스 선언
interface 인터페이스이름 {
//상수
타입 상수이름 = 값;
//추상 메소드
타입 메소드이름(매개변수, ...);
}
상수 필드(constant field) 선언
public static final 타입 상수이름 = 값;
public interface RemoteControl {
public int MAX_VOLUME = 10;
public int MIN_VOLUME = 0;
추상 메소드 선언
구현(implement) 클래스
implements 키워드를 추가하고 인터페이스 이름 명시public class 구현클래스이름 implements 인터페이스이름 {
// 인터페이스에 선언된 추상 메소드의 실체 메소드 선언
}
인터페이스와 구현 클래스 사용 방법
다중 인터페이스 구현 클래스
public class 구현클래스이름 implements 인터페이스A, 인터페이스B {
// 인터페이스 A에 선언된 추상 메소드의 실체 메소드 선언
// 인터페이스 B에 선언된 추상 메소드의 실체 메소드 선언
인터페이스 사용
대입한 후에는 재정의된 구현 객체의 메소드를 호출할 수 있다.
멤버 클래스
로컬 클래스
인스턴스 멤버 클래스