[포스코DX|Java|1주] 3일차 수업
포스코DX X 비트교육센터 6기 - 자바 객체지향
개발 언어
- 주개발언어: java, c, c++, c#
-
세컨언어: JS, python, ruby
- 절차지향프로그래밍 -> 객체지향프로그래밍 -> 함수형 프로그래밍
객체란?
실세계에 존재하는 것.
-
학사관리시스템의 학생, 교수님, 수업 정보 등등 정보가 굉장히 많을 것. 이 것의 도메인을 분석하여 의미를 부여하고 분류한 결과로 프로그램을 만들어 적당한 시점에서 객체를 만든다.
- 필드: 객체의 속성
- 메소드: 객체의 기능
JVM 메모리 모델
ex. HelloWorld.java가 실행된다.
- Method Area
- class loader가 HelloWorld.class 저장.
- instance 공간과 static 공간으로 나뉨.
- System class 공간이 자동 호출됨. 객체로 쓰일 때, Heap공간에서 쓰이는 것.
- Stack
- camera = 1000 이 들어감. (Goods camera = new Goods();)
- Heap
- String은 자동으로 내부에서 new 로, 받아와서 사용 가능. 원래는 String s = new String(“얍”) 이렇게 사용하는데, 내부적으로 처리해줌. Heap에서 배열로 저장.
- System.out.println(new String(“Hello World”)); = System.out.println(“Hello World”);
- String은 자동으로 내부에서 new 로, 받아와서 사용 가능. 원래는 String s = new String(“얍”) 이렇게 사용하는데, 내부적으로 처리해줌. Heap에서 배열로 저장.
메소드가 끝났을 때, stack이 pop()으로 정리되게 된다.
접근지정자
- public : 내부, 외부 , 자식, 다아아아 가능
- protected : 자식 -> 부모 가능 (자식에서 접근 가능하다) + 같은 패키지 (이건 별 고려해서 protect로 설정하는건아님)
- private : 다 안돼. 내부에서만 가능 (정보은닉, 캡슐화)
클래스 예시
package chapter03;
public class Goods {
String name;
int price;
int countStock;
int countSold;
}
///////////////////
package chapter03;
public class GoodsApp {
public static void main(String[] args) {
Goods camera = new Goods();
camera.name = "Nikon"; // heap 공간에 Nikon이 생성되고 -> heap의 Goods 객체를 가리킴
camera.price = 400000;
camera.countStock = 10;
camera.countSold = 20;
System.out.println("상품이름 : " + camera.name + ", 가격 : " + camera.price + ", 재고개수 : " + camera.countStock
+ ", 팔린개수 : " + camera.countSold);
}
}
접근 지정자 예시
- 파일 구조
package mypackage;
public class Goods2 {
public String name; // 모든 접근이 가능하다(접근 제한이 없다)
protected int price; // 같은 패키지 + *자식 클래스에서 접근이 가능
int countStock; // 같은 패키지(디폴트)
private int countSold; // 클래스 내부에서만 가능
public void m() {
countSold = 50;
}
}
package chapter03;
import mypackage.Goods2;
public class DiscountGoods2 extends Goods2{
private float discountRate = 0.5f; //double로 생각하기에 f로..
public int getDiscountPrice() {
//protected는 자식에서 접근할 수 있다.
int discountPrice = (int)(discountRate * price);
return discountPrice;
}
}
package chapter03;
import mypackage.Goods2;
public class GoodsApp2 {
public static void main(String[] args) {
Goods2 camera = new Goods2();
// public : 접근 제한이 없다.
camera.name = "Nikon";
// protected : 같은 패키지에서 접근이 가능하다.
// 더 중요한 접근 제어는 자식에서 접근 가능하다.
//camera.price = 400000; 다른 패키지 이동 시 오류
// 디폴트 : 같은 패키지에서 접근이 가능하다.
//camera.countStock = 10; 다른 패키지 이동 시 오류
// private : 같은 클래스에서만 접근이 가능하다.
//camera.countSold = 20;
camera.m();
//System.out.println("상품이름 : " + camera.name + ", 가격 : " + camera.price + ", 재고개수 : " + camera.countStock
// + ", 팔린개수 : " + camera.countSold);
}
}
private의 getter setter
- setter
this.name = name
this란? 해당 클래스 내부에 있는 나
package chapter03;
public class Goods3 {
private String name; //모든 접근이 가능하다(접근 제한이 없다)
private int price;
private int countStock;
private int countSold;
public Goods3() {
}
public Goods3(String name, int price, int countStock, int countSold) {
super();
this.name = name;
this.price = price;
this.countStock = countStock;
this.countSold = countSold;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public int getCountStock() {
return countStock;
}
public void setCountStock(int countStock) {
this.countStock = countStock;
}
public int getCountSold() {
return countSold;
}
public void setCountSold(int countSold) {
this.countSold = countSold;
}
@Override
public String toString() {
return "Goods2 [name=" + name + ", price=" + price + ", countStock=" + countStock + ", countSold=" + countSold
+ "]";
}
}
package chapter03;
public class GoodsApp3 {
public static void main(String[] args) {
//Goods3 camera = new Goods3("Nikon", 4000, 10, 20);
//System.out.println(camera);
Goods3 camera = new Goods3();
camera.setName("Yewon");
camera.setPrice(30000);
camera.setCountStock(20);
camera.setCountSold(30);
// 정보은닉(데이터보호)
camera.setPrice(-1);
System.out.println("Goods2 [name=" + camera.getName() + ", price=" + camera.getPrice() + ", countStock=" + camera.getCountStock() + ", countSold=" + camera.getCountSold()
+ "]");
}
}
더 깜끔하게~
package chapter03;
public class GoodsApp3 {
public static void main(String[] args) {
Goods3 camera = new Goods3("Nikon", 4000, 10, 20);
System.out.println(camera);
}
}
정보 보호?
public void setPrice(int price) {
//정보 보호
if(price < 0) {
price = 0;
}
this.price = price;
}
// 정보은닉(데이터보호)
camera.setPrice(-1);
초기화
- 지역변수는 명시적 초기화 필요
- static은 초기화 불필요
int i;
// System.out.println(i); 에러 발생. 지역변수는 초기화가 필요.
변수 별 메모리
- new를 많이하면 cpu가 느려짐.
생성자
public class Goods3 {
public static int countOfGoods = 0;
private String name; //모든 접근이 가능하다(접근 제한이 없다)
private int price;
private int countStock;
private int countSold;
public Goods3() {
//내부에서는 클래스 이름 생략 가능
//Goods.countOfGoods++;
countOfGoods++;
}
.
.
.
// countOfGoods 테스트
Goods3 goods1 = new Goods3();
Goods3 goods2 = new Goods3();
Goods3 goods3 = new Goods3();
System.out.println(Goods3.countOfGoods);
결과값 : 3 //heap에 3개의 객체가 생성. 초기값으로. 객체가 생성되고 초기화 될 때마다 생성자가 불러오고 method area에 count값이 +1됨.
메소드
-
메소드 시그너처(signature) : 메소드 인자의 타입, 개수, 순서
-
call : 메소드를 호출하다
- call by value
- call by reference
결과
a=10, b=20
a=20, b=10
결과
a=10, b=20
a=10, b=20
안 바뀌는 이유
해결하기 위해서 call by reference를 해주어야함.
package chapter03;
import mypackage.Value;
public class SwapTest03 {
public static void main(String[] args) {
Value a = new Value(10);
Value b = new Value(20);
System.out.println("a=" + a.val + ", b=" + b.val);
swap(a, b);
System.out.println("a=" + a.val + ", b=" + b.val);
}
private static void swap(Value m, Value n) {
int temp = m.val;
m.val = n.val;
n.val = temp;
}
}
package mypackage;
public class Value {
public int val;
public Value(int val) {
this.val = val;
}
}
call by value + call by reference 두 과정을 모두 겪는다.
static method
package chapter03;
public class StaticMethod {
int n; //인스턴스 변수
static int m; //static 변수 = 클래스 변수
void f1() { //인스턴스 메소드
n =10;
}
void f2() {
//같은 클래스의 클래스(static)변수 접근에서는 클래스 이름 생략 가능
m=20;
}
void f3() {
f2();
}
void f4() {
StaticMethod.s1();
//같은 클래스의 클래스(static)변수 접근에서는 클래스 이름 생략 가능
s1();
}
static void s1() {
//에러: static method 에서는 인스턴스 변수 접근 불가
// n =10;
}
static void s2() {
//에러: static method 에서는 인스턴스 변수 접근 불가
// f1();
}
static void s3() {
StaticMethod.m =10;
//같은 클래스의 클래스(static)변수 접근에서는 클래스 이름 생략 가능
m=20;
}
static void s4() {
StaticMethod.s1();
//같은 클래스의 클래스(static)변수 접근에서는 클래스 이름 생략 가능
s1();
}
}
메소드 사용법 예시
+) 자바 API - Arrays
package chapter03;
import java.util.Arrays;
public class ArrayUtilTest {
public static void main(String[] args) {
int[] a = {10,20,30,40};
// == int[] a = new int[]{10,20,30,40};
double[] d = ArrayUtil.intToDouble(a);
for(int i =0; i<d.length; i++) {
System.out.println(d[i]);
}
System.out.println(Arrays.toString(d));
//int[] b = doubleToInt(new double[] {10.0, 20.0, 30.0});
//ArrayUtil.concat(new int[] {1,2,3}, new int[] {4,5,6});
//System.out.println();
}
}
package chapter03;
public class ArrayUtil {
public static double[] intToDouble(int[] a) {
double[] d = new double[a.length];
for(int i = 0; i< a.length; i++) {
d[i] = a[i];
}
return d;
}
public static void concat(int[] is, int[] is2) {
// TODO Auto-generated method stub
}
}
배열 객체
private static final int COUNT_GOODS = 3;
public static void main(String[] args) {
Goods[] goods = new Goods[COUNT_GOODS];
goods[0] = new Goods(name, price, count); //생성자에 넣어야 null값이 아니라 값 생성
}