본문 바로가기
들은 강의

[생활코딩 자바2] - 3. JAVA 객체지향 프로그래밍(클래스, 인스턴스, static, this)

by hotdog7778 2023. 6. 6.

쉽게 배우는 자바2[생활코딩] - 공부 기록

해당 강의는 https://www.boostcourse.org/cs128 에서 무료로 수강 할 수 있다.


 

1. 수업소개

들어가기 전에

객체 지향 프로그래밍은 왜 나왔을까요? 어떤 개념일까요?

이번 시간에는 객체 지향 프로그래밍이 무엇인지 간략한 인상을 들어 봅니다.

학습 목표

객체 지향 프로그래밍의 기본 개념을 들어 봅니다.

핵심 단어

  • 객체 지향 프로그래밍

 

2. 남의 클래스 남의 인스턴스

들어가기 전에

클래스와 인스턴스라고 하는 것이 낯설 수 있지만

우리는 이미 많이 사용해 왔습니다.

이번 시간에는 이미 만들어져 있는 클래스와 인스턴스를 이용하면서

클래스와 인스턴스에 접근해 봅시다.

학습 목표

클래스와 인스턴스를 실제로 활용하여 개념을 익혀 봅니다.

핵심 단어

  • 클래스
  • 인스턴스

강의내용

클래스를 복제해서 제어한다.

import java.io.FileWriter;
import java.io.IOException;

public class OthersOOP {

	public static void main(String[] args) throws IOException {

		// class인것 : System, Math, FileWriter
		// instance인것 : f1, f2
		
		System.out.println(Math.PI);
		System.out.println(Math.floor(1.8)); // 내림
		System.out.println(Math.ceil(1.8)); // 올림

		FileWriter f1 = new FileWriter("data.txt"); 
		// new로 인해서 뒤에 따라오는 파일라이터라는 클래스는 
		// data.txt에다가 파일을 저장하겠다 라는 상태를 가진 
		// 파일라이터클래스의 복제본을 f1 이라하고
		// f1 데이터타입은 클래스 이름인 파일라이터가 된다.
		f1.write("Hello");
		f1.write(" Java");
		f1.close();
		
		FileWriter f2 = new FileWriter("data2.txt");
		f2.write("Hello");
		f2.write(" Java");
		f2.close();

	}

}

 

 

 

3. 변수와 메소드

들어가기 전에

지난 시간에는 이미 사용해 보았던 Java API에 포함되어 있는

Math와 FileWriter 클래스와 인스턴스를 이용해 보았습니다.

이번 시간에는 지난 시간에 만들었던 프로그램을 클래스를 이용해서

정리정돈하는 방법을 알아봅니다.

학습 목표

실습 예제를 통해 클래스를 구현하고 사용 방법을 익혀 봅니다.

핵심 단어

  • 클래스

강의 내용

클래스 만들기

이번 시간에는 지난 시간에 만들었던 구분자와 텍스트를 입력하는 프로그램을

클래스를 만들어서 정리정돈하여 봅니다.

public class MyOOP {

	public static void main(String[] args) {

		System.out.println("----");
		System.out.println("A");
		System.out.println("A");

		System.out.println("----");
		System.out.println("A");
		System.out.println("A");
	}

}

이런 프로그램에서 중복되는 작업을 메소드로 추출해서 만들면 다음과 같이 될 것입니다.

public class MyOOP {

	public static void main(String[] args) {

		printA();

		printA();
	}

	public static void printA() {
		System.out.println("----");
		System.out.println("A");
		System.out.println("A");
	}

}

만약에 다른 텍스트를 출력하고 싶다면 새로 메소드를 만들 수도 있습니다.

public class MyOOP {

	public static void main(String[] args) {

		printA();
		printA();

		printB();
		printB();
	}

	public static void printA() {
		System.out.println("----");
		System.out.println("A");
		System.out.println("A");
	}
	public static void printB() {
		System.out.println("----");
		System.out.println("B");
		System.out.println("B");
	}
}

구분자를 파라미터로 주어 실행할 때마다 원하는 구분자로 출력하려면 다음과 같이 고칠 수 있습니다.

public class MyOOP {

	public static void main(String[] args) {
		String delimiter = "----";
		printA(delimiter);
		printA(delimiter);
		printB(delimiter);
		printB(delimiter);

		delimiter = "****";
		printA(delimiter);
		printA(delimiter);
		printB(delimiter);
		printB(delimiter);
	}

	public static void printA(String delimiter) {
		System.out.println(delimiter);
		System.out.println("A");
		System.out.println("A");
	}
	public static void printB(String delimiter) {
		System.out.println(delimiter);
		System.out.println("B");
		System.out.println("B");
	}
}

이것을 또 구분자를 클래스의 변수로 추출한다면 다음과 같이 간략하게 만들 수 있습니다.

