객체지향이란
객체지향 프로그래밍 = oop = objected-oriented programming -> 객체를 기반으로 프로그램을 작성하는 것 / 부품 객체를 먼저 만들고 이를 조립하여 최종 프로그램을 만드는 기법
객체지향의 특성
1) 부품화
메소드라는 부품을 이용하여 하나의 완제품인 프로그램을 만든다
이 때 메소드의 관리를 위해 연관된 메소드와 그 메소드가 사용하는 변수들을 분류하고 그룹핑하는데, 이렇게 그룹핑한 대상이 객체이다
2)은닉화(캡슐화)
- 겉으로 보일 것만 빼놓고 보여줄 필요가 없는 부분은 정보보호를 위해 숨기자(정보은닉) -> 외부의 잘못된 접근으로부터 객체를 보호함
- 사용자 인터페이스에는 꼭 보여줘야하는 것들만 꺼냄
- 외부 객체는 객체 내부 구조를 알지 못하며 객체가 노출해 제공하는 필드와 메소드만 이용 가능
- 객체의 필드,메소드(멤버)를 하나로 묶고 실제 구현 내용을 감춤
- 접근 제한자를 이용, 단 메인 메소드에는 private 사용 불가
3) 상속성
- 상속관계가 자연스러워야함 (나무는 동물이다 – x) = 상속 트리 안에서는 is-a관계가 반드시 성립해야
- 상속 기준은 기능 위주로 자르는게 좋음
- 공통 부분은 재사용 : 공유 가능한 일반화개념을 상위클래스로
- 하위객체는 상위에서 허용한 모든 멤버를 물려받아 사용
- 상위에서 정의되지 않은 멤버를 하위에서 새로 정의하거나 물려받은 메소드를 수정할 수 있음
- 상속 조건: 단순히 공통부분이 있다고 상속하는게 아니라, 물리적/개념적으로 “이다”관계가 성립될때만 사용 (is-a , is-kind of)
- 부모 클래스 상속 시에는 단일 상속만 허용(다중상속 금지) / 단 인터페이스는 다중상속이 가능함
- 상속 대상;상위 개체에서 허용한 멤버(속성과 일반 메소드) , 생성자는 아님
- 상위클래스 = 부모클래스 = 슈퍼클래스 (하위클래스들의 일반화) / 하위클래스 = 자식클래스 = 서브클래스(슈퍼클래스를 재사용하고 새로운 특성 추가)
4) 다형성 : 오버로딩 / 오버라이딩
- 같은 이름의 메소드가 클래스나 객체에 따라 다르게 동작하도록 구현하는것을 뜻함
- 오버로딩: 메소드의 이름은 같지만 인자의 형태, 수에 따라 optional하게 동작하도록 만든다 (이름이 같은 여러 개의 메소드를 허용함) (리턴타입은 구분기준이 아님! 인자로 구분함)
- 오버라이딩 : 슈퍼클래스에서 상속받은 메소드의 바디를 서브 클래스마다 각자 다르게 구현하는 것(예:소리내기 – 강아지는 멍멍 고양이는 야옹 닭은 꼬꼬댁)
인터페이스
- 특별한 형태의 클래스 (속성과 변수 없이 메소드만을 정의한 클래스)
- 확장자는 .java
- 헤더가 public class가 아니라 public interface로 쓰여짐
- 기능을 명시하기 위한 클래스(should의 의미)
- 변수가 아닌 상수는 쓸 수 있음
- 점선으로 연결되어 상위에 있기 때문에 인터페이스 타입으로 참조 가능
- 인터페이스는 생성용이 아님 (new 사용 x) = new 움직일수있는 으로 사용하지x, new 강아지를 만들어서 움직일수있는으로 참조할뿐임
- 다중상속 가능(서로 다른 상속트리의 객체도 연결가능)
- default메소드가 가능 (한군데에서만 고치면 되도록) -> 예 : 인터페이스에 공부하기 먹기 휴식하기 등의 기능이 있는데 공부와 먹기는 사람마다 다르지만 휴식은 모두 똑같이 잠을 잔다면 공부와 먹기는 바디없이 프로토타입만 만들고 휴식은 default로 만들고 바디를 작성 , 공부와 먹기는 하위객체에서 바디 작성 안하면 오류지만 휴식은 하위객체에서 바디 작성 안해도 오류 안뜸(인터페이스에서 작성했으니까)
- 인터페이스에서 바디 작성한 메소드라도 하위객체에서 오버라이딩 가능
클래스와 객체
- 클래스=설계도
- 클래스를 만든다는 것은 사용자 정의 데이터타입을 만드는 것과 같다
- 클래스 = 변수(상태) + 메소드(행동) (필드 + 메소드) / 변수와 메소드를 클래스의 멤버라고 한다
- 클래스와 인스턴스 모두 멤버를 가진다 : 원주율과 같이 생성할 객체마다 다른 값을 가질 필요가 없는 값들은 클래스의 멤버로, 객체마다 다른 값을 가져야하는 변수는 인스턴스의 멤버로 만든다
- 앞의 설명과 같이 객체마다 같은 값을 갖는 멤버들을 클래스의 멤버로 만들고 싶다면 선언시 맨 앞에 static 을 적으면 된다
- 클래스의 변수에 접근할 때 인스턴스를 통해 접근하는 방법과 클래스를 통해 접근하는 방법이 있는데, 클래스의 다른 기능은 필요없고 클래스 소속의 변수만 필요하다면 인스턴스를 별도 생성할 필요 없이 후자의 방법을 택하면 된다
- 클래스 소속의 변수는 앞의 상황 뿐만 아니라 변수의 변경 사항을 모든 인스턴스에서 공유해야 할 때도 사용한다 (특정 값을 연산에 포함시키고 싶을 때 등) -> 클래스 소속의 변수로 만들어두면 추후에 해당 변수의 값을 바꿨을 때 모든 인스턴스가 메소드 실행 시에 그 바뀐 값을 반영한다
- 인스턴스 : 클래스를 바탕으로 구현한 실제 제품 , new 키워드를 통해 생성함 (클래스를 통해 만든, 메모리 공간을 갖는 구체적 실체를 해당 클래스의 인스턴스라고 부름)
- 클래스와 인터페이스 이름은 모두 대문자로 시작
- 클래스 파일의 확장자는 .java / .java 를 컴파일해서 만들어진 바이트코드의 확장자는 .class
- 클래스를 인스턴스화 할때는 해당 클래스 타입의 변수를 만들어서 그 변수에 담는다
- 하나의 클래스를 바탕으로 서로 다른 상태를 가진 인스턴스를 만들면 서로 다른 행동을 하게된다
this 는 클래스를 통해 만들어진 인스턴스 자신을 가리킨다
4행에서 선언한 left,right에 해당하는 변수는 7,8줄 좌변의 left,right이고 이들은 전역변수로 인스턴스 내의 모든 메소드에서 접근이 가능한 반면, 6행의 매개변수로 들어간 int left,right는 메소드 내에서 선언된 지역변수이기 때문에 해당 메소드 밖에서 접근할 수 없으며 4행의 변수들과 이름은 같지만 실제로는 다른 변수이다
만약 메소드가 인스턴스변수를 굳이 참조할 필요가 없다면 ,
이 사진처럼 굳이 인스턴스를 생성하지 않고 클래스의 메소드를 이용하는 방식으로 구현할 수 있다
클래스 멤버와 인스턴스 멤버 - 멤버타입의 비교
- 인스턴스 메소드는 클래스 멤버에 접근 할 수 있다
- 클래스 메소드는 인스턴스 멤버에 접근 할 수 없다 (클래스는 언제나 인스턴스보다 먼저 존재함)예) static이 붙은 메소드에서 static이 붙지 않은 변수에 접근할 수 없음
- static이 붙은 메소드와 변수를 정적 메소드/정적 변수라고 부른다
유효범위(지역변수 전역변수)
- 메소드 안에서 선언한 변수(지역변수) 는 그 메소드가 실행될 때 만들어지고 그 메소드가 종료되면 삭제된다
- 클래스 변수와 메소드 변수가 같은 이름을 가지고 있다면 메소드 내에선 메소드변수가 우선시된다
- 지역변수와 유사하게 반복문에서 정의한 변수도 반복문 내에서만 사용이 가능하다
위의 예제는 유효범위 관련 예제이다
위와 같이 코드를 작성하였을 때, a() 메소드에서 호출되는 b()메소드는 전역변수 i와 a()메소드의 지역변수 i중 무엇을 사용할까?
정답은 클래스 변수를 사용한다 ! 메소드 호출 시에는 메소드 내(b)에 지역변수가 존재하지 않는다면 그 메소드가 소속된 클래스의 전역변수를 사용하게 된다 (만약 5행을 주석처리 한다면 위의 코드는 b메소드에서 사용할 i를 찾지 못해 오류가 난다)
정적 스코프(렉시컬 스코프) : 사용되는 시점에서의 유효범위(메소드 a의 i)를 사용하는 것이 아니라 정의된 시점에서의 유효범위(전역변수 i)를 사용하는 방식을 뜻한다
메소드 안에 이미 지역변수가 있는 상황에서 전역변수를 쓰고싶다면 ? this키워드를 이용한다 !
this 키워드는 인스턴스 자신을 의미하는 키워드이고 , 인스턴스에 대한 전역의 의미를 가지기 때문에 8행은 20을 출력하지만 9행은 10을 출력한다
'언어 공부 내용 정리 > Java' 카테고리의 다른 글
자바 컴파일과 클래스, API (0) | 2023.06.17 |
---|---|
자바 객체지향(2) (ing) (1) | 2023.06.16 |
자바 메소드 (0) | 2023.06.07 |
자바 문자열(String) 주요 메소드 (3) | 2023.06.02 |
자바 문자열(String) / 스택(stack)과 힙(heap) (0) | 2023.05.26 |