클래스(class)
서로 다른 여러 데이터형을 자유로이 조합하여 만들 수 있는 자료구조
// 클래스 선언의 예
class XYZ {
int x; // int형 필드 x
long y; // long형 필드 y
double z; // double형 필드 z
}
XYZ a; // XYZ형의 클래스형 변수 a 선언
a = new XYZ(); // XYZ형의 클래스 인스턴스를 생성하고 참조하는 곳을 대입
XYZ a = new XYZ(); // 변수 선언, 인스턴트 생성, 연결 짓기를 한꺼번에 수행
// 클래스형 변수 a가 참조하는 클래스 인스턴스 안의 필드는 a.x, a.y, a.x로 접근
신체검사 데이터용 클래스 배열에서 평균 키와 시력의 분포를 구하기
package ch02_2;
import java.util.Scanner;
// 신체검사 데이터용 클래스 배열에서 평균 키와 시력의 분포를 구하기
public class Ex01_physicalExamination {
static final int VMAX = 21; // 시력 분포(0.0부터 0.1 단위로 21개)
static class PhyscData {
String name; // 이름
int height; // 키
double vision; // 시력
// 생성자
PhyscData(String name, int height, double vision) {
this.name = name;
this.height = height;
this.vision = vision;
}
}
// 키의 평균 값 구하기
static double aveHeight(PhyscData[] dat) {
double sum = 0;
for (int i = 0; i < dat.length; i++) {
sum += dat[i].height;
}
return sum / dat.length;
}
// 시력 분포를 구함
static void distVision(PhyscData[] dat, int[] dist) {
int i = 0;
dist[i] = 0;
for (i = 0; i < dat.length; i++) {
if (dat[i].vision >= 0.0 && dat[i].vision <= VMAX / 10.0) {
dist[(int) (dat[i].vision * 10)]++;
}
}
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
PhyscData[] x = {
new PhyscData("강민하", 162, 0.3),
new PhyscData("김찬우", 173, 0.7),
new PhyscData("박준서", 175, 2.0),
new PhyscData("유서범", 171, 1.5),
new PhyscData("이수연", 168, 0.4),
new PhyscData("장경오", 174, 1.2),
new PhyscData("황지안", 169, 0.8),
};
int[] vdist = new int[VMAX]; // 시력 분포
System.out.println("<< 신체 검사 리스트 >>");
System.out.println("이름 키 시력");
System.out.println("------------------");
for (int i = 0; i < x.length; i++) {
System.out.printf("%-8s%3d%5.1f\\n",
x[i].name, x[i].height, x[i].vision);
}
System.out.printf("\\n평균 키: %5.1fcm\\n", aveHeight(x));
distVision(x, vdist); // 시력 분포 구하기
System.out.println("\\n시력 분포");
for (int i = 0; i < VMAX; i++) {
System.out.printf("%3.1f~: %2d명\\n", i / 10.0, vdist[i]);
}
}
}
/*
<< 신체 검사 리스트 >>
이름 키 시력
------------------
강민하 162 0.3
김찬우 173 0.7
박준서 175 2.0
유서범 171 1.5
이수연 168 0.4
장경오 174 1.2
황지안 169 0.8
평균 키: 170.3cm
시력 분포
0.0~: 0명
0.1~: 0명
0.2~: 0명
0.3~: 1명
0.4~: 1명
0.5~: 0명
(... 생략 ...)
*/
평균 키와 시력 분포(그래프 출력)
package ch02_2;
import java.util.Scanner;
// 평균 키와 시력 분포(그래프 출력)
public class Ex02_physicalExaminationEx {
static final int VMAX = 21; // 시력 분포(0.0부터 0.1간격으로 21개)
static class PhyscData {
String name; // 이름
int height; // 키
double vision; // 시력
// 생성자
public PhyscData(String name, int height, double vision) {
this.name = name;
this.height = height;
this.vision = vision;
}
}
// 평균 키 구하기
static double avgHeight(PhyscData[] dat) {
double sum = 0;
for (int i = 0; i < dat.length; i++) {
sum += dat[i].height;
}
return sum / dat.length;
}
// 시력 분포 구하기
static void distVision(PhyscData[] dat, int[] dist) {
int i = 0;
dist[i] = 0;
for (i = 0; i < dat.length; i++) {
if (dat[i].vision >= 0.0 && dat[i].vision <= VMAX / 10.0) {
dist[(int) (dat[i].vision * 10)]++;
}
}
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
PhyscData[] x = {
new PhyscData("강민하", 162, 0.3),
new PhyscData("김찬우", 173, 0.7),
new PhyscData("박준서", 175, 2.0),
new PhyscData("유서범", 171, 1.5),
new PhyscData("이수연", 168, 0.4),
new PhyscData("장경오", 174, 1.2),
new PhyscData("황지안", 169, 0.8),
};
int[] vdist = new int[VMAX]; // 시력의 분포
System.out.println("<< 신체 검사 리스트 >>");
System.out.println("이름 키 시력");
System.out.println("------------------");
for (int i = 0; i < x.length; i++) {
System.out.printf("%-8s%3d%5.1f\\n", x[i].name, x[i].height, x[i].vision);
}
System.out.printf("\\n평균키: %5.1fcm\\n", avgHeight(x));
distVision(x, vdist);
System.out.println("\\n시력의 분포");
for (int i = 0; i < VMAX; i++) {
System.out.printf("%3.1f~: ", i / 10.0);
for (int j = 0; j < vdist[i]; j++) {
System.out.print("*");
}
System.out.println();
}
}
}
/*
<< 신체 검사 리스트 >>
이름 키 시력
------------------
강민하 162 0.3
김찬우 173 0.7
박준서 175 2.0
유서범 171 1.5
이수연 168 0.4
장경오 174 1.2
황지안 169 0.8
평균키: 170.3cm
시력의 분포
0.0~:
0.1~:
0.2~:
0.3~: *
0.4~: *
(...생략...)
*/
날짜 클래스
package ch02_2;
import java.util.Scanner;
// 날짜 클래스
public class Ex03_YMD {
static class YMD {
int y; // 년
int m; // 월(1~12)
int d; // 일(1~31)
// 각 월의 일수
static int[][] mdays = {
{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, // 평년
{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, // 윤년
};
// year년의 윤년 여부 - 평년: 0 / 윤년: 1
static int isLeap(int year) {
return (year % 4 == 0 && year % 10 != 00 || year % 400 == 0) ? 1 : 0;
}
// 생성자
YMD(int y, int m, int d) {
this.y = y;
this.m = m;
this.d = d;
}
// n일 후의 날짜 반환
YMD after(int n) {
YMD temp = new YMD(this.y, this.m, this.d);
if (n < 0) {
return before(-n);
}
temp.d += n;
while (temp.d > mdays[isLeap(temp.y)][temp.m - 1]) {
temp.d -= mdays[isLeap(temp.y)][temp.m - 1];
if (++temp.m > 12) {
temp.y++;
temp.m = 1;
}
}
return temp;
}
// n일 전의 날짜 반환
YMD before(int n) {
YMD temp = new YMD(this.y, this.m, this.d);
if (n < 0) {
return after(-n);
}
temp.d -= n;
while (temp.d < 1) {
if (--temp.m < 1) {
temp.y--;
temp.m = 12;
}
temp.d += mdays[isLeap(temp.y)][temp.m - 1];
}
return temp;
}
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("날짜를 입력하세요");
System.out.print("년: ");
int y = scanner.nextInt();
System.out.print("월: ");
int m = scanner.nextInt();
System.out.print("일: ");
int d = scanner.nextInt();
YMD date = new YMD(y, m, d);
System.out.print("며칠 전/후의 날짜를 구할까요?: ");
int n = scanner.nextInt();
YMD d1 = date.after(n);
System.out.printf("%d일 후의 날짜는 %d년 %d월 %d일입니다.\\n", n, d1.y, d1.m, d1.d);
YMD d2 = date.before(n);
System.out.printf("%d일 전의 날짜는 %d년 %d월 %d일입니다.\\n", n, d2.y, d2.m, d2.d);
}
}
/*
날짜를 입력하세요
년: 2024
월: 6
일: 22
며칠 전/후의 날짜를 구할까요?: 28
28일 후의 날짜는 2024년 7월 20일입니다.
28일 전의 날짜는 2024년 5월 25일입니다.
*/
클래스 본체와 멤버
클래스 본체에서 아래와 같은 내용 선언 가능
- 멤버(필드, 메서드, 중첩(nested) 클래스, 중첩 인터페이스)
- 클래스 초기화, 인스턴스 초기화
- 생성자
클래스 문법 규칙 및 특징
- 필드, 메서드, 생성자를 선언할 때 public, protected, private를 지정 가능
- 메서드, 생성자는 다중으로 정의(오버로드) 할 수 있음
- final로 선언한 필드는 값을 한 번만 대입 가능
- 생성자는 새로 생성하는 인스턴스를 초기화하기 위해 사용
class A {
private int f1; // 비공개 필드
protected int f2; // 한정 공개 필드
public int f3; // 공개 필드
static final int S1 = 0; // 정적 상수 피 ㄹ드
public A() {
f1 = f2 = f3 = 0;
}
// 생성자
public A(int f1, int f2, int f3) {
this.f1 = f1;
this.f2 = f2;
this.f3 = f3;
}
// 메서드 f1의 setter
public void setF1(int f) {
f1 = f;
}
// 메서드 f1의 getter
public int getF1() {
return f1;
}
}
공개 클래스(public class)
접근 제한자 public을 붙여 클래스 선언
다른 패키지에서 사용할 수 있는 클래스
파이널 클래스(final class)
접근 제한자 final을 붙여 클래스 선언
하위 클래스를 가질 수 없는(다른 클래스가 상속할 수 없는) 클래스
파생 클래스
클래스 A를 직접 상위 클래스(direct superclass)로 하려면 선언할 때 extends A를 추가해야 함
이때 선언한 클래스는 클래스 A의 직접 하위 클래스(direct subclass)가 됨
클래스 선언에 extends가 없는 클래스의 경우, 직접 상위 클래스는 Object 클래스
class C extends A {
// Object는 모든 클래스의 상위 클래스로 java.lang 패키지 소속
// 클래스 A는 Object에서 파생되었고 슈퍼 클래스는 Object, 하위 클래스는 C
// 클래스 C는 클래스 A에서 파생되었고 상위 클래스는 A
}
인터페이스 구현
인터페이스 X를 구현하려면 선언에 implements X를 추가해야 함
class Y implements X {
}
추상 클래스(abstract class)
클래스 수식자인 abstreact를 붙여 클래스를 선언하면 추상 메서드(실체가 정의되지 않은 메서드, 실체는 하위 클래스에서 정의함)를 가질 수 있는 클래스
추상 클래스형은 불완전한 클래스이므로 인스턴스를 만들 수 없음
중첩 클래스(nested class)
클래스 또는 인터페이스 안에 선언한 클래스
멤버 클래스(member class)
그 선언이 다른 클래스 또는 인터페이스 선언에 의해 직접 둘러싸인 클래스
내부 클래스(inner class)
명시적으로 암묵적으로 정적(static)이라고 선언하지 않은 중첩 클래스
정적 초기화나 멤버 인터페이스 선언을 할 수 없음
컴파일을 할 때 상수 필드가 아니면 정적 멤버를 선언할 수 없음
지역 클래스(local class)
이름이 주어진 중첩클래스인 내부클래스
어떤 클래스의 멤버도 될 수 없음
'공부기록 > 알고리즘' 카테고리의 다른 글
Chapter 03-2. 검색 알고리즘_선형 검색 (0) | 2024.08.04 |
---|---|
Chapter 03-1. 검색 알고리즘_검색 알고리즘이란 (0) | 2024.08.04 |
Chapter 02-1. 기본 자료구조_배열이란 (0) | 2024.06.22 |
Chapter 01-2. 기본 알고리즘_반복 (2) | 2023.11.19 |
Chapter 01-1. 기본 알고리즘_알고리즘이란? (0) | 2023.11.19 |
댓글