Language/Java

객체지향 언어

JUNGKEUNG 2021. 9. 12. 01:29
반응형

객체지향 언어


객체 지향에는 특징으로 4가지을 볼수가 있다.

1. 캡슐화

2. 상속

3. 추상화

4. 다형성

이 중에서 가장 중요시 여기고 있는것은 다형성이라 볼수있다.

 

 

 

객체지향언어의 장점


1. 코드의 재사용성이 높다

    -새로운 코드를 작성할 때 기존의 코드를 이용하여 쉽게 작성할 수 있다.

2. 코드의 관리가 용이하다

   - 코드간의 관계를 이용해서 적은 노력으로 쉽게 코드를 변경할 수 있다.

3. 신뢰성이 높은 프로그래밍을 가능하게 한다.

    - 제어자와 메서드를 이용해서 데이터를 보호하고 올바른 값을 유지하도록 하며,

      코드의 중복을 제거하여 코드의 불일치로 인한 오동작을 방지할 수 있다.

 

 

 

 

클래스란? 


- 객체를 정의해놓은것 (처음 클래스을 배우는 사람은 설계도 또는 틀이라고 생각하면서 공부해보자)

 

 

 

클래스의 용도


- 객체를 생성하는데 사용된다.

ex) 리모콘를 만들때 먼저 리모콘의 설계을 어떻게 할지 설계도를 만들고 설계도대로 틀을 만들어 안에 부품을 채워 하나의 리모콘이 완성되는것을 생각하는것이 좋다.

 

객체 = 속성(변수) + 기능(메서드)을 말한다.

그럼 객체는 무엇을 뜻하는가? 

클래스 : 하나의 설계도라 설명했듯이 객체는 클래스안에 부품의 역할을 한다. 

속성 : 리몬콘의 색, 전원 상태, 채널 등을 뜻한다

기능 : 채널을 눌렀을때 채널이 변경하거나 소리을 조절할때 쓰이는것을 말한다

우리는 속성과 기능을 변수와 메서드라고 부르기도 한다. 
class Tv{  // 객체를 정의해놓은것 
-------------------------------------
	String color;   // 색깔 
	boolean power;  // 전원상태       속성(변수)
	int channel;    // 채널
------------------------------------
	void power() { power =! power; } 
	void channelUp() { channel++; }      //기능(메서드)
	void channelDown() { channel --; }

 

 

 

인스턴스의 생성과 사용


인스턴스란?

어떤 클래스에 속하느 각 객체를 인스턴스라고 한다.

인스턴스는 참조변수를 통해서만 다룰 수 있으며, 참조변수의 타입은 인스턴스의 타입과 일치해야한다.

클래스명 변수명;                   //클래스의 객체를 참조하기 위한 참조변수를 선언
변수명 = new 클래스명();       //클래스의 객체를 생성 후, 객체의 주소를 참조변수에 저장
Tv t;             // Tv클래스 타입의 참조변수 t를 선언
t = new Tv();  //Tv인스턴스를 생성한 후, 생성된 Tv인스턴스의 주소를 t에 저장
class Tv{
	//Tv의 속성(멤버변수)
	String color; // 색상
	boolean power; // 전원상태(on/off)
	int channel; //채널
			
	// Tv의 기능(메서드)
	void power() {power =! power;}   // Tv를 켜거나 끄는 기능을 하는 메서드
	void channelUp() {++channel;}    // Tv의 채널을 높이는 기능을 하는 메서드
	void channelDown() {--channel;}  // Tv의 채널을 낮추는 기능을 하는 메서드			
}

public class TvTest { 
	public static void main(String[] args) {
		Tv t;				//Tv인스턴스를 참조하기 위한 변수 t를 선언
		t= new Tv();		//Tv인스턴스를 생성한다
		t.channel = 7;		//Tv인스턴스의 멤버변수 channel의 값을 7로 한다
		t.channelDown ();	//Tv인스턴스의 메서드 channelDown()을 호출한다
		System.out.println("현재 채널은 "+ t.channel + "입니다.");
	}
}

 

 

 

하나의 소스파일에 여러 클래스 작성


참고 : 자바의정석
참고 : 자바의 정석

 

 

 

객체 배열


