클래스 (class)

Agnes Park·2022년 2월 20일
0

JAVA

목록 보기
19/34

1. 클래스

1. 클래스의 정의

우리가 만든 클래스를 사용하려면, 그 클래스의 '인스턴스(실체 instance)'를 생성해야 함.
구문
클래스이름 변수이름 = new 생성자();
생성자(): 클래스의 이름과 동일, 클래스의 멤버변수들을 초기화

  • new 로 생성하는 instance 들은 지역변수와는 달리 인스턴스가 생성될 때 (자동으로) 초기화가 된다.
  • 특별히 초기화를 할 값들이 지정되어 있지 않을 때는 각 변수 타입의 기본값(디폴트 값)으로 초기화가 됨
    boolean -> false, 숫자타입(int, double, ...) -> 0
    String, 참조 타입(클래스) -> null
  • 지역변수: 메소드 안에서 선언된 변수
    -> 지역변수는 사용하기 전에 반드시 초기화를 해줘야 함.
package com.lec.java.class01;

public class Class01Main {

	public static void main(String[] args) {
		System.out.println("클래스 생성 & 사용");
		
		MyTV tv1 = new MyTV();
		tv1.disPlayStatus();
		
		tv1.powerOnOff();
		
		tv1.volumeUp();
		tv1.volumeUp();
		tv1.volumeUp();
		
		
		tv1.channelUp();
		tv1.channelUp();
		tv1.channelDown();
		
		// tv1.volume = 124;; // private 멤버는 다른 클래스에서 직접 사용 불가 not visible 에러
		
		
		tv1.disPlayStatus();
		
		tv1.powerOnOff();
		
		MyTV tv2 = new MyTV();
		tv2.volumeUp();
		tv2.volumeDown();
		tv2.disPlayStatus();
		
		System.out.println(tv1);	// 패키지 내 Heap에 생긴 주소 출력
		System.out.println(tv2);
		
		tv1 = tv2;
		tv1.disPlayStatus();
		tv1.powerOnOff();
		
		System.out.println();
		tv1.disPlayStatus();
		tv2.disPlayStatus();	// tv1 과 tv2 는 같은 인스턴스를 레퍼런스 한다
		
		System.out.println("tv1: " + tv1);
		System.out.println("tv2: " + tv2);
		
		System.out.println("\n프로그램 종료");
	} // end main()
	
} // end class

2. 클래스의 사용

  • 우리가 만들고자 하는 대상의 '상태' 와 '기능' 을 함께 가지고 있는 '데이터 타입'
    상태(속성, 필드) -> 클래스의 멤버변수로 정의
    => field, attribute, member variable 라고 함
    기능(동작) -> 클래스의 멤버메소드로 정의
    => behavior, member method 라고 함

일반적으로,

  • 멤버변수(필드)는 private 으로 설정
  • 멤버메소드는 public 으로 설정
package com.lec.java.class01;

public class MyTV {
	
	// TV의 상태
	// 멤버변수 : 같은 클래스 내에서 정의된 모든 메소드에서 사용 가능
	private boolean isPowerOn; // 전원 on/off
	private int channel; // 현재 채널
	private int volume; // 현재 볼륨
	
	
	// TV의 기능
	// TV의 현재 상태를 출력하는 동작
	public void disPlayStatus() {
		System.out.println("TV 현재 상태");
		System.out.println("--------------------------------------");
		System.out.println("전원 상태: " + isPowerOn);
		System.out.println("채널 상태: " + channel);
		System.out.println("볼륨 상태: " + volume);
		System.out.println("--------------------------------------");
	}
	
	// 전원 on/OFF 동작
	public void powerOnOff() {
		if(isPowerOn) {	// TV가 켜져 있으면
			isPowerOn = false;
			System.out.println("TV를 끕니다");
		} else {	// TV가 꺼져 있으면
			isPowerOn = true;
			System.out.println("TV가 켜졌습니다");
		}
	}
	
	// 채널 UP
	public int channelUp() {
		channel++;
		System.out.println("현재 채널: " + channel);
		
		return channel;
	}
	
	// 채널 DOWN
	public int channelDown() {
		channel--;
		System.out.println("현재 채널: " + channel);
		
		return channel;
	}
	
