본문 바로가기

Java 웹 개발

21.09.01 - 웹 개발 입문 16일차

static 개요

객체 지향 : 모든 데이터를 객체 단위로 프로그래밍하기 위한 노력

 

<일반적인 내용>

클래스 : 객체가 가져야 할 정보에 대한 명세서

           이 클래스로 만들어진 객체에는 내부에 작성된 내용이 존재

           - 멤버변수(멤버필드) : 데이터 저장

           - 멤버메소드 : 기능(코드) 저장

           - 생성자 : 초기화 담당, 객체에는 포함되지 않음

객체 : 클래스를 new 연산으로 실제 프로그래밍에 구현한 데이터 좁은 의미로 instance라고도 부른다

 

<일반적이지 않은 내용>

final : 불변 처리

static : 탈 객체 지향 키워드

 

 

 

객체 지향으로 구현해보기

package oop.keyword3;

//계산기 클래스 : 덧셈 전용
public class PlusCalculator {
	// 멤버 변수
	private int left; // 필수
	private int right; // 필수

	// 멤버 메소드
	public void setLeft(int left) {
		this.left = left;
	}

	public void setRight(int right) {
		this.right = right;
	}

	public int getLeft() {
		return this.left;
	}

	public int getRight() {
		return this.right;
	}

	public int getTotal() {
		return this.left + this.right;
	}

	// 생성자
	public PlusCalculator(int left, int right) {
		this.setLeft(left);
		this.setRight(right);
	}
}
package oop.keyword3;

public class Test01 {

	public static void main(String[] args) {
		// 객체 생성
		PlusCalculator a = new PlusCalculator(10, 20);
		System.out.println(a.getTotal());

		PlusCalculator b = new PlusCalculator(100, 200);
		System.out.println(b.getTotal());

		// 문제점 : 굳이 이렇게까지..?
	}
}

더하기 한번 하려고 이렇게 까지 해야하나...?

 

 

 

뺄셈과 같은 단순한 1회성 계산에 객체까지 쓰려니까 너무 복잡하다
멤버변수, 멤버메소드 등을 구현하지 말고 1회용 메소드를 생성하자!

 

static 키워드가 붙은 대상은 "객체 없이" 접근이 가능하다.
다양한 형태로 활용이 가능하며
이 예제에서는 "단순한데 많이 사용하는 계산"을 객체 생성 없이 처리하도록 구현

package oop.keyword4;

//계산기 : 클래스 : 뺄셈 전용
public class MinusCalculator {
	
	public static int minus(int left, int right) {
		return left - right;
	}
}
package oop.keyword4;

public class Test01 {
	public static void main(String[] args) {

		System.out.println(MinusCalculator.minus(30, 20));
	}
}

 

 

Q. static 키워드를 사용해서 1회성 계산을 수행해보기

- `multiple` 이라는 이름의 메소드를 만들어 곱셈이 수행 가능하도록 구현
- `square` 라는 이름의 메소드를 만들어 제곱 연산이 가능하도록 구현
- `triangle` 이라는 이름의 메소드를 만들어 폭과 높이에 따른 삼각형 넓이 계산이 가능하도록 구현
- `circle` 이라는 이름의 메소드를 만들어 반지름에 따른 원의 넓이 계산이 가능하도록 구현
- `random` 이라는 이름의 메소드를 만들어 주어진 숫자 두 개 사이에서 랜덤한 값을 하나 추첨하도록 구현

package oop.keyword5;

public class Calculator {

	public static int multiple(int left, int right) {
		return left * right;
	}

	public static int square(int n) {
		return n * n;
	}

	public static int square(int n, int m) {
		int result = 1;
		for (int i = 0; i < m; i++) {
			result *= n;
		}
		return result;
	}

	public static float triangle(int width, int height) {
		int rect = width * height;
		float result = rect / 2f;
		return result;
	}

	public static float circle(int radius) {
		return 3.14f * radius * radius;
	}

	public static int random(int a, int b) {
		int n = b - a + 1;
		int number = (int) (Math.random() * n) + a;
		return number;
	}

}
package oop.keyword5;

public class Test01 {