  • 많은 수의 객체를 다뤄야할때 배열로 다루면 편리할 것 이다.
  • 객체 역시 배열로 다루는 것이 가능 하다
  • 객체 배열 안에 객체가 저장되는것이 아니고, 객체의 주소가 저장 된다.
  • 객체 배열은 참조 변수들을 하나로 묶은 참조변수 배열
public class TvTest4 {
	public static void main(String[] args) {
		Tv[] tvArr = new Tv[3]; //길이가 3인 Tv객체 배열
		
		//Tv 객체를 생성해서 Tv객체 배열의 각 요소에 저장
		for (int i = 0; i < tvArr.length; i++) {
			tvArr[i] = new Tv();
			tvArr[i].channel = i + 10; // tvArr[i]의 channel에 i + 10을 저장
		}
		
		for (int i = 0; i < tvArr.length; i++) {
			tvArr[i].channelUp(); //tvArr[i]의 메서드를 호출. 채널이 1증가
			System.out.printf("tvArr[%d].channel=%d%n",i,tvArr[i].channel);
		}
	}
}
class Tv2{
	// Tv의 속성(멤버변수)
	String color;  //색상
	boolean power; //전원상태(on/off)
	int channel;   //채널
	
	// Tv의 기능(메서드)
	void power() { power =! power;} // TV를 켜거나 끄는 기능을 하는 메서드
	void channelUp() { ++channel; } // TV의 채널을 높이는 기능을 하는 메서드
	void channelDown() { --channel; } // TV의 채널을 낮추는 기능을 하는 메서드
}

 

 

 

변수와 메서드


변수의 종류 선언위치 생성시기
클래스변수
(class variable)
클래스영역 클래스가 메모리에 올라갈 때
인스턴스 변수
(insiance variable)
인스턴스가 생성되었을 때
지역변수
(local variable)
클래스 영역 이외의 영역
(메서드 생성자, 초기화 블럭 내부)
변수 선언문이 수행되었을때

 

class Variables
{
	int iv;          //인스턴스 변수
    static int cv;   //클래스 변수(static변수)
    
    void method()
    {
    	int lv = 0;   // 지역 변수
    }
}

 

 

 

클래스 변수와 인스턴스 변수


- 인스턴스 변수는 개별로 값을 넣을 때 사용하는것이다.

- 클래스 변수는 공통으로 값을 넣을 때 사용하는것이다.

class Card{
//개별
	String kind; //무늬
	int number; // 숫자
//공통
	static int width = 100; // 폭
	static int height = 250; //높이
인스턴스변수는 인스턴스가 생성될 때 마다 생성되므로 인스턴스마다 각기 다른 값을 유지할수 있지만,
클래스 변수는 모든 인스턴스가 하나의 저장공간을 공유하므로, 항상 공통된 값을 갖는다.

 

 

 

메서드


  • 메서드는 특정 작업을 수행하는 일련의 문장들을 하나로 묶은 것이다.

 

 

 

메서드의 장점


  1. 높은 재사용성
  2. 중복된 코드를 제거
  3. 코드의 관리가 쉽다
  4. 코드가 간결해서 이해하기 쉬워진다.

메서드 = 선언부 + 구현부

 

 

 

JVM의 메모리구조


JVM이 운영되면서 운영체제로 부터 부여 받은 메모리 영역