	// 볼륩 UP
	public int volumeUp() {
		volume++;
		System.out.println("현재 볼륨: " + volume);
		
		return volume;
	}
	
	// 볼륨 DOWN	
	public int volumeDown() {
		volume--;
		System.out.println("현재 볼륨: " + volume);
		
		return volume;
	}
}\

[메모리내 클래스]

  • tv1에 tv2 주소값 대입
  • garbage collector가 HEAP 내의 MyTV tv1 삭제

2. 생성자 (Constructor)

package com.lec.java.class02;


public class Class02Main {

	public static void main(String[] args) {
		System.out.println("클래스 연습");		
		
		Circle c1 = new Circle();
		Circle c2 = new Circle(3);
		
		double perimeter = c1.calcPerimeter();
		System.out.println("c1의 둘레: " + perimeter);
		perimeter = c2.calcPerimeter();
		System.out.println("c의 둘레: "+ perimeter);
		
		double area = c1.calcArea();
		System.out.println("c1의 넓이: " + area);
		area = c2.calcArea();
		System.out.println("c2의 넓이: " + area);
		
		// Rectangle 인스턴스 2개 이상 생성, 동작
		Rectangle r1 = new Rectangle();	// 기본 생성자 호출
		System.out.println("r1의 둘레: " + r1.calcPerimeter());
		System.out.println("r1의 넓이: " + r1.calcArea());
		
		Rectangle r2 = new Rectangle(2, 3);
		System.out.println("r2의 둘레: " + r2.calcPerimeter());
		System.out.println("r2의 넓이: " + r2.calcArea());
		
		System.out.println("프로그램 종료");
	} // end main()

} // end class Class02Main

생성자(Constructor)

  • 생성자의 목적: 인스턴스 생성시 멤버변수들의 초기화
  • 생성자의 이름은 반드시 클래스의 이름과 동일
  • 생성자는 리턴 타입이 없다.
  • 생성자도 매개변수(argument)를 가질 수 있다.
  • 생성자도 오버로딩(overload) 가능
  • 클래스를 만들 때, 생성자를 따로 만들지 않으면
    '디폴트 생성자(default constructor) = 기본 생성자'를 자동으로 만들어줌.
  • 디폴트 생성자란 : 매개변수가 없는 생성자. 모든 멤버변수는 기본값으로 초기화
    (주의) 클래스에서 하나 이상의 생성자를 만들게 되면, 자동으로 디폴트 생성자를 만들어 주지 않는다.
    (강력권장) 아무일도 안하더라도 디폴트 생성자는 반드시 만들어 주자.
package com.lec.java.class02;
public class Circle {

	// 원의 상태(속성) -> 멤버변수 (필드)
	double radius;
	
	// 생성자 -> 인스턴스 생성시 자동 호출
	// ↓ 기본 생성자
	public Circle() {
		System.out.println("Circle() 생성자 호출");
		System.out.println("반지름: " + radius);
	}
	
	// ↓ 생성자 오버로딩 가능.
	public Circle(double r) {
		System.out.println("Circle(" + r + ") 생성자 호출");
		radius = r;	// 멤버변수 초기화 (멤버변수를 매개변수 r로 초기화하는 것)
		System.out.println("반지름: " + radius);
	}
	
	// 원의 동작(기능) -> 메소드
	// 원의 둘레 계산
	public double calcPerimeter() {
		return 2 * Math.PI * radius;
	}
	
	
	// 원의 넓이 계산
	public double calcArea() {
		return Math.PI * radius * radius;
	}
	
}
package com.lec.java.class02;

public class Rectangle {

	// 직사각형의 속성
	// 너비, 높이
	private double width;
	private double height;
	
	// 디폴트 생성자
	public Rectangle() {
		width = 100;	// 디폴트 값을 지정해줄수 있다
		height = 100;
		System.out.println("가로: " + width);
		System.out.println("세로: " + height);
	}
	
	// 너비와 높이를 매개변수로 받아 초기화 하는 생성자
	public Rectangle(double w, double h) {
		width = w;
		height = h;
		System.out.println("가로: " + width);
		System.out.println("세로: " + height);
	}
	
	// 직사각형의 동작
	// 사각형의 둘레
	public double calcPerimeter() {
		return (width + height) * 2;
	}
	
	// 사각형의 넓이
	public double calcArea() {
		return width * height;
	}
}

