본문 바로가기
Framwork/Java기초

Chapter 7. 클래스와 객체(2)

by 김엉배 2022. 11. 4.
728x90
반응형

    목차

1. 클래스 기본과 객체 생성
2. 생성자(constructor)
3. 인스턴스 변수와 클래스 변수
4. this 키워드
5. static 키워드
6. 자바의 접근 제어와 private 키워드
7. 자료형으로서의 클래스
8. 인스턴스 배열
9. 클래스 예제들

 

4. this 키워드

-this는 그 순간에 클래스를 이용하는 인스턴스를 가리키는 변수이다.

 

  • 생성자와 this 키워드
class Book {
	String title;
	int price;
	
	Book(String title, int price) {
		this.title = title;
		this.price = price;
	}
}
-------------------------------------
public class Code_111 {
	public static void main(String[] args)
	{
		Book b1 = new Book("Peter Pan", 10000);
		Book b2 = new Book("Aladdin", 9000);
		System.out.println(b1.title + ", " + b1.price);
		System.out.println(b2.title + ", " + b2.price);
	}
}
//결과값
Peter Pan, 10000
Aladdin, 9000

- Book class에서 this를 보면 현재 이용되고 있는 인스턴스를 가리키는 특별한 참조 변수이다.

  이때 this는 b1, b2를 가리킨다.

 

class Book {
	String title;
	int price;
	
	Book( ){}
	
	Book(String title) {
		this.title = title;
	}
	
	Book(String title, int price) {
		this.title = title  //this(title); <= 수정(똑같은 코드가 중복되기 때문에 8번 줄이 중복)
		this.price = price;
	}
}
---------------------------------------
public class Code_112 {
	public static void main(String[] args) {
		Book b = new Book("Java", 25000); // 객체를 생성하면 12번 줄이 실행된다.
	}
}

- this 키워드는 어떤 생성자가 오버 로딩된 다른 생성자를 호출할 때도 사용할 수 있으나 중복에 주의하면서 사용해야 한다.

 

class Student {
	int number;
	String name;
	double score;
	
	Student( ){}
	
	Student(int number) {
		this.number = number;
	}
	
	Student(int number, String name) {
		this(number);
		this.name = name;
	}
	
	Student(int number, String name, double score) {
		this(number, name);
		this.score = score;
	}
}
---------------------------------------------------------
public class Code_113 {
	public static void main(String[] args) {
		Student s = new Student(10, "Paul", 88.5);
	}
}

- this를 이용하여 다른 생성자를 호출 할 때는 반드시 생성자 첫 줄에 한 번만 써야 한다.

 

5. static 키워드

- static 키워드는 메소드 앞에 사용할 수도 있고, static 블록을 만들어서 사용할 수도 있다.

 

  • static 변수
    static 변수는 하나의 클래스에서 정확히 한 개만 만들어지는 변수이다. '클래스. static 변수명'으로 사용한다.
class Circle {
	
	static double PI = 3.141592;
	double radius; //반지름
	
	Circle(double radius) {
		this.radius = radius;
	}
	
	double area( ) {
		return this.radius * this.radius * PI;
	}
	
	double perimeter( ) {
		return 2 * PI * this.radius;
	}
}
------------------------------------------------
public class Code_114 {
	public static void main(String[] args)
	{
		Circle c1 = new Circle(10.0);
		Circle c2 = new Circle(100.0);
		System.out.println("area of c1 : " + c1.area( ));
		System.out.println("perimeter of c1 : " + c1.perimeter( ));
		System.out.println("area of c2 : " + c2.area( ));
		System.out.println("perimeter of c2 : " + c2.perimeter( ));
	}
}
//결과값
area of c1 : 314.1592
perimeter of c1 : 62.83184
area of c2 : 31415.920000000002
perimeter of c2 : 628.3184

 - 위 코드를 보면 PI 값을 모든 인스턴스가 가질 필요가 없기에 클래스 변수로 만들어서 공유한다.

 

  • static 메소드
    메소드 앞에 static 키워드를 붙이고, 클래스 메소드 또는 정적 메소드라고 부르며,  호출 시 '클래스.메소드명()' 이용한다.
class Person {
	
	static int count;
	String name;
	
	Person( ) {
		count ++;
	}
	
	static void printCount( ) {
		System.out.println("count : " + count);
	}
}
--------------------------------------------------
public class Code_115 {
	public static void main(String[] args)
	{
		Person p1 = new Person( );
		Person p2 = new Person( );
		Person.printCount( );
		p1.printCount();
		p2.printCount();
	}
}
//결과값
count : 2
count : 2
count : 2

