java 5일차

KHLee·2023년 2월 28일

자바수업

목록 보기
5/46
  • OOP는 OOAD에서 시작을 함(object-oriented Analysis and design, 객체 지향 분석 설계)
  • 표준화있게 프로그래밍을 시작하자 -> OOAD가 논의되고 UML(Unified Model Language, 통합 모델링 언어)이 나옴.
    ex) 건축에서는 바티칸 성당은 메뉴얼 없이 사람의 손으로 만들어졌지만, 현재 건축들은 일정 메뉴얼에 따라서 만들어짐.
  • zero부터 만들지 말고 레고블럭처럼 가져다 만드는 식으로 하자!
  • OOP : 부품 객체를 먼저 만들고 이것들을 하나씩 조립해 완성된 프로그램을 만드는 기법.
  • 객체? : 물리적으로 존재하는 것, 추상적인 것 중에서 자신의 속성과 동작을 가지는 것.
  • 객체지향 이전에는 erp시스템을 만든다면, erp시스템에 맞게 회사 업무를 진행해야 함. 현업에 맞게 시스템을 수정할 수 없음.
  • 그러나 회사 업무를 100% 객체지향으로 짤 수는 없다.
  • 클래스라는 틀을 만들고, 틀을 갖고 객체를 생성하여 사용하게 된다. 클래스에서 만들어진 객체를 인스턴스라고 한다.
  • 객체는 다른 객체와 관계를 맺고 이것에 대해 공부하는 것이다.
  • 어떠한 프로세스가 주어졌을 때, 객체로 만들 것을 추출하고 그것을 먼저 만들고 프로그래밍을 시작.(빙상경기장은 좌석이 어떻고, 사람들이 어떻게 들어와서, 어떻게 티켓팅하고, 어떻게 앉힌다? -> 무엇을 객체로 추출해서 만들거야?)

기획이 나오면 어떻게 할지 분석(analysis)을 하고 그 다음 개발을 어떻게 할 지 디자인(design)을 한다. (starUML는 툴)


'Car' 현실세계를 반영할 수 있는 것은 속성과 행위 두가지로 분류할 수 있고 설계한다.
이 클래스를 갖고 만들었을 때 인스턴스가 가질 속성. 가질 행위.

Car라는 클래스에 name, color, size 속성(attribute)을 추가했고, go, stop 행위(operation)를 부여했다. 이 클래스를 통해 만들어지는 인스턴스는 위의 속성과 행위를 갖는다.
위처럼 작성하는 것은 design에 속한다.(analysis는 string, void 프로그래밍 용어 안쓰고, 색깔, 간다 이런 용어로 분석)

Car라는 객체를 이용해서 만드는 App가 되는 것.(프로그램 업데이트 시 App만 바꾸면 된다.)
추후 Web개발 시 App는 Web이 되는 것이고, Car라는 객체는 로그인을 하는 수단, 회원가입을 하는 수단들로 이루어지게 될 것이다.

위 내용을 자바로 작성하면 위와 같이 된다. Car의 클래스를 만든다.

App는 객체지향하고 관계 없다. UML한 것을 실행시켜주는 장치라고 보면 된다.(추후엔 Web에서 실행)
car1은 Car클래스를 갖고 만든 객체!!
프로그래밍을 잘 하는 사람은 잘 설계된 도면을 갖고 잘 구현해내는 사람이다.
실무에서 가장 중요한 것은 '화면'?
기획과 화면에 대한 업무 기획에 대한 업무, 서비스 런칭.?


절차진행형 vs 객체지향형?

  • 절차 진행형 : 위에서 설명한 erp처럼 진행 순서대로만 진행을 하여야 했던 시스템이다. 현업 업무도 시스템을 중심으로 진행이 되어야 했다. 수정을 해야하는 일이 생기면 시스템 개편이 어렵고 복잡했다. 절차 1부터 모두 수정을 해야하는 상황이 발생.
  • 처음 객체지향을 쓸 때는 완전하게 설계가 되지 않았기 때문에 유지보수가 어려웠던 기간이 있었음. 현재는 (서버가) 완전히 잘 되어있음. 현업에서 계속 바뀌는 부분은 화면!

  • 클래스 작명규칙 중요함!
  • 자바파일 만드는 것은 Save를 누르면 class들이 만들어짐(bin파일 아래 있음) 배포는 class만 배포하고 src는 회사에서 갖고 있음.



생성자까지 구현을 하면 위와 같이 추가가 됨.

class 는 속성(필드)/ 생성자/ 행위(메소드)로 구성이 된다!!
생성자는 필드를 초기화시켜주는 역할. 필드와 메소드 모두 멤버.
메소드는 멤버펑션이라고도 부름.


  • App이 업그레이드 된다면 App2를 만들어서 새롭게 작성을 한다.


속성, 함수를 구현할 때 this를 추가하게 되는데 여기서 this는 Car car1 = new Car; Car car2 = new Car;를 만들었을 때 각 인스턴스 요소를 가리킨다. #100, #101의 주소를 가리킨다.

Car car1 = new Car를 실행하면 새로운 car1이 생성이 되어 heap 메모리에 저장이 된다.