public class MyOOP {
	public static String delimiter = "";

	public static void main(String[] args) {
		delimiter = "----";
		printA();
		printA();
		printB();
		printB();

		delimiter = "****";
		printA();
		printA();
		printB();
		printB();
	}

	public static void printA() {
		System.out.println(delimiter);
		System.out.println("A");
		System.out.println("A");
	}
	public static void printB() {
		System.out.println(delimiter);
		System.out.println("B");
		System.out.println("B");
	}
}

출력과 관련된 모든 기능들을 하나의 클래스로 분리해서 정리정돈할 수 있지 않을까요?

클래스로 따로 떼어 다음과 같이 만들 수 있습니다.

class Print {
	public static String delimiter = "";
	public static void printA() {
		System.out.println(delimiter);
		System.out.println("A");
		System.out.println("A");
	}
	public static void printB() {
		System.out.println(delimiter);
		System.out.println("B");
		System.out.println("B");
	}
	public static void printAll() {
		printA();
		printA();
		printB();
		printB();
	}
}
public class MyOOP {

	public static void main(String[] args) {
		Print.delimiter = "----";
		Print.printAll();

		Print.delimiter = "****";
		Print.printAll();
	}
}

 

 

 

4-1. 클래스 (존재 이유와 기본형식)

들어가기 전에

지난 시간에 메소드를 이용해서 코드를 정리하고

더 나아가서 클래스로 분리하여 만드는 것도 진행했습니다.

클래스로 분리하게 되면 어떤 장점이 있었나요?

클래스를 이용하면 어떤 장점이 있는지를 정리해 보도록 합니다.

학습 목표

클래스를 사용하는 장점에 대해서 파악해 봅니다.

핵심 단어

  • 클래스

강의 내용

// 전에 공부한 코드를 클래스로 묶어 정리.

class Print{
	public static String delimiter = "";
	public static void A() {
		System.out.println(delimiter);
		System.out.println("A");
		System.out.println("A");
	}
	
	public static void B() {
		System.out.println(delimiter);
		System.out.println("B");
		System.out.println("B");
	}
}

public class MyOOP {

	public static void main(String[] args) {
		Print.delimiter = "----"; 
		Print.A();
		Print.A();
		Print.B();
		Print.B();
		
		Print.delimiter = "****";
		Print.A();
		Print.A();
		Print.B();
		Print.B();
	}
}

 

 

4-2. 클래스 (형식)

들어가기 전에

이번 시간에는 클래스의 형식에 대해서 알아보도록 합니다.

학습 목표

자바에서 클래스의 형식이 어떻게 구성되어 있는지 알아봅니다.

핵심 단어

  • 클래스

강의 내용

  • 한 java파일에 class가 여러개 있으면 컴파일 후에 .class 파일이 여러개 생김
  • 그래서 다른 class를 다른 파일에 관리할 수 있음.
  • 이클립스 리팩터에 무브 기능을 사용해서 위의 일련을 작업을 할수있다.

 

 

5. 인스턴스

들어가기 전에

클래스에 대해서는 대략 알게 되었는데, 인스턴스는 도대체 무엇일까요

인스턴스에 대해서 실습을 통해 좀 더 알아보도록 합니다.

학습 목표

기존 프로그램의 클래스로 인스턴스로 만들어 봅니다.

핵심 단어

  • 인스턴스

강의 내용

기존 코드

변경코드 (인스턴스를 활용해서 중복제거)

public class MyOOP {

	public static void main(String[] args) {
		Print p1 = new Print();
		p1.delimiter = "----"; // Print class에 정의 되어있는 delimiter의 선언에서 static을 빼줘야 한다.
		p1.A(); // Print class에 정의 되어있는 A의 선언에서 static을 빼줘야 한다.
		p1.A();
		p1.B(); // Print class에 정의 되어있는 B의 선언에서 static을 빼줘야 한다.
		p1.B();
		
		Print p2 = new Print();
		p2.delimiter = "****";
		p2.A();
		p2.A();
		p2.B();
		p2.B();
		
		// ---- 구분자를 쓰고싶으면
		p1.A();
		// **** 구분자를 쓰고싶으면
		p2.A();
		
	}

}
class Print {
		public String delimiter = "";
		public void A() {
			System.out.println(delimiter);
			System.out.println("A");
			System.out.println("A");
		}
		
		public void B() {
			System.out.println(delimiter);
			System.out.println("B");
			System.out.println("B");
		}
}

 

 

6. static

들어가기 전에

static은 무엇일까요. 클래스 소속이라는 것을 알려주는 것이라고 하는데

그럼 무슨 특징이 있는 것일까요?

간단한 예제를 통해 static 변수와 메소드의 특성을 알아봅니다.

학습 목표

static 변수와 메소드에 대해 알아봅니다.

핵심 단어

  • static

강의 내용