	public static void main(String[] args) {
		System.out.println("곱셈 = " + Calculator.multiple(30, 20));
		System.out.println("제곱 = " + Calculator.square(3));
		System.out.println("제곱 = " + Calculator.square(3, 4));
		System.out.println("삼각형 넓이 = " + Calculator.triangle(30, 20));
		System.out.println("원의 넓이 = " + Calculator.circle(5));
		System.out.println("랜덤 = " + Calculator.random(10, 20));

	}

}

- 정답

곱셈 = 600
제곱 = 9
제곱 = 81
삼각형 넓이 = 300.0
원의 넓이 = 78.5
랜덤 = 20

 

 

 

Q. static 변수 예제

private String company; 

-> private static String company;

제조사(일괄 처리 데이터) 로 관리 할 수있다.

package oop.keyword8;

//자동차 클래스
public class Sonata {
	private static String company;// 제조사(일괄 처리 데이터)

	public static String getCompany() {
		return company;
	}

	public static void setCompany(String company) {
		Sonata.company = company;
	}

	private String color;// 색상
	private int price;// 가격

	public Sonata(String color, int price) {
		this.color = color;
		this.price = price;
	}

	@Override
	public String toString() {
		return "Sonata [company=" + company + ", color=" + color + ", price=" + price + "]";
	}

	public String getColor() {
		return color;
	}

	public void setColor(String color) {
		this.color = color;
	}

	public int getPrice() {
		return price;
	}

	public void setPrice(int price) {
		this.price = price;
	}

}
package oop.keyword8;

public class Test01 {
		public static void main(String[] args) {
			Sonata.setCompany("현대");

			Sonata a = new Sonata("블랙", 20000000);
			Sonata b = new Sonata("그레이", 20000000);
			Sonata c = new Sonata("레드", 19000000);

//			System.out.println(a.toString());
//			System.out.println(b.toString());
//			System.out.println(c.toString());

			System.out.println(a);
			System.out.println(b);
			System.out.println(c);
		}
}

 

 

 

Q. 다음 요구사항에 맞게 데이터 구현
요구사항
- 다음 데이터는 KH은행의 "내집마련 장기적금" 계좌에 대한 정보입니다.
- 모든 통장은 동일한 기본이율을 적용받습니다.
- 모든 통장의 잔액은 음수일 수 없습니다
- 모든 통장의 기본이율, 우대이율은 음수일 수 없습니다

이름 기본이율 우대이율 잔액
유재석 1.2 0.3 5000000
강호동 1.2 0.5 3500000
신동엽 1.2 0.2 8000000
package oop.keyword9;

public class Account {
	// 정적데이터 - static 변수
	private static float basicRate = 1.2f;

	public static void setBasicRate(float basicRate) {
		Account.basicRate = basicRate;
	}

	public static float getBasicRate() {
		return Account.basicRate;
	}

	// 동적데이터 - 멤버 변수
	private String name;
	private float advancedRate;
	private long balance;

	public String getName() {
		return name;
	}

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

	public float getAdvancedRate() {
		return advancedRate;
	}

	public void setAdvancedRate(float advancedRate) {
		this.advancedRate = advancedRate;
	}

	public long getBalance() {
		return balance;
	}

	public void setBalance(long balance) {
		this.balance = balance;
	}

	// 생성자 : static을 고려할 필요가 없다.
	public Account(String name) {
		this(name, 0f, 0L);
	}

	public Account(String name, float advancedRate) {
		this(name, advancedRate, 0L);
	}

	public Account(String name, float advancedRate, long balance) {
		this.setName(name);
		this.setAdvancedRate(advancedRate);
		this.setBalance(balance);
	}

	public void showInfo() {
		System.out.println("<계좌 정보>");
		System.out.println("소유자 : " + name); // this.name
		System.out.println("기본이율 : " + basicRate + "%"); // this.basicRate
		System.out.println("우대이율이율 : " + advancedRate + "%"); // this.advancedRate
		System.out.println("예금잔액 : " + balance); // this.balance

	}

	// 원한다면 부가적인 기능들을 얼마든지 추가할 수 있다.
	public void deposit(long money) { // 입금
		if (money <= 0) {
			return;
		}
		this.balance += money;
	}