지정된 것을 만들어주는 생성자 말고, 입력을 받아서 만들어주는 생성자를 구현했고, car2를 지정하여 만들었다.



System.out.printf("%s, %s go car...", this.name, this.color); }으로 색상도 함께 출력할 수 있다.


package oop2;

import java.util.Random;

public class Employee {
	private String id;//class밖에서 수정을 못하도록 private으로 막는 장치. 처음에 생성될 때만 건들 수 있음.
	private String name;
	private int salary;

	// 생성자는 마우스 오른쪽 -> source -> generate constructor에서 만들 수 있음.
	// 생성자를 오버로드 한 것, 아규먼트에 따라서 다른게 호출됨.
	public Employee() {
		this.id = "temp0001";
		this.name = "temp";
		this.salary = 10000000;
	}

	public Employee(String id, String name, int salary) {
		this.id = id;//이 경우는 this.를 생략할 수 없음. 들어온 데이터를 똑같은 들어온 데이터에 넣는다? 말이 안됨.
		this.name = name;//이 주소(this)에 새로 들어온 데이터를 넣겠다. 이 경우는 생략 안돼!
		this.salary = salary;
	}

	public Employee(String name, int salary) {// arguments가 2개라도 id는 설정해주는 것 잊지말기;
		Random r = new Random();
		this.id = String.valueOf(r.nextInt(100) + 1);
		this.name = name;
		this.salary = salary;
	}

	public String getName() {//source에서 getter와 setter를 설정해줌.
		return name;
	}

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

	public String getId() {
		return id;
	}

	public int getSalary() {
		return salary;
	}

	public int getAnnSalary() {
		return this.salary * 12;//this.를 빼더라도 컴파일러는 자동으로 this.을 붙임.
	}

	public double getTax() {
		return this.salary * 0.175;
	}

	@Override//이게 뭐에요? 아직 안배움.
	public String toString() {
		return "Employee [id=" + id + ", name=" + name + ", salary=" + salary + "]";
	}
	
}

위 class를 이용한 아래 App

package oop2;

public class App {

	public static void main(String[] args) {
		Employee e1 = new Employee();
		System.out.println(e1.toString());//출력을 하기 위해 class에 toString을 정의하고 출력.
		
		Employee e2 = new Employee("이말숙", 5000000);
		//e2.salary = 9000000;//중요한 변수들(연봉,아이디)이 class 내에 들어가있고 현재는 오픈되어있는 상태. 접근을 막아야함.
		
		System.out.println(e2.toString());
		System.out.println(e2.getAnnSalary());
		System.out.println(e2.getTax());
		
		e2.setName("이말자");
		System.out.println(e2.toString());
	}

}

A a = new A();
A클래스 a참조변수 = new힙메모리에넣어 A생성자
=> 객체생성

  • 모든 생성 객체는 동일한 메소드를 공유!함.
  • 객체를 구분하는 것은 속성!
  • this.를 생략할 수 없는 경우 : 새로 받은 요소를 this.라는 주소에 할당하려고 할 때 생략 불가능.
    this.를 생략하더라도 컴파일러에서 자동으로 붙여주는 것임.

필드의 내용 :

  • 고유 내용 : 정적임. 이름, 모델 등
  • 상태 : 속도, 회전수 등
  • 부품 :

생성자와 기본생성자 :

  • 생성자가 없을 때는 자동으로 디폴트 컨스트럭트를 만들어서 쓰게됨.
    ex) public car(){}
  • argument가 존재하는 생성자가 하나라도 있을 경우는 디폴트 컨스트럭터는 자동생성 안됨.
  • 생성자는 이름이 다른 생성자가 존재할 수 있다. 단, argument가 달라야 한다. <- 생성자의 오버로딩


다른 컨스트럭터를 this()를 통해 호출하는 방법!
salary를 0이하는 0으로 받기 위해서 생성자를 작성했는데 모든 생성자에 if else를 넣으면 소스가 지저분해짐. 따라서 두번째 생성자를 작성할 때는, 첫번째 생성자를 호출하여 작성함.
반드시 첫째 줄에서 호출을 해야함.

메소드 :

  • void : 리턴타입이 없는 경우(ex. car.go()의 경우 가면 됨. 나한테 돌아오는 건 필요없어)
  • 리턴타입은 메소드 타입과 같아야함.(ex. 메일을 보냈을 때 성공은 1, 실패는 0으로 리턴을 받아)

package oop3;

public class Car {
	private String name;
	private String color;
	private int size;
	private int fsize;
	private int cfsize;

	// 생성자. (constructor)
	public Car() {
	}

	public Car(String name, String color, int size, int fsize) {
		this.name = name;
		this.color = color;
		this.size = size;
		this.fsize = fsize;
	}

	public Car(String name, String color, int size, int fsize, int cfsize) {
		this(name, color, size, fsize);
		this.cfsize = cfsize;
	}

	@Override
	public String toString() {
		return "Car [name=" + name + ", color=" + color + ", size=" + size + ", fsize=" + fsize + ", cfsize=" + cfsize
				+ "]";
	}

