OOP (Object Oriented Programming)
- 기존의 절차지향 프로그램은 데이터와 함수 간에 유기적인 관계성 X
- 객체 : 현실 세계에 존재하는 유무형의 모든 것
- 정적인 요소 : 변수
- 동적인 요소 : 메서드
- 클래스 : 현실 세계의 객체를 컴퓨터 매모리에 생성 할 수 있는 템플릿
- 인스턴스 : 클래스로부터 생성된 메모리상의 객체
- Object == Instance
Car myCar = new Car()
- 코드의 재사용성 높이는 객체 지향의 핵심!
- 상속을 통해 객체들 간에 계층 구조 이룸
extends
예약어 사용 :public class 아들 extends 아빠
- 자바는 단일 상속만을 지원한다
- 하나의 인터페이스를 이용해 서로 다룬 구현을 제공
- 메서드 오버로딩과 오버라이딩을 통해 지원
- Overloading : 한 클래스 안에 인자의 갯수와 유형은 다르고 같은 이름을 가진 메서드를 여러개 정의하는 형태
- Overriding : 하위 클래스가 상위 클래스 메서드를 재정의 하는 것
- 구체적인 사실들을 일반화시켜 기술하는 것 (공통된 특성을 일반화)
- 클래스 정의하는데 주요한 역할
- 변수와 메서드를 하나의 추상화된 클래스로 묶는 과정
- 독립적으로 동작하지 않도록 함
- Public
- Private
- 객체 간에 서로 통신하는 방법
- 여러 객체는 동일한 프로세스를 갖을 필요 X
- 대상 객체 + 메시지 + 부가 정보 :
car.changeGear(lowerGear)
-
객체 지향 : 모든 프로그램을 객체로 생성
-
Acces modifier
-
Constuctor : 객체의 초기화
-
Variable : 클래스의 속성 정의
-
Method : 클래스의 데이터 조작 및 변화
public class 클래스명 [extends 부모 클래스명]{
public 클래스명(arg[]) {} // 생성자, 클래스로부터 객체 생성
public 데이터타입(data_type) 변수명 [=초기값]; // 클래스의 변수 선언
public return_type 메서드명(arg[]) {} // 클래스의 메서드 선언
}
- 접근 권한 예약어
- public : 모든 클래스에서 접근 가능, 서로 다른 패키지의 클래스에서 접근하기 위해서는 지정 필요
- protected
- private
- (default) : 같은 패키지내의 클래스에서만 접근 가능
- 활용 방법 예약어
- final : 자식 클래스를 가질 수 없는 클래스
- abstract : 객체 생성이 불가능한 추상 클래스
- static
- transient
- volatile
- synchronized
- native
- Unified Modeling Language : sw 개념을 다이어그램으로 그리기 위해 사용하는 시각적 표기법
- 객체지향 프로그램 시각화, 시스템 사양 설계를 문서화
- 클래스간의 관계 그림으로 표현
- 3가지 영역의 직사각형으로 표기
- 클래스 이름
- 변수
- 메서드
- 자바의 변수
- 기본형 변수
- 참조형 변수 : 배열 객체, 일반 클래스 객체
- 객체 참조 변수의 선언
- int[] scoreList;
- Car Avante;
- 객체 생성 및 주소값 할당
- scoreList = new int[5];
- Avante = new Car();
- Car Avante = new Car();
- 클래스이름 객체참조변수이름 = new 클래스이름();
- 객체 참조 변수의 선언
- 멤버 변수의 선언
- 전역 변수
- 클래스 선언부 밑에 선언된 변수, 멤버 변수
- 여러 메서드에서 공통으로 사용가능
- 객체가 가질 수 있는 속성을 나타냄
- 지역 변수
- 메서드 선언부 밑에 선언된 변수
- 해당 변수가 선언된 메서드 내에서만 사용가능
- 전역 변수
- 멤버 변수 Modifier
- public
- protected : 동일 패키지 클래스 + 하위 클래스의 접근 가능
- private : 변수가 선언된 클래스내에서만 접근 가능
- final : 상수로 사용
- static : 클래스에 소속된 클래스 변수를 의미
- 캡슐화(변수+메서드를 하나의 클래스로) + 접근 제한자로 정보 은닉 구현
- 일종의 Function, 클래스가 제공할 로직들을 정의
접근제한자 리턴타입 메서드명(int num1, 매개변수들) { 메서드 실행 코드 }
메서드명(4, 인자Argument)
- 메서드 활용을 통해 코드 재사용성이 증대
- 리턴값 X, 매개변수 X
public void printCarInfo() { System.out.println(name); }
- 리턴값 X, 매개변수 O
public void setData(String name, int speed) { this.name = name; this.speed = speed; }
- 리턴값 O, 매개변수 O
public String changeCarInfo(Strinf name, int speed) { this.name = name; this.speed = speed; return name + speed; }
- 메서드의 자동 구현
- 멤버 변수 : private 선언, public 메서드를 통해 접근하도록 클래스 구현 => 정보 은닉의 구현
- private 변수 저장된 값을 리턴 :
Getter 메서드
- private 변수 값을 저장 :
Setter 메서드
alt+shift+s
=> 팝업 메뉴에서Generate Getters and Setters
선택 =>Select All / Getters / Setters
선택alt+shift+s
=> 팝업 메뉴에서Generate toString
선택 => Ok- 생성된 객체의 상태를 쉽게 확인 가능
System.out.println(car.toString())
==System.out.println(car)
: 내부적으로 toString() 호출
- 인스턴스 변수 : static 예약어가 붙지 않는 변수
- 생성된 인스턴스마다 클래스의 인스턴스 변수들이 포함됨
- 일반적인 멤버 변수를 인스턴스 변수라고 부름
- 클래스 변수 : static 예약어가 붙는 변수
- 클래스로부터 생성된 인스턴스에 포함되지 않는 변수
- 클래스가 로딩되는 과정에서 메모리에 한번만 할당되는 변수
- 클래스 변수의 값이 변경된 경우, 모든 객체에서 변경된 값을 사용 가능함
- 객체를 생성하지 않고도 접근할 수 있는 변수, 클래스 이름을 통해서 접근 (객체 통해서도 접근 가능)
- 동일한 값을 갖는 변수를 클래스 변수로 설정
- System.out : System클래스의 out 클래스 변수
- 클래스 메서드
- 인스턴스 변수, 메서드 사용 불가 : 인스턴스를 생성하지 않고 호출이 가능하기 때문
- 클래스 변수, 메서드만 호출 가능
- Integer.parseInt : Integer클래스의 parseInt 클래스 메서드
- final + 변수 : 변경 금지 => 상수 선언
- 이름 규칙 : 대문자 사용, 여러 단어
_
사용, ex :COMPANY_NAME
- 이름 규칙 : 대문자 사용, 여러 단어
- final + 메서드 : 메서드 재정의 금지
- final + 클래스 : 상속 금지
- abstract + 클래스 : 추상클래스
- abstract + 메서드 : 추상메서드
- 추상 메서드란 메서드의 시그니처만 정의되고, 행동 (블록) 부분은 정의되지 않은 메서드를 의미
- 시그니처 : 리턴 타입, 메서드명, 매개변수
- 추상 메서드를 포함한 클래스는 추상 클래스로 선언되어야 함
- 단, 추상 클래스가 추상 메서드를 포함하지 않을 수 있음
- 추상 메서드란 메서드의 시그니처만 정의되고, 행동 (블록) 부분은 정의되지 않은 메서드를 의미
- 추상 기능 : 상속과 연관
- 부모클래스의 추상 메서드 => 자식클래스에서 재정의
- 클래스로부터 객체를 생성할 때 호출
- 객체의 멤버 변수를 초기화하는 메서드
int[] scoreList = new int[5];
- 자바의 모든 객체는
new
객체 생성 연산자를 통해서 생성 - 배열에 필요한 값들을 초기화
- 자바의 모든 객체는
- 초기화 과정의 단순화
int[] scoreList = {1, 2, 3, 4, 5};
Employee jang = new Employee("장현준", 31, "전자과", "010-3221-3395");
- 클래스와 같은 이름을 가진 메서드
- 객체 생성 시 멤버 변수의 초기화를 담당
- 반환형 X, void도 허용되지 않음
- 매개변수를 달리하여 여러 개를 중복정의 (Overloading) 가능
new
키워드와 함께 사용- 명시적으로 작성하지 않을 경우, 기본 생성자(매개변수X)가 제공됨
- 멤버 변수 초기값
- 0 : byte, short, int
- 0L : long
- 0.0F : float
- 0.0D : Double
\u0000
: char- false : boolean
- null : 참조형
- 멤버 변수 초기값
- 이클립스 자동 생성
alt + shift + s
=> 팝업 메뉴 =>Generate Constructor using Fields
선택
- 생성자나 메서드의 매개변수 이름이 객체 변수의 이름과 같을때
- 객체 변수 이름 앞에 this를 사용하여 구별
- 변수 : 데이터 타입이 달라도 동일한 이름은 불가 ∵ 프로그램이 모호해지기 때문
- 메서드 : 하나의 클래스에 동일한 이름의 정의 허용 ∵ 오버로딩
- 정의 : 하나의 클래스에 동일한 이름의 메서드가 여러 개 중복 정의 하는 것
- ∵ 매개변수 갯수와 타입을 통해 실행된 메서드 구분이 가능
- 자바같은 객체지향 언어에서 제공되는 문법
- 데이터타입별로 다른 수행하는 메서드 통해 코드 재사용성 증대
- ex)
System.out.println()
- ex)
- 매개변수의 갯수와 타입이 모두 다른 경우 : O
리턴 타입이 다른 경우: 오버로딩에서 리턴타입은 무시, 불가매개변수의 이름이 다른 경우: 매개변수는 외부로부터 값을 받기 위한 이름임- 매개변수의 갯수와 타입이 같지만 순서가 다른 경우 : O
- 매개변수가 형변환된 다른 타입인 경우
class Ov {
void calc(double d) { ... }
}
public class Test {
public static void main(String[] args) {
Ov ov = new Ov();
ov.calc(45); //int => double로 묵시적 형변환
}
}
- 목적 : 클래스로부터 객체 생성시 필요한 변수들만 적절히 초기화하기 위해
- 구분 : 매개변수 갯수와 타입 or 순서
- this 예약어 : 생성자 or 메서드의 매개변수의 이름과 객체 변수의 이름과 동일할때, 객체 변수 이름 앞에 this를 사용하여 구별
- this () 생성자 : 같은 클래스 내의 오버로딩 된 다른 생성자 메서드를 호출할 때 사용
public Employee() {
this.name = "Anonymity";
this.age = 0;
this.salary = 0;
}
public Employee(int age, String name){
this.age = age;
this.name = name;
}
//public Employee(int age, String name, int salary){
// this.age = age;
// this.name = name;
// this.salary = salary;
//}
// this()를 이용한 중복코드 최소화
public Emplyee(int age, String name, int salary){
this(age, name);
this.age = age;
}
- 메서드 호출 시, 객체 간 메시지가 전달될때 담긴 부가정보
- 매개변수가 기본형이냐 참조형이냐에 따라 다른 동작
-
값 복사
- 기본형 : 두 개의 변수에 같은 값이 저장됨 => 독립적
- 참조형 : 두 개의 변수에 같은 주소 값이 저장됨 => 의존적
-
- 메서드 호출 시 매개변수 값이 복사 됨
- 메서드의 인자값 변동 되어도 영향 X
- 메서드 수행에 필요한 값만 넘길때 활용
-
- 메서드 호출 시 객체의 주소 값이 복사
- 같은 객체의 주소를 같음 => 하나의 객체를 두 개의 참조변수가 공유
- 하나의 참조변수에서 객체의 값을 수정하면, 다른 참조변수에도 변경된 객체의 값이 인식
- 메서드 수행 이후에도 수행 결과를 유지하고자 할때 활용
매개변수 갯수가 지정되어야만 하는 제한을 극복하기 위함
...
활용
- 하나의 메서드만 정의, 매개변수의 갯수를 가변적으로 활용
public sum(데이터타입... 변수명){ 실행코드 }
- 매개변수 리스트 마지막 위치에 한 번만 사용가능
extends
예약어 사용- 기본 클래스를 확장 => 새로운 클래스 정의
- 변수와 메서드를 상속
- 관리자 : 사원 + @
class 관리자 extends 사원 { +@ 선언 }
- 상속을 통해 소스코드의 재사용성 보장
- 관리자만의 특성 @를 쉽게 찾을 수 있다 = 가독성
- 상속에서 논리적으로
~ is a ~
의 관계여야 한다.
- 하나의 클래스는 오직 하나의 부모 클래스만 상속
- ∵개발의 편의성과 가독성
- 다중상속
- 전자제품 + 자동차 => 전기자동차
- 중복 변수 or 메서드 상속 문제 발생 => 다중상속 불허로 근본적 차단
- 부모 클래스 생성자 초기화 수행 => 자식 클래스의 초기화
- 명시되지 않으면 자동 호출 되는 생성자는 매개변수 없는 기본 생성자
- 이때 부모 클래스에 기본 생성자가 없으면
에러
-
this() 생성자와 유사한 역할
- this : 클래스 안, 오버로딩 된 또 다른 생성자 호출
- super : 부모 클래스 중, 오버로딩된 여러 생성자 중 특정 생성자 호출
-
호출 위치 : 반드시 첫 번째 라인
- ∵ 부모 클래스의 생성자가 자식 클래스보다 먼저 수행되어야 함
- private 변수
- 부모 클래스의 변수와 같은 이름의 인스턴스 변수
- 부모 클래스의 변수와 같은 이름의 클래스 변수
- this
- 생성된 객체 자신에 대한 참조
- 멤버 변수, 메서드 매개변수 이름이 같을때, 구분
- super
- 부모 객체에 접근 가능한 참조변수
- 부모 클래스의 메서드를 재사용 않고 새롭게 정의
- 메서드 오버로딩과 비교 : 하나의 클래스, 동명의 메서드 다수 정의
- 부모 클래스의 메서드와 매개변수 유형 및 갯수가 동일해야함
- 동일하지 않으면 오버로딩됨
- 메서드 재정의 & super로 기능 상속
- 변수 : 상수
- 클래스 : 자식 클래스 가질 수 없는 클래스
- 메서드 : 오버라이딩 금지
- abstract + 메서드 : 추상 메서드로 정의
- 추상 메서드 : 시그니쳐(리턴타입, 메서드명, 매개변수)만 정의, 블록 부분은 정의 X 메소스
- 시그니처가 선언 되었기때문에 기본적인 기능 유추 가능
- 추상 메서드 : 시그니쳐(리턴타입, 메서드명, 매개변수)만 정의, 블록 부분은 정의 X 메소스
- 의미가 없는 추상 메서드 => 상속을 통해 의미 부여
- 추상 메서드를 포함하는 클래스는 추상 클래스로 선언 되어야함
- 객체 생성 불가
- 객체 생성 => 객체 참조 변수 => 추상 메서드 호출 => 아무 기능 없는 추상메서드가 호출되었음 => 불가
- 클래스 => 객체 생성이 목표
- 유지 보수를 위해 사용
- 모든 클래스에서 메서드 시그니처 통일 불가 => 추상 클래스 => 모든 클래스에서 메서드 통일
- 클래스는 데이터 표현의 기본 단위
- 멤버 변수, 메서드로 구성
- 클래스가 다른 클래스를 포함 => 내부 클래스
- 목적 : 파일 크기 최소화, 보안, 성능 향상. 이벤트 처리
- 멤버 클래스 : 멤버 변수와 동일한 위치에 선언된 내부 클래스, static 멤버, instance 멤버로 나뉨, 멤버 변수와 비슷
- 지역 클래스 : 메서드 내 클래스 정의 O, 지역 클래스와 무명 클래스로 나뉨, 지역 변수와 비슷 (활동 범위 : 메서드 블록 제한)
- 외부 클래스에서 접근 가능
- 외부 클래스 객체 생성 후 내부 클래스 객체 생성 가능
외부클래스명$내부클래스명.class
- statice + 내부 클래스 : 외부 클래스 객체 생성 없이, 내부 클래스 객체 생성 가능
- 메서드 내부에서 정의된 클래스
- 지역 변수와 동일한 범위 가짐
- 외부 클래스 객체 생성 후 내부 클래스 객체 생성 가능
외부클래스명$1$지역내부클래스명.class
class classA {
void methodB() {
class classB {
}
}
}
public class InnerClassTest {
public static void main(String args[]){
Outside outer = new Outside();
Outside.Inside inner = outer.new Inside();
}
}
- 이름을 갖지 않는 내부 클래스
- new 예약어 뒤에 명시된 클래스가 기존의 클래스인 경우, 자동적으로 이 클래스의 자식 클래스가 됌
- 추상 클래스의 객체를 내부 클래스 형태로 생성시 사용됌
- 추상 클래스는 추상 메서드를 포함 => 객체 생성 불가 => 이름이 없는 지역 내부 클래스로 만들어 사용하는 것이 편리
- 활용도 높음
// 이름이 없는 내부 클래스로 구현
abstract class TV {
public abstract void powerOn();
}
public class AnonymousTest {
public static void watchTV(TV tv) {
tv.powerOn();
}
public static void main(String args[]) {
watchTV(new TV() {
public void powerOn() {
System.out.println("TV 전원 On")
}
}
}
}
// 이름이 있는 독립된 클래스로 구현
abstract class TV {
public abstract void powerOn();
}
public class AnonymousTest extends TV {
public void powerOn(){
System.out.println("TV 전원 On");
}
}
- 묵시적 형변환 : 자동 형변환
- 명시적 형변환
- 객체 형변환
- 객체 참조변수도 형변환이 일어난다
leftObjRef = rightObjRef
- 서로 다른 객체 유형일 경우 상속 관계에 있다 (상속관계에 있어야한 형변환이 발생한다)
- 왼쪽 객체가 상위 클래스 : 묵시적 형변환
- 오른쪽 객체가 상위 클래스 : 명시적 형변환
- 단, 이 경우 할당되는 인스턴트 유형에 따라서 실행오류 발생
instanceof
: 생성된 객체가 class와 관계있는 type인지 확인
- m instance of Manager : true
- m instance of Employee : true
- e instance of Manager : false
Father f1 = new Father();
: OSun s1 = new Sun();
: OFather f2 = new Sun()
: 에러Sun s2 = (Sun) f2;
: O
// TV 객체를 생성하여 리턴하는 TVFactory 클래스
class TVFactory {
// TV 타입으로 묵시적 형변환되며 리턴됨
public TV TVgetTV(String tvName) {
if(tvName.equals("A사")) {
return enw S_TV();
} else if(tvName.equals("B사")) {
return new L_TV();
}
return null;
}
}
public class AbstractTVUser {
public static void main(String[] args) {
// S_TV tv = new S_TV();
// L_TV tv = new L_TV();
// 위 코드는 TV 객체가 변경 될때마다 코드 수정 요구됨
TVFactory factory = new TVFactory();
TV tv = factory.getTV(args[0]);
tv.powerOn();
}
}
- 형변환에 참여한 서로 상속 관계에 있는 두 클래스
- 동일한 이름의 변수가 존재, 메서드 오버라이딩 되어 있을때
- 생성된 객체 변수를 통해 멤버에 접근 시 주의
class Parent {
int num = 10;
void printNum() {
System.out.println(num);
}
}
class Child extends Parent {
int num = 20;
}
public class ObjectcastTest {
public static void main(String args[]) {
Parent p = new Parent();
p.printNum();
System.out.println(p.num);
Child c = new Child();
c.printNum();
System.out.println(c.num);
Parent p = new Child();
p.printNum(); // 20 => 변수에 대한 접근은 객체의 유형에 의해 결정
System.out.println(p.num); //10 => 메서드 호출은 할당되는 인스턴스에 의해 결정
}
}