static 메소드에서

  • static 변수 사용가능
  • static이 아닌 변수(인스턴스 변수) 사용 불가능

실험실. 클래스를 통해서 인스턴스 변수, 인스턴스 메소드를 사용할 수 없다.

class Foo{
	// 두개의 변수 생성. 하나는 static, 하나는 X
	public static String classVar = "I class var";
	public String instanceVar = "I instance var";

	// 두개의 메소드 생성
	// static 메소드
	public static void classMethod() {
		// static 에서 메소드의 경우 static이 아닌 변수는 사용이 불가능한게 보임
		System.out.println(classVar);
//		System.out.println(instanceVar); //Error
	}
	// static이 아닌 메소드에서는 둘다 사용이 가능한게 보임
	public void instanceMethod( ) {
		System.out.println(classVar);
		System.out.println(instanceVar);
	}
}

public class StaticApp {

	public static void main(String[] args) {

		// 둘다 Foo라는 클래스의 변수지만 static이 아닌 Foo.instanceVar는 사용이 불가능한게 보임
		System.out.println(Foo.classVar); // OK
//		System.out.println(Foo.instanceVar); // Error
		
		// static이 아닌 메소드는 사용이 불가능한걸 확인 가능
		Foo.classMethod();
//		Foo.instanceMethod(); //Error
		
		Foo f1 = new Foo();
		Foo f2 = new Foo();
		
//      
        System.out.println(f1.classVar); // I class var
        System.out.println(f1.instanceVar); // I instance var
//      
        f1.classVar = "changed by f1";
        System.out.println(Foo.classVar); // changed by f1
        System.out.println(f2.classVar);  // changed by f1
//      
        f1.instanceVar = "changed by f1";
        System.out.println(f1.instanceVar); // changed by f1
        System.out.println(f2.instanceVar); // I instance var
	}
}

인스턴스에서 static 변수를 바꾸면 class에서도 바뀐다,

인스턴스에서 static이 아닌 변수를 바꿔도 class에서는 안바뀐다.

인스턴스에서 static 메소드를 바꾸면 class에서도 바뀐다,

인스턴스에서 static이 아닌 메소드를 바꿔도 class에서는 안바뀐다.

 

 

7. 생성자와 this

들어가기 전에

우리는 변수를 새로 만들 경우 선언과 함께 초기화를 진행합니다.

인스턴스도 마찬가지로 선언을 하고 초기화를 할 수 있을까요?

이번 시간에는 인스턴스의 초기화를 하는 생성자에 대해 알아봅니다.

학습 목표

클래스의 생성자와 this 예약어에 대해 알아봅니다.

핵심 단어

  • 생성자
  • this (인스턴스를 가리키는 예약어)

강의 내용

생성자는 클래스와 동일한 이름의 메소드?

Print()와 같이 아무것도 지정하지 않는 생성자를 기본 생성자라고 합니다.

print p1 = new Print(); // 프린트 인스턴스 생성

////////

class Print {  // 프린트 클래스
	public Print() {  // 프린트 메소드
}

인스턴스를 생성할 때 자바는 클래스와 동일한 이름의 메소드가 있다면 그 메소드를 호출하도록 되어있음.

public class MyOOP {

	public static void main(String[] args) {
		Print p1 = new Print("----");
	}

}

class Print {

//this를 안사용할때
	public String delimiter = "";
	public Print(String _delimeter) {
		delimiter = _delimeter;
	}

//this를 사용할 때
	public String delimiter = "";
	public Print(String delimeter) { // 매개변수 delimeter 와 변수 delimeter의 이름이 같음
		this.delimeter = delimeter; // this 뒤의 delimeter는. 생성한 인스턴스의 delimeter변수
		// 생성한 인스턴스의 delimeter 변수는 매개변수로 받은 delimeter 이다. 라는의미
	}
	public void A() {
		System.out.println(delimiter);
		System.out.println("A");
		System.out.println("A");
	}
	
	public void B() {
		System.out.println(delimiter);
		System.out.println("B");
		System.out.println("B");
	}
}

 

 

 

8-1. 활용 (클래스화)

들어가기 전에

지금까지 배워온 클래스와 인스턴스에 대한 내용을 바탕으로

이번 시간에는 실전 문제를 클래스와 인스턴스를 이용해서 풀어 봅시다.

학습 목표

클래스와 인스턴스를 이용하여 실질적인 우리의 문제를 풀어 봅니다.

핵심 단어

