Chapter 06. 객체지향 프로그래밍(1)
1. 객체지향 언어의 특징
- 코드의 재사용성이 높다.
- 코드의 관리가 용이하다
- 신뢰성이 높은 프로그래밍을 가능하게 한다.
- (제어자와 메소드를 이용해서 데이터를 보호하고 올바른 값을 유지하도록 하며, 코드의 중복을 제거하여 코드의 불일치로 인한 오동작을 방지할 수 있다.)
2. 클래스와 객체
클래스란 ?
객체를 정의해 놓은 것
'설계도'라고 생각하면 쉽다.
객체를 생성하기 위한 '필드' , 기능을 가지고 있는 [함수(method)가 정의되어 있다.
객체란?
실제로 존재하는 것, 사물 또는 개념이다
객체는 클래스에 정의된 대로 생성된다.
클래스를 이용해서 만든 것
즉 클래스는 설계도 객체는 제품이라고 생각하면 된다.
3. 인스턴스
- 클래스로부터 만들어진 객체
- 클래스로부터 객체를 만드는 과정을 인스턴스화라고 한다.
인스턴스화
클래스 ------------>인스턴스(객체)
4. 클래스 선언
클래스 선언 방법
- 하나 이상의 문자로 이루어져야 한다.(MemberList, SportsCar 등등)
- 첫 글자는 숫자가 올 수 없습니다.(999Enhaculdo(x),Engachuldo999(o))
- '$','_' 외의 특수문자는 사용할 수 없다.
- 자바 키워드는 사용할 수 없다.(int (x) , for(x))
- 통상적으로 첫 글자는 대문자로 하고 나머지는 소문자로 작성한다.
객체 생성과 클래스 변수
- 클래스로부터 객체를 생성하여 만들어진 객체(인스턴스)
- 클래스로부터 객체를 생성하려면 new 연산자를 사용한다.
- new 연산자 뒤에는 생성자가 온다.
- new 연산자로 생성된 객체는 힙(heap)메모리 영역에 생성된다.
클래스는
-필드 (정수형,실수형,논리형,문자형과 같은 기본타입을 갖는 변수와 값)
-생성자
-함수(method) 로 구성되어 있다.
5. 객체 배열
- 객체 배열은 참조변수들을 하나로 묶은 참조변수 배열이다.
Tv tv1,tv2,tv3; //참조변수
Tv[] tvArr = new Tv[3]; //참조변수배열
객체를 생성해서 객체 배열의 각 요소에 저장하는 것 잊으면 안된다!
Tv[] tvArr = new Tv[3]; // 참조변수배열(객체 배열)을 생성
//객체를 생성해서 배열의 각 요소에 저장
tvArr[0] = new Tv();
tvArr[1] = new Tv();
tvArr[2] = new Tv();
Tv[] tvArr = {new Tv(), new Tv(), new Tv()}; //초기화 하는 법
//다뤄야할 객체 수가 많을 때는 for문을 사용하면 된다.
Tv[] tvArr = new Tv[100];
for(int i = 0; i<tvArr.length;i++) {
tvArr[i] = new Tv();
6. 사용자 정의 데이터 타입
- 데이터의 최종 진화 형태이다. (변수->배열->클래스)
- 서로 다른 타입의 데이터를 묶어서 사용하는 것이다.
- 변수와 메서드로 구성할 수 있다.
//3차형 데이터관리
public static void main(String[] args) {
Student student = new Student();
student.name = "홍길동";
student.kor = 90;
System.out.println(student.name);
System.out.println(student.kor);
System.out.println(student.toString());
}
//3차형 데이터 관리
class Student{
private int kor, eng, math;
private int sum;
private double avg;
private String name;
Student(int kor, int eng, int math, String name){
this.kor = kor;
this.eng = eng;
this.math = math;
this.name = name;
this.sum = sum();
this.avg = avg();
}
private double avg() {
return (double) sum /3;
}
private int sum() {
return kor + eng + math;
}
}
6. 선언위치에 따른 변수의 종류
- 인스턴스 변수, 클래스 변수, 지역변수
*인스터스 변수는 인스턴스가 생성될 때 마다 생성되므로 인스턴스마다 각기 다른 값을 유지할 수 있지만,
클래스 변수는 모든 인스턴스가 하나의 저장공간을 공유하므로, 항상 공통된 값을 갖는다.
*인트턴스 변수 (개별 속성) 클래스 변수(공통 속성)
7. 메서드(method)
메서드는 변수를 가지고 하는 작업(일)
- 선언 방법
접근제한자 리턴타입 메서드명(파라미터){} // ex) public void method1(){}
- 파라미터(매개변수) : 실행에 필요한 정보
- 리턴타입(반환타입) : 실행 후 돌려줘야 하는 결과물
public void method1(){
// void : 메서드가 종료 후 반환하는 결과물이 없음
// 파라미터가 없음
System.out.println("리턴 타입도 파라미터도 없음");
}
public void method2(String parameter) {
// String 타입의 파라미터가 필요하다
System.out.println(parameter + " : 파라미터를 받아 명령을 수행함");
}
public String method3() {
// 메서드가 종료 후 반환하는 결과물이 String 타입
String str = "홍길동";
return str; //return -> 메서드를 종료한다.
// System.out.println(str); //도달할 수 없는 코드이다
}
- return문
메서드의 반환타입이 void가 아닌 경우 반환값이 꼭 있어야 한다. 적어도 자동 형변환이 가능한 것이어야함!
- 지역변수
메서드 내에서만 사용할 수 있는 변수!
- 메서드 호출
메서드이름(값1, 값2, ...); // 메서드를 호출하는 방법
(호출 스택)
// flowTest() 호출 시 출력되는 문장에 순서(번호)를 붙여주세요
public void flowTest1() {
System.out.println("flowTest1 시작 : 1");
flowTest3();
System.out.println("flowTest1 종료 : 6");
}
public void flowTest2() {
System.out.println("flowTest2 시작 : 3");
System.out.println("flowTest2 종료 : 4");
}
public void flowTest3() {
System.out.println("flowTest3 시작 : 2");
flowTest2();
System.out.println("flowTest3 종료 : 5");
}
JVM(Java Virtual Machine)
- 자바로 만들어진 프로그림이 실행되는 컴퓨터 안의 가상 컴퓨터
- 운영체제 -> JVM -> 자바 프로그램
- 장점 : 운영체제와 상관없이 실행할 수 있다.
- 단점 : 속도가 비교적 느리다.
JVM 메모리 구조
- Method Area (메서드 영역) : 클래스 멤버가 저장된다
- Call Stack (호출 스택) : 현재 호출되어있는 메서드가 저장된다. //Stack은 후입선출의 구조를 가지고 있음
- Heap(힙) : 객체가 저장된다.
-static 메서드는
클래스 변수처럼 객체를 생성하지 않고도 '클래스이름.메서드이름(매개변수)'와 같은 식으로 호출 가능
ex) new SampleClass().method1();
ex) System.out.println(MyMath2.add(200L,100L));
(멤버변수는 인스턴스변수와 static변수를 모두 통칭하는 말임)
(인스턴스 메서드는 객체생성 후에만 호출이 가능함.)
- static 메서드는 인스턴스 변수를 사용할 수 없다.
- static을 붙인 변수는 객체간에 변수의 값을 공유한다.
- static이 붙은 멤버의 명칭 : 클래스 변수, 클래스 메서드
- Static이 붙지 않은 멤버의 명칭 : 인스턴스 변수, 인스턴스 메서드
// 값을 공유하기위해 static을 붙인다.
static int var;
public static void main(String[] args) {
Human 철수 = new Human();
Human 영희 = new Human();
철수.saveMoney(50000);
영희.saveMoney(100000);
Human 커플통장 = new Human();
커플통장.saveMoney(200000);
철수.saveGroupMoney(200000);
System.out.println(영희.groupAccount);
영희.saveGroupMoney(100000);
System.out.println(철수.groupAccount); //영희 철수 것이 아니라 휴먼클래스 안에있는 모든 것 즉 휴먼클래스 것이당!
System.out.println(Human.groupAccount);
//Static으로 선언된 것은 단하나의 값만 존재한다.
}
}
class Human{
int account; //잔고
public void saveMoney(int money) {
this.account += money;
System.out.println("통장 잔고 :" + this.account);
}
static int groupAccount;
public void saveGroupMoney(int money) {
this.groupAccount += money;
System.out.println("모임통장 잔고 :" + groupAccount);
}
}
8. 오버로딩(overloading)
- 한 클래스 내에 같은 이름의 메서드를 여러개 정의하는 것
1) 메서드 이름이 같아야 한다.
2)매개변수의 개수 또는 타입이 달라야 한다.
3)반환 타입은 관계없다!
9. 생성자(constructor)
- 클래스와 이름이 같은 매서드
- 인스턴스 변수를 초기화하기 위해 사용한다.
- 클래스에 생성자는 반드시 하나 이상 존재해야한다.
- 직접 선언해주지 않으면 컴파일러가 기본 생성자를 만들어준다.
- 생성자는 리턴타입이 없다.
(Scanner sc = new Scanner(); //스캐너는 기본생성자가 없다)
VariableInit(){ //기본생성자 (클래스이름과 매서드 명이 같고 파라미터가 없음)
var = 50; //기본생성자를 통해 초기화가 됌
// 생성자를 사용 이유
//- 초기화에 여러줄의 코드가 필요할때
//- 초기화에 파라미터가 필요할때
}
//오버로딩 (같은 메서드 2개를 중복해서 사용할때!) , 변수명은 같은데 파라미터가 다를 때
VariableInit(int var){
this.var = var;
// this : 클래스 자체를 말함
}
9. this
this : 인스턴스 자신을 가리키는 참조변수, 인스턴스의 주소가 저장되어 있다.
모든 인스턴스메서드에서 지역변수로 숨겨진 채 존재.
this(), this(매게변수) :생성자, 같은 클래스의 다른 생성자를 호출할 때 사용한다.
class DditClass{
int 컴퓨터;
int 학생;
String 담임;
//오버로딩 : 같은 이름의 메서드를 여러개 정의하는 것
DditClass(){
// this : 인스턴스 변수와 지역변수의 이름이 같을때 둘을 구분하기 위해 사용
// this.컴퓨터 = 25;
// this.학생 = 25;
this(null); //참조형변수의 기본값은 null, this는 생성자를 부를때 쓸 수있다
}
//파라미터가 없는 생성자와 있는 생성자 두개 다 만들어야지 쓸 수 있다
DditClass(String 담임){
this.컴퓨터 = 25;
this.학생 = 25;
this.담임 = 담임;
}
10. 변수의 초기화
int _int;
//명시적 초기화
int var = 10;
static int staticVar = 20;
//stack과 static은 저장공간이 다르고 static은 웬만하면 사용하지 말자! 절대!
// 초기화 블럭
{
var = 20;
staticVar = 30; // 일반 초기화 블럭에서 초기화할 수 있다
}
//스태틱 블럭 :클래스 초기화 블럭 복찹한 초기화
static {
staticVar = 40;
// var = 30; // 스태틱 블럭에서 초기화 할 수 없다
}
// 초기화블럭과 스태틱블럭은 잘 사용하지 않음
-멤버변수(클래스 변수와 인스턴스 변수)와 배열의 초기화는 선택이지만
지역변수의 초기화는 필수이다!