	// 기름을 넣는다.
	// 기름보다 많이 넣으면 - 다시 주유 하세요
	// 음수 값이 들어가면 - 다시 주유 하세요.

	public void setCfsize(int size) {// 반환값이 없어서 void, 기름 얼마나 넣을지, 기름통량보다 더 많으면 어떡할지 구현하는 필드임
		if (size < 0 || size > fsize - cfsize) {
			System.out.println("다시 주유 하세요");
			return;
		}
		System.out.println(size + "L주유되었습니다");
		cfsize += size;
	}

	// 주행을 한다.
	// 1리터당 10km를 주행할 수 있다.
	public void go(int distance) {
		if (cfsize <= 0 || cfsize < (distance / 10)) {
			System.out.println("기름이 부족합니다");
			return;
		}
		System.out.printf("%s %dKM go...\n", this.name, distance);
		cfsize -= distance / 10;
	}

	// 멈춘다.
	public void stop() {
		System.out.printf("%s stop...\n", this.name);
	}

}
package oop3;

public class App {

	public static void main(String[] args) {
		Car car = new Car("C1", "red", 1000, 50);
		System.out.println(car.toString());
		car.go(1);
		car.setCfsize(30);
		car.setCfsize(20);
		car.setCfsize(10);
		System.out.println(car.toString());
		car.go(177);
		System.out.println(car.toString());

	}

}

package ws0228;

public class Employee {
	private String name;
	private double salary;

	// 생성자
	public Employee() {
	}

	public Employee(String name, double salary) {
		this.name = name;
		this.salary = salary;
	}

	// 메소드
	public String getName() {
		return name;
	}

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

	public double getSalary() {
		return salary;
	}

	@Override
	public String toString() {
		return "Employee [name=" + name + ", salary=" + salary + "]";
	}

	public double getAnnSalary() {
		// System.out.printf("%4.2f\n", (salary * 12.0));//App내에서 Sum을 구할 때 함수 호출 시
		// print가 되어서 미사용
		return salary * 12.0;
	}

	public double getTax() {
		// System.out.printf("%4.2f\n", (salary * 0.0372));
		return salary * 0.0372;
	}

}

public class Manager {
	private String name;
	private double salary;
	private double bonus;

	// 생성자
	public Manager() {
	}

	public Manager(String name, double salary, double bonus) {
		this.name = name;
		this.salary = salary;
		this.bonus = bonus;
	}

	// 매서드
	public String getName() {
		return name;
	}

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

	public double getSalary() {
		return salary;
	}

	public double getBonus() {
		return bonus;
	}

	@Override
	public String toString() {
		return "Manager [name=" + name + ", salary=" + salary + ", bonus=" + bonus + "]";
	}

	public double getAnnSalary() {
		// System.out.printf("%4.2f\n",((salary * 12.0) + bonus));
		return (salary * 12.0) + bonus;
	}

	public double getTax() {
		// System.out.printf("%4.2f\n",(((salary * 12.0) + bonus) * 0.0372));
		return ((salary * 12.0) + bonus) * 0.0372;
	}
//	public double getTax() {//이 코드는 this.으로 메서드 결과값을 불러왔지만, 출력하는 줄도 있어서 연봉이 여러번 출력됨.
//		System.out.printf("%4.2f\n",(this.getAnnSalary() * 0.0372));
//		return (this.getAnnSalary() * 0.0372);
//	}

}
package ws0228;

public class App {

	public static void main(String[] args) {
		Employee e1 = new Employee("apple", 1000000);
		Employee e2 = new Employee("banana", 3000000);
		Employee e3 = new Employee("caramel", 4000000);
		Employee e4 = new Employee("doll", 5000000);
		Employee e5 = new Employee("elec", 1000000);
		Employee e[] = { e1, e2, e3, e4, e5 };
		double sumE = 0.0;

		Manager m1 = new Manager("fall", 300000, 10000);
		Manager m2 = new Manager("great", 700000, 20000);
		Manager m3 = new Manager("home", 900000, 30000);
		Manager m4 = new Manager("image", 2000000, 40000);
		Manager m5 = new Manager("juice", 1800000, 50000);
		Manager m[] = { m1, m2, m3, m4, m5 };
		double sumM = 0.0;

		for (int i = 0; i < e.length; i++) {
			System.out.printf("%d번째 직원의 연봉은 %10.2f, 세금은 %10.2f\n", i + 1, e[i].getAnnSalary(), e[i].getTax());
			System.out.println(e[i].toString());
			sumE += e[i].getAnnSalary();
		}
		System.out.printf("----------직원 연봉의 총 합은 %10.2f----------\n", sumE);

		for (int i = 0; i < m.length; i++) {
			System.out.printf("%d번째 매니저의 연봉은 %10.2f, 세금은 %10.2f\n", i + 1, m[i].getAnnSalary(), m[i].getTax());

			System.out.println(m[i].toString());
			sumM += m[i].getAnnSalary();
		}
		System.out.printf("----------매니저 연봉의 총 합은 %10.2f----------\n", sumM);
	}
}
profile
안녕하세요

0개의 댓글