Presentation is loading. Please wait.

Presentation is loading. Please wait.

[INA470] Java Programming Youn-Hee Han

Similar presentations


Presentation on theme: "[INA470] Java Programming Youn-Hee Han"— Presentation transcript:

1 [INA470] Java Programming Youn-Hee Han http://link.kut.ac.kr
09. 클래스와 객체 II [INA470] Java Programming Youn-Hee Han

2 1. 생성자 생성자(constructor) 생성자의 조건 일반적으로 중복정의 (Overloading) 된다.
객체가 생성될 때에 필드에게 초기값을 제공하고 필요한 초기화 절차를 실행하는 메소드 생성자의 조건 일반 메소드와 흡사 메소드 이름이 클래스 이름과 동일 반환값을 가지지 않는다. “일반적으로” public 접근수식자가 붙는다. 일반적으로 중복정의 (Overloading) 된다.

3 1. 생성자 생성자 정의 예

4 1. 생성자 생성자 사용 예

5 1. 생성자 디폴트 생성자 (Default Constructor)
만약 클래스 작성시에 생성자를 하나도 만들지 않는 경우에는 자동적으로 메소드의 몸체 부분이 비어있는 디폴트 생성자가 만들어진다. 이 생성자를 호출하면 객체는 만들어지지만 필드 초기화 등의 작업은 전혀 이루어지지 않는다.

6 1. 생성자 디폴트 생성자 (Default Constructor)
주의할 점: 임의의 생성자가 하나라도 정의되면 디폴트 생성자가 자동으로 추가되지 않는다.

7 1. 생성자 생성자에서 다른 생성자 호출하기 생성자들은 거의 비슷한 초기화 작업을 수행하기 때문에 생성자에서 다른 생성자를 호출하는 경우가 많다. this() 라는 예약어 사용 메소드 시그너처를 보고 적당한 생성자를 호출