	public void withdraw(long money) { // 출금
		if (this.balance < money) {
			return;
		}
		this.balance -= money;
	}
}
package oop.keyword9;

public class Test01 {
	public static void main(String[] args) {
		Account a = new Account("유재석", 0.3f, 5000000L);
		Account b = new Account("강호동", 0.5f, 3500000L);
		Account c = new Account("유재석", 0.2f, 8000000L);

		// Account.setBasicRate(1.3f); //static-way
		// a.setBasicRate(1.3f); //non static-way

		a.deposit(1000000L);// 100만원 입금(승인)
		b.withdraw(5000000L);// 500만원 출금(거절)
		c.withdraw(5000000L);// 500만원 출금(승인)

		a.showInfo();
		b.showInfo();
		c.showInfo();

	}
}

- 정답

<계좌 정보>
소유자 : 유재석
기본이율 : 1.2%
우대이율이율 : 0.3%
예금잔액 : 6000000
<계좌 정보>
소유자 : 강호동
기본이율 : 1.2%
우대이율이율 : 0.5%
예금잔액 : 3500000
<계좌 정보>
소유자 : 유재석
기본이율 : 1.2%
우대이율이율 : 0.2%
예금잔액 : 3000000

 

 

 

 

상수 (static final) 가 만들어지는 과정 알아보기

Q. 랜덤으로 가위바위보 중 하나를 출력
랜덤으로는 정수를 추첨할 수 있다.
문자열은 어떻게?

 

- 상수 없이 풀이

package oop.keyword10;

import java.util.Random;

public class Test01 {
	public static void main(String[] args) {

		Random r = new Random();
		int com = r.nextInt(3) + 1; // 1부터 3개

		// System.out.println("com = " + com);

		switch (com) {
		case 1:
			System.out.println("가위!");
			break;
		case 2:
			System.out.println("바위!");
			break;
		case 3:
			System.out.println("보!");
			break;
		}
	}
}

 

- final로 값이 안변하게 사용

package oop.keyword10;

import java.util.Random;

public class Test02 {
	public static void main(String[] args) {

		final int 가위 = 1;
		final int 바위 = 2;
		final int 보 = 3;

		Random r = new Random();
		int com = r.nextInt(3) + 1; // 1부터 3개

		// System.out.println("com = " + com);

		switch (com) {
		case 1:
			System.out.println("가위!");
			break;
		case 2:
			System.out.println("바위!");
			break;
		case 3:
			System.out.println("보!");
			break;
		}
	}
}

 

 

- 상수 (static final) 사용하기
static 아무데서나 객체없이 편리하게 클래스명으로 접근가능
final 변하지 않는 변수
객체 없이 편하게 접근할 수 있도록 정적 변수 처리
public static final 세트로 써야함

package oop.keyword10;

import java.util.Random;

public class Test03 {

	public static final int 가위 = 1;
	public static final int 바위 = 2;
	public static final int 보 = 3;

	public static void main(String[] args) {

		Random r = new Random();
		int com = r.nextInt(3) + 1; // 1부터 3개

		// System.out.println("com = " + com);

		switch (com) {
		case 가위:
			System.out.println("가위!");
			break;
		case 바위:
			System.out.println("바위!");
			break;
		case 보:
			System.out.println("보!");
			break;
		}
	}
}

 

- 최종

package oop.keyword10;

import java.util.Random;

public class Test04 {

	public static void main(String[] args) {

		Random r = new Random();
		int com = r.nextInt(RSP.RANGE) + RSP.START;

		// System.out.println("com = " + com);

		switch (com) {
		case RSP.SCISSORS:
			System.out.println("가위!");
			break;
		case RSP.ROCK:
			System.out.println("바위!");
			break;
		case RSP.PAPER:
			System.out.println("보!");
			break;
		}
	}
}
package oop.keyword10;

public class RSP {
	// 상수는 일반적으로 변수명을 대문자로 작성한다
	public static final int SCISSORS = 1;
	public static final int ROCK = 2;
	public static final int PAPER = 3;

	public static final int RANGE = 3;
	public static final int START = 1;

}

 

 

 

 

 

상속 그림으로 알아보기

Q. 상속이 없는 형태의 구조 예제

package oop.inherit1;

