자바빈(JavaBean)은 자바에서 사용되는 컴포넌트 모델이며, 재사용 가능한 소프트웨어 컴포넌트를 만들기 위한 규약이다. 자바빈은 소프트웨어 개발에서 일반적으로 사용되는 객체를 쉽게 생성, 관리, 조작할 수 있게 해준다. 자바빈의 주요 특징은 다음과 같다.
public class Person implements Serializable {
private String name;
private int age;
// 기본 생성자
public Person() {
}
// getter
public String getName() {
return name;
}
// setter
public void setName(String name) {
this.name = name;
}
// getter
public int getAge() {
return age;
}
// setter
public void setAge(int age) {
this.age = age;
}
}
이 예제에서 Person 클래스는 name과 age라는 두 개의 속성을 가지며, 각 속성에 대한 getter와 setter 메소드를 제공한다. 이렇게 간단하고 일관된 접근 방식 덕분에 자바빈은 많은 자바 프레임워크와 라이브러리에서 널리 사용된다.


자바에서 캡슐화는 클래스의 데이터(필드)와 그 데이터를 다루는 메소드를 하나의 단위로 묶는 것을 의미한다. 이 개념의 핵심은 객체의 세부 구현 내용을 숨기고, 외부에서는 오직 정의된 인터페이스만을 통해 상호작용할 수 있게 하는 것이다.
캡슐화의 장점은 다음과 같다.
간단한 예를 들어보자. Car 클래스가 있고, 이 클래스에는 speed라는 private 필드가 있다고 하자. 이 필드에 접근하기 위해 getSpeed()와 setSpeed()라는 public 메소드를 제공할 수 있다. 이렇게 함으로써 speed 필드는 외부에서 직접 접근할 수 없게 되며, Car 클래스의 메소드를 통해서만 접근할 수 있다. 이는 캡슐화의 전형적인 예이다.
이처럼 캡슐화는 자바 프로그래밍에서 중요한 객체지향 원칙 중 하나이며, 프로그램의 안정성과 유지보수성을 향상시키는 데 기여한다.