- 위 코드와 같이 '클래스명.메소드명()' 또는 '인스턴스명.메소드()'으로 static 메소드를 호출할 수 있으나, 

   '클래스명.메소드명()'이 올바른 형식이다.

 

class Data {
	
	static int x;
	int y;
	
	Data(int x, int y) {
		Data.x = x;
		this.y = y;
	}
	
	void print( ) {
		System.out.println("x : " + x);
		System.out.println("y : " + y);
	}
}
-------------------------------------------
public class Code_116 {
	public static void main(String[] args) {
		Data d = new Data(10, 20);
		d.print( );
	}
}
//결과값
x : 10
y : 20

- static 메소드에서는 static 멤버만 사용할 수 있다.

 

  • static 블록과 non-static블록
class Block {
	Block( ) {
		System.out.println("I am constructor");
	}
	
	{ // non-static 블록
		System.out.println("I am block");
	}
}
----------------------------------------------------
public class Code_117 {
	public static void main(String[] args)
	{
		Block b1 = new Block( );
		Block b2 = new Block( );
	}
}
//결과값
I am block
I am constructor
I am block
I am constructor

 - non-static 블록은 생성자처럼 인스턴스를 생성할 때마다 수행되는 영역.

class Block {
	Block( ) {
		System.out.println("I am constructor");
	}
	
	static {
		System.out.println("I am static block");
	}
}
---------------------------------------------------
public class Code_118 {
	public static void main(String[] args)
	{
		Block b1 = new Block( );
		Block b2 = new Block( );
	}
}
//결과값
I am static block
I am constructor
I am constructor

 - static 블록은 생성자처럼 첫 번째 인스턴스를 생성하기 바로 전에 한 번만 수행되는 블록

 

6.  자바의 접근 제어와 private 키워드

 클래스 내의 멤버에 대해서 접근 권한을 줄 수가 있는데, 다음과 같이 네 가지의 접근 권한이 있다.

private  같은 클래스 내에서만 접근이 가능하다.
protected  상속과 관계가 있다.
(default)  패키지와 관계가 있다.
public  어디서나 접근 가능하다.

 

  • private 키워드
class Book {
	private String title;
	private int price;
	
	Book( ){}
	
	Book(String title, int price){
		this.title = title;
		this.price = price;
	}
	
	void printBook( ) {
		System.out.println("title : " + title);
		System.out.println("price : " + price);
	}
}
-------------------------------------------------
public class Code_119 {
	public static void main(String[] args)
	{
		Book bk = new Book("Java Programming", 25000);
		bk.printBook( );
		bk.price = 27000; // 에러 (The field Book.price is not visible.)
	}
}

 - 인스턴스 변수인 title과 price 앞에 private 키워드가 붙어 있기 때문에 다른 클래스에서 사용하면 에러가 나타난다.

 

  • public 키워드
    public 키워드는 private 키워드와 완전히 반대로 어디서나 사용할 수 있다. 즉 접근 제어가 전혀 없는 키워드다.

  • 디폴트 접근 제어
    디폴트 접근 제어는 private, public, protected 키워드가 아무것도 붙지 않을 때 디폴트 접근 제어라고 한다.

class Data {
	private int x; // private 접근 제어
	public int y; // public 접근제어 
	int z; // 디폴트 접근 제어 
}
---------------------------------------
public class Code_120 {
	public static void main(String[] args)
	{
		Data data = new Data( );
		data.x = 10; // 에러 발생
		data.y = 20;
		data.z = 30;
	}
}
  • 접근자 메소드와 변경자 메소드
    - 접근자(accessor): 인스턴스 변수의 값을 가져오기 위한 메소드, 이름을 getXXX()의 형태로 사용하는데
                                     XXX자리에는 인스턴스 변수명을 넣어준다.
    - 변경자(mtator): 인스턴스 변수의 값을 수정하기 위한 메소드, 이름은 setXXX()의 형태로 사용하는데
                                  XXX자리에는 인스턴스 변수명을 넣어준다.
class Book {
	private String title;
	private int price;
	
	Book( ){}
	
	Book(String title, int price){
		this.title = title;
		this.price = price;
	}
	
	String getTitle( ) { // title 접근자 
		return title;
	}
	
	int getPrice( ) { // price 접근자 
		return price;
	}
	