8 1. 생성자 생성자 예제 1-1 import java.util.Scanner; class Date {
DateTest.java import java.util.Scanner; class Date { private int year; private String month; private int day; public Date() { // 기본 생성자 month = "1월"; day = 1; year = 2009; } public Date(int year, String month, int day) { // 생성자 setDate(year, month, day);

9 1. 생성자 생성자 예제 1-2 public Date(int year) { // 생성자
DateTest.java public Date(int year) { // 생성자 setDate(year, "1월", 1); } public void setDate(int year, String month, int day) { this.month = month; // this는 현재 객체를 가리킨다. this.day = day; this.year = year; public class DateTest { public static void main(String[] args) { Date date1 = new Date(2009, "3월", 2); // Date date2 = new Date(2010); // Date date3 = new Date(); //

10 1. 생성자 생성자 예제 2-1 class Time { private int hour; // 0 – 23
TimeTest.java class Time { private int hour; // 0 – 23 private int minute; // 0 – 59 private int second; // 0 – 59 public Time() { // 첫 번째 생성자 this(0, 0, 0); } public Time(int h, int m, int s) { // 두 번째 생성자 setTime(h, m, s); public void setTime(int h, int m, int s) { // 시간 설정 함수 hour = ((h >= 0 && h < 24) ? h : 0); // 시간 검증 minute = ((m >= 0 && m < 60) ? m : 0); // 분 검증 second = ((s >= 0 && s < 60) ? s : 0); // 초 검증 public String toString() { // “시:분:초”의 형식으로 출력 return String.format("%02d:%02d:%02d", hour, minute, second);

11 1. 생성자 생성자 예제 2-2 public class TimeTest {
TimeTest.java public class TimeTest { public static void main(String args[]) { Time time = new Time(); // Time 객체를 생성하고 초기화한다. System.out.print("기본 생성자 호출 후 시간: "); System.out.println(time.toString()); Time time2 = new Time(13, 27, 6); // 두 번째 생성자 호출 System.out.print("두번째 생성자 호출 후 시간: "); System.out.println(time2.toString()); Time time3 = new Time(99, 66, 77); // 올바르지 않은 시간으로 설정해본다. System.out.print("올바르지 않은 시간 설정 후 시간: "); System.out.println(time3.toString()); }

12 1. 생성자 생성자 예제 3-1 class Point { public int x; public int y; // 생성자
CircleTest.java class Point { public int x; public int y; // 생성자 public Point(int a, int b) { x = a; y = b; } class Circle { public int radius = 0; public Point center; // Point 참조 변수가 필드로 선언 // 생성자 public Circle() { center = new Point(0, 0); } public Circle(int r) { radius = r; public Circle(Point p, int r) { center = p;

13 1. 생성자 생성자 예제 3-2 생각해보기 public class CircleTest {
225p Q&A의 3번째 질문 생성자 정의 없이… 인스턴스 변수 선언시 초기화를 하면 생성되는 모든 객체의 초기 인스턴스 변수값들은 동일하다. CircleTest.java public class CircleTest { public static void main(String args[]) { // Circle 객체를 생성하고 초기화한다. Point p = new Point(25, 78); Circle c = new Circle(p, 10); }

14 1. 생성자 생성자 예제 4 (Thinking on Java) class Tag { Tag(int marker) {
OrderOfInitialization.java class Tag { Tag(int marker) { System.out.println("Tag(" + marker + ")"); } class Card { Tag t1 = new Tag(1); Card() { System.out.println("Card()"); t3 = new Tag(33); Tag t2 = new Tag(2); void f() { System.out.println("f()"); Tag t3 = new Tag(3); public class OrderOfInitialization { public static void main(String[] args) { Card t = new Card(); t.f(); }

15 2. 정적 변수와 정적 메소드 인스턴스 변수 (Instance Variable) 정적 변수 (Static Variable)
클래스에서 필드로 선언된 일반적인 변수 각각의 객체들마다 별도로 각 변수들이 생성됨 정적 변수 (Static Variable) 클래스 변수(Class Variable) 모든 객체들에게 공통적인 변수 메모리에 로드된 클래스에 존재하여 모든 객체들이 공유함 필드 선언 앞에 static 키워드 사용하여 정적 변수 선언 static 키워드는 필드에만 사용가능하며 지역변수에는 사용못함

16 2. 정적 변수와 정적 메소드 정적 변수 (Static Variable) 정의 예
자동차 객체마다 시리얼 번호 (ID)를 붙이려면 객체가 몇 개나 생성되었는지를 알아야 한다.

17 2. 정적 변수와 정적 메소드 정적 변수 (Static Variable) 접근 방법
만약 정적 변수가 public 으로 지정되어 있다면 main() 함수가 있는 CarTest 클래스 내부에서 다음과 같이 접근 가능 즉, 객체로 부터 접근이 아니라 클래스명으로 접근 심지어는 객체를 생성하지 않고도 접근 가능 하지만, 앞선 예에서 numberOfCars 는 private이므로 다른 클래스에서 위와 같이 접근 불가 int n = Car.numberOfCars;

18 2. 정적 변수와 정적 메소드 정적 메소드 (Static Method) 정적 메소드 활용 예
클래스 메소드 (Class Method) 메소드 앞에 static 이 붙음 클래스 이름을 통해서 호출함 정적 메소드를 호출하기 위하여 객체 생성 필요 없음 정적 메소드 활용 예 Math 클래스의 대부분의 메소드 main() 메소드 자바 가상 기계가 객체를 생성할 필요 없이 main() 메소드 호출 가능 double value = Math.sqrt(9.0);

19 2. 정적 변수와 정적 메소드 정적 메소드 (Static Method) 정의 예

20 2. 정적 변수와 정적 메소드 정적 메소드 (Static Method) 사용시 주의점
정적 메소드는 객체의 생성 유무와 관계없이 호출됨을 기억!!! 정적 메소드에서 인스턴스 변수 접근 불가 정적 메소드에서 인스턴스 메소드 호출 불가 public static int getSpeed () { return speed; // 컴파일 오류 } public class Test { public static void main(String[] args) { add(10,20); // 컴파일 오류 } int add(int x, int y) { return x+y; public class Test { public static void main(String[] args) { add(10,20); } static int add(int x, int y) { return x+y;

21 2. 정적 변수와 정적 메소드 상수 정적 변수는 모든 객체가 공유하여 사용하며 상수도 비슷하게 많은 객체들이 공유하며 사용함.
그러므로 final 키워드를 통해 상수를 만들 때 보통 static 도 함께 붙임 객체마다 상수가 만들어지지 않고 클래스에만 존재하므로 공간 절약 효과를 볼 수 있음

22 2. 정적 변수와 정적 메소드 정적 변수와 정적 메소드 예제 EmployeeTest.java
import java.util.*; class Employee { private String name; private double salary; private static int count = 0; // 정적 변수 public Employee(String n, double s) { // 생성자 name = n; salary = s; count++; // 정적 변수인 count를 증가 } protected void finalize() {// 객체가 소멸될 때 호출된다. count--; // 직원이 하나 줄어드는 것이므로 count를 하나 감소 public static int getCount() { // 정적 메소드 return count;

23 2. 정적 변수와 정적 메소드 정적 변수와 정적 메소드 예제 EmployeeTest.java
public class EmployeeTest { public static void main(String[] args) { Employee e1,e2,e3; e1 = new Employee("김철수", 35000); e2 = new Employee("최수철", 50000); e3 = new Employee("김철호", 20000); int n = Employee.getCount(); System.out.println("현재의 직원수=" + n); }

24 2. 정적 변수와 정적 메소드 정적 변수 초기화 시기 예제 – 1 (Thinking on Java)
StaticInitialization.java class Bowl { Bowl(int marker) { System.out.println("Bowl(" + marker + ")"); } void f(int marker) { System.out.println("f(" + marker + ")"); class Table { static Bowl b1 = new Bowl(1); Table() { System.out.println("Table()"); b2.f(1); void f2(int marker) { System.out.println("f2(" + marker + ")"); static Bowl b2 = new Bowl(2); class Cupboard { Bowl b3 = new Bowl(3); static Bowl b4 = new Bowl(4); Cupboard() { System.out.println("Cupboard()"); b4.f(2); } void f3(int marker) { System.out.println("f3(" + marker + ")"); static Bowl b5 = new Bowl(5);

25 2. 정적 변수와 정적 메소드 정적 변수 초기화 시기 예제 – 2 (Thinking on Java)
StaticInitialization.java [출력결과] Bowl(1) Bowl(2) Table() f(1) Bowl(4) Bowl(5) Bowl(3) Cupboard() f(2) main 1 main 2 f2(1) f3(1) public class StaticInitialization { public static void main(String[] args) { System.out.println("main 1"); new Cupboard(); System.out.println("main 2"); t2.f2(1); t3.f3(1); } static Table t2 = new Table(); static Cupboard t3 = new Cupboard(); static Cupboard t4 = new Cupboard(); 1) 정적 변수는 클래스가 사용됨과 동시에 초기화가 이루어짐!!! 2) 정적 변수는 최초에 한번만 초기화됨

26 2. 정적 변수와 정적 메소드 static 블록으로 초기화하기 1 (Thinking on Java)
ExplicitStatic.java class Cup { Cup(int marker) { System.out.println("Cup(" + marker + ")"); } void f(int marker) { System.out.println("f(" + marker + ")"); class Cups { static Cup c1; static Cup c2; static { c1 = new Cup(1); c2 = new Cup(2); Cups() { System.out.println("Cups()"); public class ExplicitStatic { public static void main(String[] args) { System.out.println("Inside main()"); Cups.c1.f(99); // (1) } static Cups x = new Cups(); // (2) static Cups y = new Cups(); // (2) [출력결과] Cup(1) Cup(2) Cups() Inside main() f(99)

27 2. 정적 변수와 정적 메소드 static 블록으로 초기화하기 2 (Thinking on Java)
이전 예제 StaticInitialization.java 을 다음과 같이 수정해 컴파일하고 수행해보자. StaticInitialization.java public class StaticInitialization { public static void main(String[] args) { System.out.println("main 1"); new Cupboard(); System.out.println("main 2"); t2.f2(1); t3.f3(1); } static Table t2 = new Table(); static {System.out.println("--");} static Cupboard t3 = new Cupboard(); static Cupboard t4 = new Cupboard();

28 3. 접근 제어 접근 제어 (Access Control) 접근 제어의 두 가지 수준
임의의 클래스가 다른 클래스 또는 특정한 필드나 메소드에 접근하는 것을 제어하는 것 접근 제어의 두 가지 수준 클래스 수준에서의 접근 제어 임의의 클래스를 다른 패키지의 클래스가 사용하게 하거나 못하게 하는 것 public package (none) 멤버 수준에서의 접근 제어 필드나 메소드를 다른 클래스에서 사용하게 하거나 못하게 하는 것 protected  11장 private

29 3. 접근 제어 클래스 수준에서의 접근 제어 public package (수식자가 없을 때)
같은 패키지 내뿐만 아니라 서로 다른 패키지의 모든 클래스까지도 사용할 수 있는 공용 클래스 package (수식자가 없을 때) 같은 패키지 안에 있는 클래스들만이 사용 public class myClass { } class myClass { }

30 3. 접근 제어 클래스 수준에서의 접근 제어 예제 (1/2)
우선 클래스들을 모아둘 기본 폴더 (d:\MyClasses)를 정하고 그 폴더를 클래스 경로에 다음과 같이 추가한다. 다음의 소스를 컴파일하여 Cookie.class를 위 기본 클래스 경로 밑으로 두자. .java의 경로  d:\java\학번 컴파일 명령어  javac –d d:\MyClasses Cookie.java set CLASSPATH=$CLASSPATH$;d:\MyClasses package access.dessert; public class Cookie { public Cookie() { System.out.println("Cookie constructor"); } void bite() { System.out.println("bite"); Cookie.java

31 3. 접근 제어 클래스 수준에서의 접근 제어 예제 (2/2)
다음의 소스를 컴파일하여 Dinner.class를 기본 클래스 경로 밑으로 두자. .java의 경로  d:\java\학번 컴파일 명령어  javac –d d:\MyClasses Dinner.java 실행 명령어  java Dinner 앞선 Cookie.java에서 class 앞에 public 키워드를 지우고 Cookie.java와 Dinner.java를 모두 컴파일 해보자. Dinner.java에서 x.bite() 앞의 주석 기호를 없에고 컴파일해보자. 에러가 나는 이유는? import access.dessert.*; public class Dinner { public static void main(String[] args) { Cookie x = new Cookie(); // x.bite(); } Dinner.java

32 3. 접근 제어 멤버 수준에서의 접근 제어 일반적인 접근 제어 설정 방법 패키지 멤버
같은 패키지 내에서의 접근만을 허락할 때에는 접근 제어자를 설정하지 않는다. 일반적인 접근 제어 설정 방법 정적 변수, 인스턴스 변수에 대해서는 특별한 이유가 없으면 private으로 설정 일반적으로 상수는 public 으로 설정 정적 메소드, 인스턴스 메소드에 대해서는 사용자가 설

33 3. 접근 제어 멤버 수준에서의 접근 제어 예제 1 (1/2)

34 3. 접근 제어 멤버 수준에서의 접근 제어 예제 1 (2/2)

35 3. 접근 제어 멤버 수준에서의 접근 제어 예제 2 IceCream.java class Sundae {
private static Sundae s = new Sundae(); private Sundae() { } static Sundae getSundae() { return s; } void bite() { System.out.println("bite"); public class IceCream { public static void main(String[] args) { // Sundae s = new Sundae(); Sundae s = Sundae.getSundae(); s.bite(); [Singletone 패턴] 하나의 객체만 생성되게끔 해줌

36 4. this 참조 this 참조의 의미 this와 static 자기 자신의 객체
정적인 레벨에서는 의미가 없고 사용될 수도 없음 this와 static this 키워드는 현재 객체라는 동적인 의미를 갖는 반면에 static은 정적인 의미 따라서 메소드를 static으로 지정한다는 것은 그 메소드 내에서 this 키워드를 사용할 수 없음을 의미

37 4. this 참조 사용 용도 1) 필드의 이름과 매개 변수의 이름을 구별하기 위하여
2) 메소드 몸체에서 필드나 메소드 접근 시에 자신의 멤버 변수 또는 멤버 메소드 접근을 좀 더 확실히 하기 위해 3) 생성자 자체를 호출할 때 4) 자신 객체의 참조값을 넘겨야 할 경우 public void setSpeed(int speed) { this.speed = speed; } public Time(int h, int m, int s) { this.setTime(h, m, s); } this(10, 20); System.out.println(this);

38 4. this 참조 this 사용 예제 1 - pp. 235~236 this 사용 예제 2 Leaf.java
public class Leaf { int i = 0; Leaf increment() { i++; return this; } void print() { System.out.println("i=" + i); public static void main(String[] args) { Leaf x = new Leaf(); x.increment().increment().increment().print();

39 4. this 참조 this 사용 예제 3-1 public class Flower { int petalCount = 0;
Flower.java public class Flower { int petalCount = 0; String s = new String("null"); Flower(int petals) { petalCount = petals; System.out.println("Constructor w/ int arg only, petalCount= " + petalCount); } Flower(String ss) { System.out.println("Constructor w/ String arg only, s=" + ss); s = ss; Flower(String s, int petals) { this(petals); //! this(s); // Can't call two! this.s = s; // Another use of "this" System.out.println("String & int args");

40 4. this 참조 this 사용 예제 3-2 Flower() { this("hi", 47);
Flower.java Flower() { this("hi", 47); System.out.println("default constructor (no args)"); } void print() { //! this(11); // Not inside non-constructor! System.out.println("petalCount = " + petalCount + " s = "+ s); public static void main(String[] args) { Flower x = new Flower(); x.print();

41 5. 클래스와 클래스의 관계 3가지의 클래스와 클래스 관계 사용 (use) 관계
집합(has-a): 하나의 클래스가 다른 클래스를 포함한다. 상속(is-a): 하나의 클래스가 다른 클래스를 상속한다 (11장). 사용 (use) 관계 클래스 A의 메소드에서 클래스 B의 객체를 만들어 이 객체의 메소드를 호출 자기 자신 클래스를 사용하는 경우도 매우 흔하다.

42 5. 클래스와 클래스의 관계 사용 관계 예제 (1/2) Complex.java public class Complex {
private double real; private double imag; public Complex(double r, double i) { real = r; imag = i; } double getReal() { return real; double getImag() { return imag; public Complex add(Complex c) { // 객체 참조를 매개 변수로 받는다. double resultReal = real + c.getReal(); double resultImag = real + c.getImag(); return new Complex(resultReal, resultImag);

43 5. 클래스와 클래스의 관계 사용 관계 예제 (2/2) ComplexTest.java
public class ComplexTest { public static void main(String[] args) { Complex c1 = new Complex(10, 10); Complex c2 = new Complex(20, 20); Complex c3 = c1.add(c2); System.out.println(c3.getReal() + ", " + c3.getImag()); Complex c4 = new Complex(15, 15); Complex c5 = c1.add(c2).add(c3).add(c4); System.out.println(c5.getReal() + ", " + c5.getImag()); }

44 5. 클래스와 클래스의 관계 집합 (has-a) 관계 집합 관계 예제 (1/2)
클래스를 정의할 때 다른 클래스를 자신의 멤버 변수의 타입으로 활용하는 경우 즉, 임의의 클래스가 다른 클래스의 객체 참조를 멤버로 지님을 뜻함 집합 관계 예제 (1/2) AlarmClockTest.java class Time { private int time; private int minute; private int second; public Time(int t, int m, int s) { time = t; minute = m; second = s; } public String toString() { return time + ":" + minute + ":" + second;

45 5. 클래스와 클래스의 관계 집합 관계 예제 (2/2) AlarmClockTest.java class AlarmClock {
private Time currentTime; private Time alarmTime; public AlarmClock(Time a, Time c) { alarmTime = a; currentTime = c; } public String toString() { return "Current Time: " + currentTime + ", Alarm Time: " + alarmTime; public class AlarmClockTest { public static void main(String args[]) { Time alarm = new Time(6, 0, 0); Time current = new Time(12, 56, 34); AlarmClock c = new AlarmClock(alarm, current); System.out.println(c);


Download ppt "[INA470] Java Programming Youn-Hee Han"

Similar presentations


Ads by Google