자바에서 접근 제한자(Access Modifiers)는 클래스, 메소드, 변수 등의 멤버에 대한 접근 범위를 제한하는 키워드다. 자바에는 네 가지 주요 접근 제한자가 있다:
이러한 접근 제한자들은 객체지향 프로그래밍의 캡슐화 원칙을 지원하는 데 중요한 역할을 한다. 캡슐화는 클래스의 내부 구현을 숨기고, 외부에서는 제공된 메소드를 통해서만 상호작용할 수 있도록 함으로써, 데이터 보호와 구현의 세부 사항 숨김을 가능하게 한다.
예를 들어, 클래스 Person이 있고, 이 클래스에는 name, age라는 필드와 getName(), setName(String name) 같은 메소드가 있다고 가정해보자. name 필드를 private로 선언하고 getName(), setName(String name) 메소드를 public으로 선언하면, 외부 클래스에서는 직접 name 필드에 접근할 수 없고, 제공된 public 메소드를 통해서만 name 필드의 값을 읽거나 변경할 수 있다. 이것이 캡슐화의 기본적인 예이며, 접근 제한자는 이러한 캡슐화를 구현하는 데 필수적이다.
private와 public은 자바에서 사용되는 접근 제한자이다. 이들은 클래스의 멤버(변수, 메소드 등)에 대한 접근 수준을 정의한다.
class Person {
// private 멤버 변수
private String name;
private int age;
// public 생성자
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// public 메소드
public void displayInfo() {
System.out.println("Name: " + name + ", Age: " + age);
}
// private 메소드
private String getDetails() {
return "Name: " + name + ", Age: " + age;
}
// public getter
public String getName() {
return name;
}
// public setter
public void setName(String name) {
this.name = name;
}
}
public class Main {
public static void main(String[] args) {
Person person = new Person("Alice", 30);
person.displayInfo(); // 가능: public 메소드
System.out.println(person.getName()); // 가능: public getter
// person.getDetails(); // 불가능: private 메소드, 클래스 외부에서 접근 불가
// System.out.println(person.name); // 불가능: private 변수, 직접 접근 불가
}
}
이 예제에서, name과 age 변수는 private으로 선언되어 Person 클래스 외부에서 직접 접근할 수 없다. 대신, public으로 선언된 getName()과 setName(String name) 메소드를 통해 간접적으로 이 변수들에 접근할 수 있다. displayInfo() 메소드 역시 public이므로 클래스 외부에서 호출할 수 있지만, getDetails() 메소드는 private이므로 Person 클래스 내부에서만 호출할 수 있다.
이렇게 private와 public을 적절히 사용함으로써 클래스의 캡슐화를 향상시키고, 외부에서 불필요하거나 위험한 접근을 제한할 수 있다.
super();는 자바에서 상속 관계에 있는 클래스들 사이에서 사용되는 특별한 키워드로, 하위 클래스에서 상위 클래스의 생성자를 호출하는 데 사용된다. 상위 클래스를 '슈퍼클래스'라고도 하며, 하위 클래스는 이 슈퍼클래스로부터 상속을 받는다.
상위 클래스 생성자 호출: super();는 하위 클래스의 생성자 내에서 상위 클래스의 생성자를 호출한다. 이 호출은 하위 클래스의 객체가 생성될 때 상위 클래스의 객체도 적절하게 초기화되도록 보장한다.기본 생성자 호출: super();는 상위 클래스의 '기본 생성자'(매개변수가 없는 생성자)를 호출한다. 만약 상위 클래스에 기본 생성자가 명시적으로 정의되어 있지 않고 다른 생성자만 정의되어 있다면, 하위 클래스에서 super();를 사용하면 컴파일 에러가 발생한다.자동 삽입: 하위 클래스의 생성자에서 상위 클래스의 생성자를 명시적으로 호출하지 않으면, 컴파일러는 자동으로 상위 클래스의 기본 생성자 호출을 위한 super();를 첫 번째 줄에 삽입한다.생성자의 첫 줄에 위치: super();는 하위 클래스의 생성자의 첫 번째 문장이어야 한다. 만약 첫 번째 문장이 아니라면 컴파일 에러가 발생한다.class Parent {
public Parent() {
System.out.println("Parent 클래스의 생성자");
}
}
class Child extends Parent {
public Child() {
super(); // Parent 클래스의 기본 생성자 호출
System.out.println("Child 클래스의 생성자");
}
}
이 경우, Child 클래스의 객체를 생성할 때 Child 클래스의 생성자가 호출되기 전에 super();에 의해 Parent 클래스의 생성자가 먼저 호출된다. 따라서 출력은 다음 순서로 나타난다.
Parent 클래스의 생성자
Child 클래스의 생성자
super();는 클래스 상속과 객체 생성 과정에서 부모 클래스의 올바른 초기화를 보장하는 중요한 역할을 한다.
package com.mystudy.array;
public class SungjukExam {
public static void main(String[] args) {
// 2차원 배열을 사용한 성적 처리
// 국어, 영어, 수학 점수 3개를 저장한 2차원 배열(sungjunk)을 만들고
// 3명 성적을 입력하고 개인별 총점과, 평균을 계산하여 데이터 출력
// --------------------------------------------
/*
* 국어\t영어\t수학 총점 평균
* --------------------
* 100 90 80 270 90.0
* 95 95 95 275 95.0
* 100 90 82 272 90.66
* ---------------------
*/
int[][] studentScore = {{100, 90, 80}, {100, 90, 81}, {100, 90, 82}};
printAllScore(studentScore);
}
static void printAllScore (int[][] arr) {
System.out.println("국어\t영어\t수학\t총점\t평균\t");
System.out.println("--------------------------------------");
for (int[] i : arr) {
int scSum = scoreSum(i);
double avSum = avrSum(i, scSum);
printScore(scSum, avSum, i);
}
}
static int scoreSum (int[] arr) {
int sum = 0;
for (int score : arr) {
sum = sum + score;
}
return sum;
}
static double avrSum(int[] arr, int sum) {
double avr = Math.round((double) sum / arr.length * 100.0) / 100.0;
return avr;
}
static void printScore(int scoreSum, double avrSum, int[] arr) {
for (int i : arr) {
System.out.print(i + "\t");
}
System.out.print(scoreSum + "\t" + avrSum + "\n");
}
}
국어 영어 수학 총점 평균
--------------------------------------
100 90 80 270 90.0
100 90 81 271 90.33
100 90 82 272 90.67
package com.mystudy.bean;
/*
■ 자바빈(Java Bean)
- 멤버변수(property)의 접근제어자는 private
- 멤버변수(property) 마다 get/set 메소드 제공(선택적으로 get만 제공)
- get/set 메소드는 public
- get 메소드는 파라미터 없고, set 메소드는 하나 이상의 파라미터 존재
- 멤버변수(property)가 boolean 타입이면 get 메소드 대신 is 메소드 사용가능
- 외부에서 멤버변수(property) 접근시에는 get/set 메소드를 통해 접근
*/
//public class Student extends Object {
class Student { //extends Object 작성 안하면 컴파일러가 자동 삽입
private String name; //private 선언시 외부에서 직접 접근불가
private int kor = 0;
private int eng = 0;
private int math = 0;
private int tot = kor + math + eng;
private double avg = Math.round((tot / 3) * 100) / 100;
// 생성자 ====================
public Student() {
// super : 부모클래스 객체(인스턴스)
// super(); : 부모클래스 객체(인스턴스)의 기본생성자 호출문
super(); // 생략시 컴파일러가 자동 삽입해서 처리함
}
public Student(String name) {
super(); // 생성자 호출구문은 첫 번재로 작성해야 한다.
this.name = name;
}
public Student(String name, int kor, int eng, int math) {
this(name); //현재객체(인스턴스)의 생성자 호출, 생성자 재사
//this.name = name;
this.kor = kor;
this.eng = eng;
this.math = math;
setTotAvg();
}
// 메소드 ================
// 외부에서 사용할 수 있도록 메소드 제공(public)
// 같은 패키지 내에서 사용하려면 default
// 명칭(호칭) : set메소드, setter, set property
public void setName(String name) {
this.name = name;
}
// 외부에서 데이터를 읽어 가기 위한 get 메소드
// 명칭(호칭) : get메소드, getter, get property(속성값 읽기/조회)
public String getName() {
return name;
}
// kor : setter, getter
public void setKor(int kor) {
if (kor >= 0 && kor <= 100) {
this.kor = kor;
setTotAvg();
} else {
System.out.println("국어 점수 오류");
}
}
public int getKor() {
return kor;
}
public void setEng(int eng) {
this.eng = eng;
setTotAvg();
}
public int getEng() {
return eng;
}
public void setMath (int math) {
this.math = math;
setTotAvg();
}
public int getMath() {
return math;
}
private void setTotAvg() { // private이므로 이 메소드 안에서만 처리한다.
this.tot = (kor + math + eng);
this.avg = Math.round(((double) tot / 3) * 100) / 100.0;
}
public int getTot() {
return tot;
}
public double getAvg() {
return avg;
}
public String toString() {
return "Student [" + "name:" + name + ", kor:" + kor + ", eng:" + eng + ", math:" + math + ", tot:" + tot + ", avg:" + avg + "]";
}
// (실습) setter, getter 만들기 ==============
}
package com.mystudy.bean;
public class StudentMain {
public static void main(String[] args) {
Student stu = new Student();
System.out.println(stu);
// System.out.println("name : " + stu.name); // pirvate선언으로 직접 접근 불가능
stu.setName("홍길동");
System.out.println("name : " + stu.getName());
String name = stu.getName();
System.out.println("name : " + name);
stu.setKor(100);
System.out.println("국어 : " + stu.getKor());
setScore(stu, 90, 70, 78);
printScore(stu);
System.out.println(stu.toString());
Student stu2 = new Student("김유신", 99, 88, 77);
System.out.println(stu2.toString());
}
static void setScore(Student stu, int kor, int eng, int math) {
stu.setKor(kor);
stu.setEng(eng);
stu.setMath(math);
}
static void printScore(Student stu) {
System.out.println("국어:" + stu.getKor() + "\t영어:" + stu.getEng() + "\t수학:" + stu.getMath() + "\t총합:" + stu.getTot() + "\t평균:" + stu.getAvg());
}
}
Student [name:null, kor:0, eng:0, math:0, tot:0, avg:0.0]
name : 홍길동
name : 홍길동
국어 : 100
국어:90 영어:70 수학:78 총합:238 평균:79.33
Student [name:홍길동, kor:90, eng:70, math:78, tot:238, avg:79.33]
Student [name:김유신, kor:99, eng:88, math:77, tot:264, avg:88.0]
package com.mystudy.bean.vo;
/*
* 자바빈(Java Bean) 형태의 클래스 작성
* VO(Value Object) : 값(데이터)을 저장하기 위한 클래스(객체) - Oxxx, OxxxVO, OxxxVo 방식으로 사용
* 사용예) Student, StudentVO, StudentVo
* DTO(Data Transfer Object) : 값(데이터)을 저장해서 전달하기 위한 클래스(객체)
* 사용예) Student, StudentDTO, StudentDto
*/
public class StudentVO {
// 필드(변수) 선언 ---------
// 성명 - name : String
// 국어 - kor : int
// 영어 - eng : int
// 수학 - math : int
// 총점 - tot : int
// 평균 - avg : double
private String name;
private int kor = 0;
private int eng = 0;
private int math = 0;
private int tot = 0;
private double avg = 0;
public StudentVO(String name, int kor, int eng, int math) {
this(name);
setKor(kor);
setEng(eng);
setMath(math);
}
public StudentVO(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
setTot();
setAvg();
}
public int getKor() {
return kor;
}
public void setKor(int kor) {
if (kor <= 100 && kor >= 0) {
this.kor = kor;
setTot();
setAvg();
} else {
System.out.println("잘못돤 국어 점수입니다.");
}
}
public int getEng() {
return eng;
}
public void setEng(int eng) {
if (eng <= 100 && eng >= 0) {
this.eng = eng;
setTot();
setAvg();
} else {
System.out.println("잘못된 영어 점수입니다.");
}
}
public int getMath() {
return math;
}
public void setMath(int math) {
if (math <= 100 && math >= 0) {
this.math = math;
setTot();
setAvg();
} else {
System.out.println("잘못된 수학 점수입니다.");
}
}
public int getTot() {
return tot;
}
public double getAvg() {
return avg;
}
private void setTot() {
this.tot = calTot(this);
}
private void setAvg() {
this.avg = calAvg(this);
}
static int calTot(StudentVO student) {
int tot = (student.getKor() + student.getEng() + student.getMath());
return tot;
}
static double calAvg(StudentVO student) {
double avg = Math.round(((double) student.getTot() / 3) * 100) / 100.0;
return avg;
}
public String toString() {
return "Student [" + "name:" + name + ", kor:" + kor + ", eng:" + eng + ", math:" + math + ", tot:" + tot + ", avg:" + avg + "]";
}
public void printScore() {
System.out.println("Student [" + "name:" + name + ", kor:" + kor + ", eng:" + eng + ", math:" + math + ", tot:" + tot + ", avg:" + avg + "]");
}
}
package com.mystudy.bean.vo;
public class StudentManager {
public static void main(String[] args) {
// 2차원 배열을 사용한 성적 처리
// 국어, 영어, 수학 점수 3개를 저장한 2차원 배열(sungjunk)을 만들고
// 3명 성적을 입력하고 개인별 총점과, 평균을 계산하여 데이터 출력
// --------------------------------------------
/*
* 성명\t국어\t영어\t수학 총점 평균
* --------------------
* 김유신 100 90 80 270 90.0
* 이순신 95 95 95 275 95.0
* 홍길동 100 90 82 272 90.66
* ---------------------
*/
StudentVO stu1 = new StudentVO("김유신", 100, 90, 80);
StudentVO stu2 = new StudentVO("이순신", 95, 95, 95);
StudentVO stu3 = new StudentVO("홍길동", 100, 90, 82);
StudentVO stu4 = new StudentVO("asdf", 101, -1, 103);
System.out.println(stu4.getKor());
StudentVO[] stuArr = {stu1, stu2, stu3};
for (StudentVO st : stuArr) {
st.printScore();
}
}
}
잘못돤 국어 점수입니다.
잘못된 영어 점수입니다.
잘못된 수학 점수입니다.
0
Student [name:김유신, kor:100, eng:90, math:80, tot:270, avg:90.0]
Student [name:이순신, kor:95, eng:95, math:95, tot:285, avg:95.0]
Student [name:홍길동, kor:100, eng:90, math:82, tot:272, avg:90.67]