📌240104 과제 Solution
- 내림차순으로 정리하는 sort method를 추가할 수 있다
- sort method의 코드를 이해하려면, 참조형배열인 students 변수가 어떤 형태로 저장되어 있는지 그림으로 이해해야 한다. (그래야 덩어리로 비교한다는 말을 이해할 수 있음)
package ex07_08_private_field;
public class Student_Make_Solution_Array_Sort {
public static void main(String[] args) {
Student[] students = { new Student("강호동", 85, 60, 70),
new Student("이승기", 90, 95, 80),
new Student("유재석", 75, 80, 100),
new Student("하하", 80, 70, 95),
new Student("이광수", 100, 65, 80) };
int subject[] = getTotal(students);
sort(students);
print(students, subject);
}
private static int[] getTotal(Student[] objs) {
int[] subject = new int[3];
for (Student obj : objs) {
subject[0] += obj.kor;
subject[1] += obj.eng;
subject[2] += obj.math;
}
return subject;
}
static void print(Student[] objs, int[] subject) {
System.out.println("========= 학생별 / 과목별 총점 구하기 =========");
System.out.println("이름\t국어\t영어\t수학\t총점\t평균");
for (Student obj : objs) {
printInfo(obj);
}
for (int j = 0; j < 45; j++) {
System.out.print("=");
}
System.out.print("\n총점\t");
for (int i = 0; i < subject.length; i++)
System.out.print(subject[i] + "\t");
}
static void printInfo(Student student) {
System.out.print(student.name + "\t" + student.kor + "\t" + student.eng + "\t" + student.math + "\t"
+ student.getTotal() + "\t");
System.out.printf("%.1f\n", student.getAverage());
}
private static void sort(Student[] students) {
for (int i = 0; i < students.length - 1; i++) {
for (int j = i + 1; j < students.length; j++) {
if (students[i].getTotal() < students[j].getTotal()) {
Student imsi = students[i];
students[i] = students[j];
students[j] = imsi;
}
}
}
}
}
📌 Static Field
- 클래스 필드에 Static으로 선언된 멤버는 클래스를 통해 생성되는 모든 인스턴스에서 동일한 값을 가진다.
- class(static) variable은 인스턴스 생성없이 '클래스이름.클래스변수명'으로 접근한다.
instance variable은 각 인스턴스의 개별 저장공간으로 '참조변수.인스턴스변수명'으로 접근한다.
class Accumulator {
int total = 0;
static int grandTotal = 0;
void accumulate(int amount) {
total += amount;
grandTotal += amount;
}
}
public static void main(String args[]) {
System.out.println("정적변수 grandTotal = " + Accumulator.grandTotal);
Accumulator obj1 = new Accumulator();
obj1.accumulate(10);
System.out.println("obj1.total = "+obj1.total);
System.out.println("obj1.grandTotal = "+obj1.grandTotal);
System.out.println("Accumulator.grandTotal = "+Accumulator.grandTotal);
Accumulator obj2 = new Accumulator();
obj2.accumulate(20);
System.out.println("===========================================");
System.out.println("obj2.total = "+obj2.total);
System.out.println("obj2.grandTotal = "+obj2.grandTotal);
System.out.println("Accumulator.grandTotal = "+Accumulator.grandTotal);
}
정적변수 grandTotal = 0
obj1.total = 10
obj1.grandTotal = 10
Accumulator.grandTotal = 10
===========================================
obj2.total = 20
obj2.grandTotal = 30
Accumulator.grandTotal = 30
- total은 정적필드가 아니다. 즉, 인스턴스를 생성할 때마다 초기화되는 값이다.
반면 정적필드 grandTotal은 Accumulator 클래스와 함께 Method Area 메모리 영역에 올라가 있다.
인스턴스 생성 후 accumulate(10)을 했을 때 10이 저장되어 있고,
두 번째 인스턴스 생성 후 accumulate(20)을 했을 때 20이 더해지고 대입된다.
그 결과 30이 저장되어 있는 것이다.
📌 Static method
- 동일한 클래스 안에 static method가 정의된 경우
메소드를 호출할 때 '클래스명.'을 생략하고 '메소드이름(매개변수)'로 호출할 수 있다.
public class Circle {
public static void main(String[] args) {
Circle obj = new Circle(3.5);
Circle.print(obj);
obj.radius = 5.5;
print(obj);
}
private static void print(Circle obj) {
System.out.println("원의 반지름 = " + obj.radius);
System.out.println("원의 넓이 = " + obj.getArea());
}
}
📌 캡슐화 및 접근제어자 / getter, setter
- 객체 지향 프로그래밍의 주요 특징 중 하나인 캡슐화는 클래스 멤버를 클래스 내부에 감추는 것이다.
클래스 멤버를 외부에서 조작할 수 없도록 은닉하기 위해 접근제어자 private을 사용한다.
- 하지만 일부 멤버는 외부 클래스가 사용할 수 있도록 공개해야 한다.
예로 리모컨은 복잡한 내부 회로를 캡슐화해서 은폐하지만 전원 버튼, 음량 조절 버튼 등은 외부에 노출해서 사용할 수 있게 한다.
이처럼 클래스 내부에 은닉한 필드를 외부에서 사용할 수 있도록 Getter와 Setter를 제공한다.
일반적으로 Getter는 get, Setter는 set으로 시작하는 이름을 사용한다.
private으로 설정된 radius 클래스의 필드에 접근 하기 위해서 getRadius(), setRadius()메서드를 사용한다.
- public : 다른 package에서도 접근 가능
protected : 같은 package안에서는 접근 가능 / 다른 package의 자손은 접근 가능
default : 같은 package안에서만 접근 가능
private : 같은 class안의 멤버들만 접근 가능
public class Circle {
private double radius;
final double PI = 3.14;
Circle(double radius) {
this.radius = radius;
}
double getArea() {
return radius * radius * PI;
}
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
this.radius = radius;
}
}
📌 singleton
- getInstance() 메서드를 활용해 객체를 생성할 수 있다.
객체 생성 방법이 new 연산자로 정의해주는 것만 있는 건 아니었다.
- 참조변수인 obj1, obj2는 서로 같은 객체를 가리키고 있으므로, 서로 같은 값을 갖는다.
class Singleton {
private static Singleton s = new Singleton();
private Singleton() {}
public static Singleton getInstance() {
System.out.println("여기는 getInstance입니다");
return s;
}
}
public class Singleton_main {
public static void main(String[] args) {
Singleton obj1 = Singleton.getInstance();
Singleton obj2 = Singleton.getInstance();
if(obj1 == obj2) {
System.out.println("같은 Singleton 객체입니다.");
} else {
System.out.println("다른 Singleton 객체입니다.");
}
}
}