  • 클래스
  • 인스턴스

강의 내용

어카운팅에 클래스를 따로 모아서 어카운팅앱에 사용하기에 코드를보고 용도를 파악하기 쉽고 정리되어있는 느낌으로 바꿔보자

// Before

public class AccountingApp {
	public static double valueOfSupply = 10000.0; // 전역변수
	public static double vatRate = 0.1; // 전역변수
	public static double getVAT() {
		return valueOfSupply * vatRate;
	}
	public static double getTotal() {
		return valueOfSupply + getVAT();
	}
	public static void main(String[] args) {
		System.out.println("Value of supply : " + valueOfSupply);
		System.out.println("VAT : " + getVAT());
		System.out.println("Total : " + getTotal());
	}

}
// After
class Accounting{
	public static double valueOfSupply; // 전역변수
	public static double vatRate = 0.1; // 전역변수
	public static double getVAT() {
		return valueOfSupply * vatRate;
	}
	public static double getTotal() {
		return valueOfSupply + getVAT();
	}
}

public class AccountingApp {
	// .. 다른종류의 코드가 여러개 있다고 상상

	// ..
	public static void main(String[] args) {
		Accounting.valueOfSupply = 10000.0;
		System.out.println("Value of supply : " + Accounting.valueOfSupply);
		System.out.println("VAT : " + Accounting.getVAT());
		System.out.println("Total : " + Accounting.getTotal());
	} 
}

 

 

8-2. 활용 (인스턴스화)

들어가기 전에

지난 시간에 이어서 클래스만을 이용하지 않고 여러 상황의 문제를 처리할 수 있는

인스턴스를 이용해서 문제를 풀어 보도록 합니다.

학습 목표

인스턴스를 이용해서 문제를 풀어 봅니다.

핵심 단어

  • 인스턴스

강의 내용

클래스의 상태가 계속해서 변해야하는 코드라면. 인스턴스를 이용

// Before. 클래스화 되어있는 코드
class Accounting{
	public static double valueOfSupply; // 전역변수
	public static double vatRate = 0.1; // 전역변수
	public static double getVAT() {
		return valueOfSupply * vatRate;
	}
	public static double getTotal() {
		return valueOfSupply + getVAT();
	}
}

public class AccountingApp {
	public static void main(String[] args) {
		Accounting.valueOfSupply = 10000.0;
		System.out.println("Value of supply : " + Accounting.valueOfSupply);
		Accounting.valueOfSupply = 20000.0;
		System.out.println("Value of supply : " + Accounting.valueOfSupply);
		
		Accounting.valueOfSupply = 10000.0;
		System.out.println("VAT : " + Accounting.getVAT());
		Accounting.valueOfSupply = 20000.0;
		System.out.println("VAT : " + Accounting.getVAT());
		
		Accounting.valueOfSupply = 10000.0;
		System.out.println("Total : " + Accounting.getTotal());
		Accounting.valueOfSupply = 20000.0;
		System.out.println("Total : " + Accounting.getTotal());
	} 
}
// After 인스턴스화 해봄
class Accounting{
	public double valueOfSupply; // 전역변수
	public static double vatRate = 0.1; // 전역변수
	public double getVAT() {
		return valueOfSupply * vatRate;
	}
	public double getTotal() {
		return valueOfSupply + getVAT();
	}
}

public class AccountingApp {
	public static void main(String[] args) {
		Accounting a1 = new Accounting();
		a1.valueOfSupply = 10000.0;
		
		Accounting a2 = new Accounting();
		a2.valueOfSupply = 20000.0;
		
		System.out.println("Value of supply : " + a1.valueOfSupply);
		System.out.println("Value of supply : " + a2.valueOfSupply);
		
		System.out.println("VAT : " + a1.getVAT());
		System.out.println("VAT : " + a2.getVAT());
		
		System.out.println("Total : " + a1.getTotal());
		System.out.println("Total : " + a2.getTotal());
		
	} 
}
// After. 생성자를 사용해서 valueOfSupply 를 바꿔서 사용할 수 있게!
class Accounting{
	public double valueOfSupply; // 전역변수
	public Accounting(double valueOfSupply) {
		this.valueOfSupply = valueOfSupply;
	}
	public static double vatRate = 0.1; // 전역변수
	public double getVAT() {
		return valueOfSupply * vatRate;
	}
	public double getTotal() {
		return valueOfSupply + getVAT();
	}
}

public class AccountingApp {
	public static void main(String[] args) {
		Accounting a1 = new Accounting(10000.0);
		
		Accounting a2 = new Accounting(20000.0);
		
		System.out.println("Value of supply : " + a1.valueOfSupply);
		System.out.println("Value of supply : " + a2.valueOfSupply);
		
		System.out.println("VAT : " + a1.getVAT());
		System.out.println("VAT : " + a2.getVAT());
		
		System.out.println("Total : " + a1.getTotal());
		System.out.println("Total : " + a2.getTotal());
		
	} 
}

 

 

 

9. 수업을 마치며

다음에 도전해 볼 만한 내용

학습 목표

상속, 인터페이스에 대해서 알아 봅니다.

핵심 단어

  • 상속
  • 인터페이스

강의 내용

상속.

인터페이스.

패키지.