3. 캡슐화, 은닉, 추상화

클래스 안에 필요한 '속성' 과 '행동' 을 멤버로 묶고 외부에서의 '직접적인 접근을 제한'하여 객체의 데이터 와 메소드를 은닉(hiding)하고, 사용자에게는 필요한 기능만 제공하여 추상화(abstraction) 하는 객체지향 기술을 '캡슐화(encapsulation)' 라고 한다

클래스의 멤버변수를 접근하기 위한 기능을 제공하는 메소드를 getter , setter 라 한다

package com.lec.java.class03;

public class Class03Main {

	public static void main(String[] args) {
		System.out.println("Getter & Setter");
		
		Number n1 = new Number(100);
//		n1.num = 300; not visible 에러

		System.out.println(n1.getNum());
		n1.setNum(200);
		System.out.println(n1.getNum());
		
		
		System.out.println("프로그램 종료");
	} // end main()
} // end class Class03Main
package com.lec.java.class03;

public class Number {

	// 멤버변수
	private int num;	// 멤버변수 파란색 표시
	private boolean enabled;
        
	// 생성자
	// 디폴트 생성자
	public Number() {}
	
	public boolean isEnabled() {
		return enabled;
	}
	
	public void setEnabled(boolean enabled) {
		this.enabled = enabled;
	}    
    
	// 매개변수 있는 생성자
	public Number(int num) {	// 지역변수 & 매개변수 갈색 표시
		 this.num = num;	// this: 인스턴스 자기자신
	}
	
	// 메소드
	// getter: 멤버 변수의 값을 리턴해 주는 메소드
	// setter: 멤버 변수의 값을 변경해 줄 수 있는 메소드
	public int getNum() {	// 이름 앞에 get 붙이기 - 복수개의 단어로 조합된 경우, 두번째 단어의 첫문자를 대문자로 만들어줌 (camel notation)
		return this.num;
	}
	
	public void setNum(int num) {	// 이름 앞에 set 붙이기
		this.num = num;
	}
	
}
package com.lec.java.class03;

public class Numeric {
	private char ch;
	private byte operator;
	private int operand1;
	private int operand2;
	// 이클립스의 source generator 를 사용하면 손쉽게 자동 코드 생성
	// 방법1. 우클릭후 Sources 메뉴
	// 방법2. ALT + SHIFT + S 누른후 팝업에서 선택
	
	public Numeric() {	// Generate Constructor using Fields -> 4개 모두 Deselect -> 기본생성자
		super();
	}
	
	public Numeric(char ch, byte operator, int operand1, int operand2) {	// Generate Constructor using Fields
		super();
		this.ch = ch;
		this.operator = operator;
		this.operand1 = operand1;
		this.operand2 = operand2;
	}

	public char getCh() {	// Generate Getters and Setters
		return ch;
	}

	public void setCh(char ch) {
		this.ch = ch;
	}

	public byte getOperator() {
		return operator;
	}

	public void setOperator(byte operator) {
		this.operator = operator;
	}

	public int getOperand1() {
		return operand1;
	}

	public void setOperand1(int operand1) {
		this.operand1 = operand1;
	}

	public int getOperand2() {
		return operand2;
	}

	public void setOperand2(int operand2) {
		this.operand2 = operand2;
	}

}

4. 메소드 체이닝 (method chaining)

메소드 체이닝 (methond chaining)
자기자신을 리턴하여, 연이어 메소드
호출 가능케 하는 메소드 설계
보통 setter 와 이와 같은 동작을 수행하는 메소드들에 적용하면 좋다

클래스 안에서 this :
객체 내에서 자기자신(인스턴스)을 가리킴

package com.lec.java.class04;

public class Class04Main {

	public static void main(String[] args) {
		System.out.println("this & 메소드 체이닝");
		
		Number n1 = new Number();
		System.out.println("n1.num = " + n1.getNum());
		
		Number n2 = new Number(123);
		System.out.println("n2.num = " + n2.getNum());

		n1.add(n2);
		System.out.println("n1.num = " + n1.getNum());
		Number n3 = new Number(30);
	
		n1.add(n3);
		n1.add(new Number(100));
		System.out.println("n1.num = " + n1.getNum());
		
		// n1 <- 353
		
		n1.add(n3).add(n3).add(n2).add(new Number(1));
		System.out.println("n1.num = " + n1.getNum());
		
		n3.add(n3).sub(n1);
		// 30 + 30 - 537
		System.out.println("n3.num = " + n3.getNum());
		
		
		
		
		System.out.println("프로그램 종료");
	} // end main()

} // end class Class04Main
package com.lec.java.class04;