//갤럭시 클래스
public class Galaxy {
	// 멤버변수
	private String number;

	// 멤버 메소드
	public String getNumber() {
		return number;
	}

	public void setNumber(String number) {
		this.number = number;
	}

	public void call() {
		System.out.println("전화 기능 실행!");
	}
	public void sms() {
		System.out.println("문자 기능 실행!");
	}
	public void gallery() {
		System.out.println("갤러리 실행!");
	}
	public void samsungPay() {
		System.out.println("삼성페이 실행");
	}
	public void voiceRecord() {
		System.out.println("통화녹음 실행");
	}
}
package oop.inherit1;

//아이폰 클래스
public class IPhone {
	// 멤버 변수
	private String number;

	// 멤버 메소드
	public String getNumber() {
		return number;
	}

	public void setNumber(String number) {
		this.number = number;
	}

	public void call() {
		System.out.println("전화 기능 실행!");
	}
	public void sms() {
		System.out.println("문자 기능 실행!");
	}
	public void gallery() {
		System.out.println("갤러리 실행!");
	}
	public void itunes() {
		System.out.println("아이튠즈 실행");
	}
	public void siri() {
		System.out.println("음성인식 실행");
	}
}
package oop.inherit1;

public class Test01 {

	public static void main(String[] args) {
		// 갤럭시 생성 및 기능 실행
		Galaxy p1 = new Galaxy();
		p1.setNumber("010-1212-3434");
		System.out.println(p1.getNumber());
		p1.call();
		p1.sms();
		p1.gallery();
		p1.samsungPay();
		p1.voiceRecord();

		// 아이폰 생성 및 기능 실행
		IPhone p2 = new IPhone();
		p2.setNumber("010-1212-3434");
		System.out.println(p2.getNumber());
		p2.call();
		p2.sms();
		p2.gallery();
		p2.itunes();
		p2.siri();
	}

}

 

Q. 상속 적용한 예제

package oop.inherit2;

//휴대폰 클래스 : 휴대폰이라면 가져야할 공용 기능에 대해서 정의
public class Phone {
	//멤버 변수
	private String number;

	//멤버 메소드
	public String getNumber() {
		return number;
	}

	public void setNumber(String number) {
		this.number = number;
	}
	public void call() {
		System.out.println("전화 걸기!");
	}
	public void sms() {
		System.out.println("문자 전송!");
	}
	public void gallery() {
		System.out.println("갤러리 기능 실행!");
	}
}
package oop.inherit2;

//아이폰 클래스는 휴대폰 클래스의 모든 내용을 "상속"받고 시작한다
public class IPhone extends Phone {
	public void itunes() {
		System.out.println("아이튠즈 실행");
	}
	public void siri() {
		System.out.println("음성인식 실행");
	}
}
package oop.inherit2;

//갤럭시 클래스는 휴대폰 클래스의 모든 내용을 "상속"받고 시작한다
public class Galaxy extends Phone {
	public void samsungPay() {
		System.out.println("삼성페이 실행");
	}
	public void voiceRecord() {
		System.out.println("통화녹음 실행");
	}
}
package oop.inherit2;

public class Test01 {
	public static void main(String[] args) {
		//Galaxy 객체를 생성해서 기능 실행
		Galaxy p1 = new Galaxy();
		p1.setNumber("010-1212-3434");
		System.out.println(p1.getNumber());
		p1.call();
		p1.sms();
		p1.gallery();
		p1.samsungPay();
		p1.voiceRecord();

		
		//IPhone 객체를 생성해서 기능 실행
		IPhone p2 = new IPhone();
		p2.setNumber("010-1212-3434");
		System.out.println(p2.getNumber());
		p2.call();
		p2.sms();
		p2.gallery();
		p2.itunes();
		p2.siri();
	}
}

- 정답

010-1212-3434
전화 걸기!
문자 전송!
갤러리 기능 실행!
삼성페이 실행
통화녹음 실행
010-1212-3434
전화 걸기!
문자 전송!
갤러리 기능 실행!
아이튠즈 실행
음성인식 실행

 

 

 

Q. 다음 요구사항에 맞게 클래스 구조를 설계하고 객체 생성 후 기능 실행