    1. 메서드영역(method area)
      • 모든 쓰레드가 공유하는 영역이며 JVM이 시작될 때 생성된다. 클래스와 인터페이스의 메소드에 대한 바이트코드, 전역변수(클래스 변수), 런타임 상수 풀이 위치한다.
    2. 힙(heap)
      • 인스턴스가 생성되는 공간, 프로그램 실행 중 생성되는 인스턴스는 모두 이곳에 생성된다. 즉, 인스턴스변수들이 생성되는 공간이다.
    3. 호출스택(call stack 또는 execution stack)
      • 스택(stack): 메서드 수행에 필요한 메모리가 제공되는 공간, 종료되면 해제
      • 기본 자료형에 해당되는 지역변수의 데이터의 값이 저장되는 공간이 Stack영역이다.
    4. Static(스태틱 메모리 영역)
      • 필드부분에서 선언된 변수(지역변수)와 정적 멤버변수(Static이 붙은 자료형) Static영역에 데이터를 저장한다.
      • 프로그램의 시작부터 종료가 될 때까지 메모리에 남아있게 된다.

 

 

 

기본형 매개변수


  • 자바에서는 메서드를 호출할 때 매개변수로 지정한 값을 메서드의 매개변수에 복사해서 넘겨준다.
  • 매개변수의 타입이 기본형(primitive type)일 때는 기본형 값이 복사되겠지만, 참조형(reference type)이면 인스턴스의 주소가 복사된다.
  • 메서드의 매개변수를 기본형으로 선언하면 단순히 저장된 값만 얻지만, 참조형으로 선언하면 값이 저장된 곳의 주소를 알 수 있기 때문에 값을 읽어 오는 것은 물론 값을 변경하는 것도 가능하다.
  • 기본형 매개변수 - 변수의 값을 읽기만 할 수 있다. (read only)
  • 참조형 매개변수 - 변수의 값을 읽고 변경할 수 있다.(read & write)

 

 

 

재귀함수


메서드의 내부에서 메서드 자신을 다시 호출하는 것을 '재귀호출' 이라한다.

왜? 굳이 반복문대신 재귀호출을 사용할까?

재귀호출이 주는 논리적 간결함 때문이다.

아무리 효율적이라도 알아보기 힘들게 작성하는 것보다 다소 비효율적이더라도 알아보기 쉽게 작성하느 것이 논리적 오류가 발생할 확률도 줄어들고 나중에 수정하기도 좋다

만약 반복문으로 작성해보고 너무 복잡하면 재귀호출로 간단히 할 수 없는지 고민해볼 필요가 있다. 재귀호출은 비효율적이므로 재귀호출에 드는 비용보다 재귀호출의 간결함이 주는 이득이 충분히 큰 경우에만 사용하는것이 좋다.

class FactorialTest{
	public static void main(String [] args){
		int result = factorial(4);  // int result = FacotialTest.factorial(4);
		System.out.println(result);
	}

static int factorial (int n) {
		int result = 0;
	
		if ( n == 1) {
			result = 1;
		} else {
			result = n * factorial(n-1); // 다시 메서드 자신을 호출한다.
		}

		return result;
	}
}
```

 

 

 

Static 메서드와 인스턴스 메서드


  • 인스턴스메서드
    • 인스턴스 생성 후, '참조변수.메서드이름()'으로 호출
    • 인스턴스 멤버와 관련된 작업을 하는 메서드
    • 메서드 내에서 인스턴스 변수 사용기능
  • static메서드(클래스메서드)
    • 객체생성없이 '클래스이름.메서드()'으로 호출
    • 인스턴스 멤버와 관련없는 작업을 하는 메서드
    • 메서드 내에서 인스턴스 변수 사용불가
    • 클래스메서드 호출할때는 클래스 이름을 사용한다.
class MyMath2{
	long a, b;
	
	long add() { //인스턴스 메서드
			return a + b;
	}

	static long add (long a, long b) { //클래스 메서드(static메서드)
			return a + b;
	}
두 개의 차이점이 무엇일까?
  1. 매개변수가 다르다
  2. 첫번째 메서드는 인스턴스 메서드이고 두번째 메서드는 클래스 메서드 이다.
  3. 인스턴스 메서드는 객체를 생성 후 호출 해야하지만,
  4. static메서드는 객체 생성 없이 호출이 가능하다.
  5. static 메서드는 사용할때는 인스턴스 변수를 사용안할때 이용한다.
class MyMath2{
	long a, b; //인스턴스 변수 iv
	
	//인스턴스변수 a,b만을 이용해서 작업하므로 매개변수가 필요없다.
	long add() { return a + b;}       //인스턴스 변수
	long subtract() { return a - b;}
	long multiply() { return a * b; }
	double divide() { return a / b; }
	
	//인스턴스변수와 관계없이 매개변수만으로 작업이 가능하다.
	static long add(long a, long b) { return a + b; }
	static long subtact(long a, long b) { return a - b; }
	static long multiply(long a, long b) { return a * b; }
	static double divide(double a, double b) { return a / b; }
	}

public class MyMathTest2 {

	public static void main(String[] args) {
		//클래스메서드 호출. 인스턴스 생성없이 호출 가능
		System.out.println(MyMath2.add(200L, 100L));
		System.out.println(MyMath2.subtact(200L, 100L));
		System.out.println(MyMath2.multiply(200L, 100L));
		System.out.println(MyMath2.divide(200.0, 100.0));
		
		MyMath2 mm = new MyMath2(); //인스턴스 생성
		mm.a = 200L;
		mm.b = 100L;
		//인스턴스메서드는 객체생성 후에만 호출이 가능함.
		
		System.out.println(mm.add());
		System.out.println(mm.subtract());
		System.out.println(mm.multiply());
		System.out.println(mm.divide());
		
	}
}

 

 

 

클래스 멤버와 인스턴스 멤버간의 참조와 호출


  • 인스턴스 멤버가 존재하는 시점에 클래스 멤버는 항상 존재하지만, 클래스멤버가 존재하는 시점에 인스턴스 멤버가 존재하지 않을 수도 있기 떄문이다.
class MemberCall {
	int iv =10;
	static int cv = 20;
	
	int iv2= cv;
//	static int cv2 = iv; //에러 클래스변수는 인스턴스 변수를 사용할 수 없음
	static int cv2 = new MemberCall().iv; //이처럼 객체를 생성해야 사용가능
	
	static void staticMethod1() {
		System.out.println(cv);
//		System.out.println(iv); //에러. 클래스 메서드에서 인스턴스변수를 사용 불가
		MemberCall c = new MemberCall();
		System.out.println(c.iv); //객체를 생성한 후에야 인스턴스변수의 참조가능
	}
	
	void instanceMethod1() {
		System.out.println(cv);
		System.out.println(iv); //인스턴스메서드에서는 인스턴스변수를 바로 사용가능
	}
	
	static void stataicMethod2() {
		staticMethod1();
//		instanceMethod(); //에러. 클래스메서드에서는 인스턴스메서드를 호출 할수 없다
		MemberCall c= new MemberCall();
		c.instanceMethod1(); //인스턴스를 생성한 후에야 호출할 수 있음.
	}
	
	void instanceMethod2() { //인스턴스메서드에서는 인스턴스메서드와 클래스메서드
		staticMethod1();   //모두 인스턴스 생성없이 바로 호출이 가능하다.
		instanceMethod1(); 
	}
}

Q. Static 메서드는 static 메서드 호출이 가능한가?

A. 네

Q. Static 메서드는 인스턴스 변수 사용가능한가?

A. 아니요

Q. Static 메서드는 인스턴스 메서드 호출가능한가?

A. 아니요

Q. 왜? static메서드는 인스턴스 멤버를 쓸 수 없나요?

A. static메서드 호출시 객체가 없을 수도 있어서

 

 

 

참조자료


자바의 정석

'Language > Java' 카테고리의 다른 글

상속, 패키지, 접근 제어자  (0) 2021.09.16
Static  (0) 2021.09.12
public static void main(String[] args)  (0) 2021.09.07
final 클래스, 메소드, 변수  (0) 2021.09.07
상수와 리터럴(constant & literal)  (0) 2021.09.06