public class Number {
	private int num = 100;	// 멤버변수 선언시 초깃값 명시 가능.
	
	// 생성자
	// 기본생성자
	public Number() {
		super();
	}
	
	// 매개변수 받는 생성자
	public Number(int num) {
		super();
		this.num = num;
	}
	
	// getter, setter
	public int getNum() {
		return num;
	}
	
	public void setNum(int num) {
		this.num = num;
	}
	
	public Number add(Number x) {
		this.num += x.num;
		return this;	// 메소드 체이닝 핵심. this.를 리턴
	}
	
	public Number sub(Number x) {
		this.num -= x.num;
		return this;
	}
}

5. 객체의 배열

package com.lec.java.class06;

// 객체의 배열
public class Class06Main {

	public static void main(String[] args) {
		System.out.println("클래스 연습 : 성적처리");
		
		Score [] arrScore = new Score[3];
		
		System.out.println("arrScore =" + arrScore);
		System.out.println("arrScore[0] =" + arrScore[0]);	// null
		
		//System.out.println(arrScore[0].calcTotal());	// NullPointException
		
		arrScore[0] = new Score("홍길동", 100, 80, 70);
		arrScore[1] = new Score("손오공", 78, 23, 62);
		arrScore[2] = new Score("나루토", 52, 93, 100);
		
		for (int i = 0; i < arrScore.length; i++) {
			arrScore[i].displayInfo();
			System.out.println("총점: " + arrScore[i].calcTotal());
			System.out.println("평균: " + arrScore[i].calcAvg());
		}
		
		System.out.println("-------------------------------------");
		
		
		Score [] arr = {
			new Score("아이언맨", 10, 20, 33),
			new Score("캡틴", 100, 100, 0),
			new Score("토르", 54, 22, 91)
		};
		
		for(Score score : arr) {
			System.out.println("총점: " + score.calcTotal());
			System.out.println("평균: " + score.calcAvg());
		}
		
		System.out.println("프로그램 종료");
	} // end main()

} // end class Clas06Main
package com.lec.java.class06;

public class Score {
	// 멤버변수 : 
	private String name; // 	학생 이름 String
	private int kor;     // 	국어점수 int 
	private int math;    // 	수학점수 int
	private int eng;     // 	영어점수 int
	
	
	// 생성자: 멤버 변수 초기화
	//   1) 디폴트 생성자
	public Score() {}
	
	//   2) 매개변수 받는 생성자 (이름, 국어점수, 수학점수, 영어점수)
	public Score(String name, int kor, int eng, int math) {
		this.name = name;
		this.kor = kor;
		this.eng = eng;
		this.math = math;
	}
	
	// 메소드
	// 총점계산 메소드
	// 메소드이름 :calcTotal()
	// 리턴타입 : int
	public int calcTotal() {
		int total = 0;
		total = kor + eng + math;
		
		return total;
	} // end calcTotal()
	
	
	// 평균계산 메소드
	// 메소드 이름 : calcAvg()
	// 리턴타입 : double
	public double calcAvg() {
		double avg = 0;
		avg = (double)calcTotal() / 3;
		
		return avg;
	} // end calcAvg()
	
	// 메소드
	// 이름: displayInfo()
	// 리턴: void
	// 매개변수: none
	//   학생의 이름, 국어, 영어, 수학 점수 출력
	public void displayInfo() {
		System.out.print(name + " : ");
		System.out.print(kor + " : ");
		System.out.print(eng + " : ");
		System.out.print(math + " : ");
		System.out.println();
	} // end displayInfo()

	// getter & setter
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getKor() {
		return kor;
	}

	public void setKor(int kor) {
		this.kor = kor;
	}

	public int getMath() {
		return math;
	}

	public void setMath(int math) {
		this.math = math;
	}

	public int getEng() {
		return eng;
	}

	public void setEng(int eng) {
		this.eng = eng;
	}
	
}

0개의 댓글