요구사항
- 브라우저 들을 클래스로 구현(크롬, 엣지, 웨일)
- 각각의 브라우저들은 다음 데이터와 기능이 존재


- 크롬(Chrome) 브라우저
- 주소를 저장할 수 있어야 한다(url)
- 새로고침 기능이 존재해야 한다(refresh)
- 페이지 이동 기능이 존재해야 한다(move)
- 개발자 도구 기능이 존재해야 한다(develop)
- 크롬스토어 기능이 존재해야 한다(chromeStore)


- 엣지(Edge) 브라우저
- 주소를 저장할 수 있어야 한다(url)
- 새로고침 기능이 존재해야 한다(refresh)
- 페이지 이동 기능이 존재해야 한다(move)
- 전체화면 기능이 존재해야 한다(fullScreen)


- 웨일(Whale) 브라우저
- 주소를 저장할 수 있어야 한다(url)
- 새로고침 기능이 존재해야 한다(refresh)
- 페이지 이동 기능이 존재해야 한다(move)
- 파파고 번역 기능이 존재해야 한다(papago)
- 네이버 검색 기능이 존재해야 한다(naverSearch)
- 모든 기능들은 실행 시 간단한 텍스트 메세지가 출력되어야 한다
- 예를 들어 페이지 이동 기능을 실행하면 "페이지 이동 기능 실행"이라고 화면에 표시되면 된다

 

package oop.inherit3;

public class Browser {
	// 멤버 변수
	private String url;

	// 멤버 메소드
	public String getUrl() {
		return url;
	}

	public void setUrl(String url) {
		this.url = url;
	}

	public void refresh() {
		System.out.println("새로고침 기능 실행!");
	}

	public void move() {
		System.out.println("페이지 이동 기능 실행!");
	}

}
package oop.inherit3;

public class Chrome extends Browser {
	public void develop() {
		System.out.println("개발자 도구 기능 실행!");
	}

	public void chromeStore() {
		System.out.println("크롬 스토어 기능 실행!");
	}
}
package oop.inherit3;

public class Edge extends Browser {
	public void fullScreeen() {
		System.out.println("전체 화면 기능 실행!");
	}
}
package oop.inherit3;

public class Whale extends Browser{
	public void papago() {
		System.out.println("파파고 번역 기능 실행!");
	}
	public void naverSearch() {
		System.out.println("네이버 검색 기능 실행!");
	}
}
package oop.inherit3;

public class Test01 {

	public static void main(String[] args) {

		Chrome b1 = new Chrome();
		b1.setUrl("https://www.google.com");
		System.out.println(b1.getUrl());
		b1.refresh();
		b1.move();
		b1.develop();
		b1.chromeStore();

		Edge b2 = new Edge();
		b2.setUrl("https://www.google.com");
		System.out.println(b2.getUrl());
		b2.refresh();
		b2.move();
		b2.fullScreeen();

		Whale b3 = new Whale();
		b3.setUrl("https://www.google.com");
		System.out.println(b3.getUrl());
		b3.refresh();
		b3.move();
		b3.papago();
		b3.naverSearch();
	}

}

- 정답

https://www.google.com
새로고침 기능 실행!
페이지 이동 기능 실행!
개발자 도구 기능 실행!
크롬 스토어 기능 실행!


https://www.google.com
새로고침 기능 실행!
페이지 이동 기능 실행!
전체 화면 기능 실행!


https://www.google.com
새로고침 기능 실행!
페이지 이동 기능 실행!
파파고 번역 기능 실행!
네이버 검색 기능 실행!

 

 

 

Q. 과제

다음 요구사항에 맞게 클래스 구조를 설계하고 객체 생성 후 기능 실행