	void setTitle(String title) { // title 변경자 
		this.title = title;
	}
	
	void setPrice(int price) { // price 변경자 
		this.price = price;
	}
	
	void printBook( ) {
		System.out.println("title : " + title);
		System.out.println("price : " + price);
	}
}
-------------------------------------------------
public class Code_121 {
	public static void main(String[] args)
	{
		Book bk = new Book("Java Programming", 25000);
		bk.printBook( );
		bk.setPrice(27000); // 변경자 (mutator) 호출 
		bk.setTitle("Java Programming 2"); // 변경자 (mutator)호출 
		System.out.println("title : " + bk.getTitle( )); // 접근자 (accessor)호출 
		System.out.println("price : " + bk.getPrice( )); // 접근자 (accessor) 호출
	}
}
//결과값
title : Java Programming
price : 25000
title : Java Programming 2
price : 27000

 - Book클래스 외부에서 인스턴스 변수 price를 직접 접근할 수 없기 때문에 setPrice() 메소드와 getPrice()메소드를 추가했다.

 

7.   자료형으로서의 클래스

- 기본 자료형(primitve data types): boolen, char, byte, short, int, long, float, double

- 참조 자료형(reference data types): 배열, 클래스

class Point {
	private int x;
	private int y;
	
	Point( ) {}
	
	Point(int x, int y) {
		this.x = x;
		this.y = y;
	}
	
	int getX( ) {
		return x;
	}
	
	int getY( ) {
		return y;
	}
	
	void setX(int x) {
		this.x = x;
	}
	
	void setY(int y) {
		this.y = y;
	}
}
---------------------------
public class Code_122 {
	static void add(Point t1, Point t2) {
		Point pt = new Point( );
		pt.setX(t1.getX( ) + t2.getX( ));
		pt.setY(t1.getY( ) + t2.getY( ));
		System.out.println("p1 + p2 : (" + pt.getX( ) + "," + pt.getY( ) +
				")");
	}
	
	public static void main(String[] args) {
		Point p1 = new Point(1, 3);
		Point p2 = new Point(5, 8);
		System.out.println("p1 : (" + p1.getX( ) + "," + p1.getY( ) + ")");
		System.out.println("p2 : (" + p2.getX( ) + "," + p2.getY( ) + ")");
		add(p1, p2);
	}
}
//결과값
p1 : (1,3)
p2 : (5,8)
p1 + p2 : (6,11)

 - 참조 자료형인 배열과 클래스 인스턴스는 데이터 자체가 새롭게 생기지 않고 참조값이 넘어간다.

class Point {
   .....
}
----------------
public class Code_123 {
	static void change(Point t) {
		t.setX(10);
		t.setY(33);
	}
	
	public static void main(String[] args) {
		Point p = new Point(2, 7);
		System.out.println("before : (" + p.getX( ) + "," + p.getY( ) + ")");
		change(p);
		System.out.println("after : (" + p.getX( ) + "," + p.getY( ) + ")");
	}
}
//결과값
before : (2,7)
after : (10,33)

- 참조값을 메소드 change() 넘겨 코드는 위처럼 수행된다.

class Point {
   .....
}
----------------
public class Code_124 {
	static Point add(Point t1, Point t2) {
		Point t3 = new Point( );
		t3.setX(t1.getX( ) + t2.getX( ));
		t3.setY(t1.getY( ) + t2.getY( ));
		return t3;
	}
	
	public static void main(String[] args) {
		Point p1 = new Point(10, 20);
		Point p2 = new Point(11, 33);
		Point p3 = add(p1, p2);
		System.out.println("p3 : (" + p3.getX( ) + "," + p3.getY( ) + ")");
	}
}
//결과값
p3 : (21,53)

 

 

8.   인스턴스 배열

- 배열은 같은 자료형의 데이터를 한꺼번에 저장할 수 있도록  하는 공간이다.

class Student {
	private String name;
	private int score;
	Student(String name, int score) {
		this.name = name;
		this.score = score;
	}
	String getName( ) {
		return name;
	}
	int getScore( ) {
		return score;
	}
	void print( ) {
		System.out.println(name + "(" + score + ")");
	}
}
---------------------------------------------------------
public class Code_125 {
	public static void main(String[] args) {
		Student st[] = new Student[5];
		st[0] = new Student("Alice", 88);
		st[1] = new Student("Tom", 98);
		st[2] = new Student("Jenny", 80);
		st[3] = new Student("Betty", 79);
		st[4] = new Student("Daniel", 91);
		int total = 0;
		for (int i = 0 ; i < st.length; i++)
			total += st[i].getScore( );
		double average = (double) total / st.length;
		System.out.println("average : " + average);
	}
}
//결과값 
average : 87.2