요구사항
- 각종 파일들을 유형별로 구현
MP3
- 파일명을 가지고 있어야 한다(fileName)
- 파일크기를 가지고 있어야 한다(fileSize)
- 재생시간을 초단위로 가지고 있어야 한다(duration)
- 실행 기능을 가지고 있어야 한다(execute)
- 빨리감기 기능을 가지고 있어야 한다(forward)
- 되감기 기능을 가지고 있어야 한다(rewind)
AVI
- 파일명을 가지고 있어야 한다(fileName)
- 파일크기를 가지고 있어야 한다(fileSize)
- 재생속도를 가지고 있어야 한다(speed)
- 실행 기능을 가지고 있어야 한다(execute)
- 빨리감기 기능을 가지고 있어야 한다(forward)
- 되감기 기능을 가지고 있어야 한다(rewind)
PPT
- 파일명을 가지고 있어야 한다(fileName)
- 파일크기를 가지고 있어야 한다(fileSize)
- 프레젠테이션 페이지 수를 가지고 있어야 한다(pageSize)
- 실행 기능을 가지고 있어야 한다(execute)
- 파일 정보 확인 기능을 가지고 있어야 한다(information)
- 모든 기능들은 실행 시 간단한 텍스트 메세지가 출력되어야 한다
- 예를 들어 MP3의 빨리감기 기능을 실행하면 "빨리감기 실행"과 같은 메세지가 출력되어야 한다.

 

 

package oop.inherit5;

public class File {

	private String fileName;
	private float fileSize;

	public String getFileName() {
		return fileName;
	}

	public void setFileName(String fileName) {
		this.fileName = fileName;
	}

	public float getFileSize() {
		return fileSize;
	}

	public void setFileSize(float fileSize) {
		if (fileSize < 0) {
			return;
		}
		this.fileSize = fileSize;
	}

	public void execute() {
		System.out.println("실행!");
	}

	public void forward() {
		System.out.println("빨리감기 기능 실행!");
	}

	public void rewind() {
		System.out.println("되감기 기능 실행!");
	}

}
package oop.inherit5;

public class MP3 extends File {

	private float duration;

	public float getDuration() {
		return duration;
	}

	public void setDuration(int duration) {
		if (duration < 0) {
			return;
		}
		this.duration = duration;
		System.out.println("재생 시간 = " + duration + "초");
	}

}
package oop.inherit5;

public class AVI extends File {

	private float speed;

	public float getSpeed() {
		return speed;
	}

	public void setSpeed(float speed) {
		if (speed < 0 || speed > 2) {
			return;
		}
		this.speed = speed;
	}

}
package oop.inherit5;

public class PPT extends File {

	private int pageSize;

	public int getPageSize() {
		return pageSize;
	}

	public void setPageSize(int pageSize) {
		if (pageSize < 0) {
			return;
		}
		this.pageSize = pageSize;
	}

	public void information() {
		System.out.println("<파일 정보 확인>");
	}

}
package oop.inherit5;

public class Test01 {
	public static void main(String[] args) {

		MP3 f1 = new MP3();
		f1.setFileName("aaa");
		System.out.println("파일명 = " + f1.getFileName() + ".mp3");
		f1.setFileSize(4.15f);
		System.out.println("파일크기 = " + f1.getFileSize() + "GB");
		f1.setDuration(1000);

		f1.execute();
		f1.forward();
		f1.rewind();

		System.out.println();

		AVI f2 = new AVI();
		f2.setFileName("bbb");
		System.out.println("파일명 = " + f2.getFileName() + ".avi");
		f2.setFileSize(1.23f);
		System.out.println("파일크기 = " + f2.getFileSize() + "GB");
		f2.setSpeed(1.5f);
		System.out.println("재생 속도 = x" + f2.getSpeed());
		f2.execute();
		f2.forward();
		f2.rewind();

		System.out.println();

		PPT f3 = new PPT();
		f3.setFileName("ccc");
		System.out.println("파일명 = " + f3.getFileName() + ".ppt");
		f3.setFileSize(12.03f);
		System.out.println("파일크기 = " + f3.getFileSize() + "GB");
		f3.setPageSize(3);
		System.out.println("페이지 수 = " + f3.getPageSize());
		f3.execute();
		f3.information();

	}
}

- 정답

파일명 = aaa.mp3
파일크기 = 4.15GB
재생 시간 = 1000초
실행!
빨리감기 기능 실행!
되감기 기능 실행!

파일명 = bbb.avi
파일크기 = 1.23GB
재생 속도 = x1.5
실행!
빨리감기 기능 실행!
되감기 기능 실행!

파일명 = ccc.ppt
파일크기 = 12.03GB
페이지 수 = 3
실행!
<파일 정보 확인>