- main에서 인스턴스를 저장한 배열을 만들고 for문을 돌려 평균값을 계산.

 

 

9.   클래스 예제들

class Score {
	private int math;
	private int english; 
	
	Score( ){}
	
	Score(int math, int english) {
		this.math = math;
		this.english = english;
	}
	
	int getMath( ) { return math; }
	int getEnglish( ) { return english; }
	void setMath(int math) { this.math = math; }
	void setEnglish(int english) { this.english = english; }
	void incMath(int n) { this.math += n; }
	void incEnglish(int n) { this.english += n; }
}
-------------------------------------------------------------
class Student {
	private String name;
	private Score score;
	
	Student( ){}
	
	Student(String name, Score score) {
		this.name = name;
		this.score = score;
	}
	String getName( ) { return name; }
	
	Score getScore( ) { return score; }
	
	void setName(String name) { this.name = name; }
	
	void setScore(Score score) { this.score = score; }
	
	void incScore(int m, int e) {
		score.incMath(m);
		score.incEnglish(e);
	}
	
	void printStudent( ) {
		System.out.println(name +
				" : math(" + score.getMath( ) + "), english(" + score.getEnglish( ) +
				")");
	}
}
------------------------------------------------------------
public class Code_126 {
	
	public static void main(String[] args) {
		Student s1 = new Student("Alice", new Score(90, 80));
		Score a = new Score(88, 93);
		Student s2 = new Student("Bob", a);
		Student s3 = new Student( );
		Score b = new Score(78, 70);
		s3.setName("Paul");
		s3.setScore(b);
		s1.incScore(3,5);
		s1.printStudent( );
		s2.printStudent( );
		s3.printStudent( );
	}
}
//결과값
Alice : math(93), english(85)
Bob : math(88), english(93)
Paul : math(78), english(70)
class Coin {
	
	private int value;
	private int count;
	
	Coin( ){}
	
	Coin(int value, int count) {
		this.value = value;
		this.count = count;
	}
	
	int getValue( ) { return value; }
	
	int getCount( ) { return count; }
	
	void setValue(int value) {
		this.value = value;
	}
	
	void setCount(int count) {
		this.count = count;
	}
}
-----------------------------------
class Purse {
	private String owner;
	private Coin coin[];
	
	Purse( ){}
	
	Purse(String owner, Coin coin[]) {
		this.owner = owner;
		this.coin = coin;
	}
	
	String getOwner( ) {
		return owner;
	}
	
	Coin[] getCoin( ) {
		return coin;
	}
	
	void setOwner(String owner) {
		this.owner = owner;
	}
	
	void setCoin(Coin[] coin) {
		this.coin = coin;
	}
}
----------------------------------------------
public class Code_127 {	
	public static void main(String[] args)
	{
		Coin coin1 = new Coin(500, 4);
		Coin coin2 = new Coin(100, 3);
		Coin coin3 = new Coin(50, 6);
		Coin coin4 = new Coin(10, 7);
		Coin coin[] = { coin1, coin2, coin3, coin4 };
		Purse purse = new Purse("Alice", coin);
		System.out.println(purse.getOwner( ) + " 지갑의 각 동전 개수");
		for (Coin c : purse.getCoin( ))
			System.out.println(c.getValue( ) + "원 : " + c.getCount( ) + "개");
					int total = 0;
			for (Coin c : purse.getCoin( )) {
				total += c.getValue( ) * c.getCount( );
			}
			System.out.println(purse.getOwner( ) + "는 지갑에 " + total + "원 있습니다");
	}
}
//결과값
Alice 지갑의 각 동전 개수
500원 : 4개
100원 : 3개
50원 : 6개
10원 : 7개
Alice는 지갑에 2670원 있습니다
728x90
반응형

'Framwork > Java기초' 카테고리의 다른 글

Chapter 9. 패키지와 접근 제어  (7) 2023.08.06
Chapter 8. 상속  (5) 2023.08.06
Chapter 7. 클래스와 객체(1)  (0) 2022.10.30
Chapter 6. 메소드  (0) 2022.10.26
Chapter 5. 배열과 문자열  (2) 2022.10.23