java OOP (Object-Oriented Programming)
자바언어 :
1. 운영체제에 독립적이다.
2. 객체지향 언어이다.
-코드의 재사용성이 높다. (새로운 코드를 작성할때 기존 코드를 이용해 쉽게 작성 가능)
-코드의 관리가 용이하다.(코드간의 관계를 이용해 쉽게 코드를 변경할 수 있다.)
- 신뢰성이 높은 프로그래밍이 가능하다.(데이터 보호,코드의중복제거)
3. 배우기 쉽다.
- 간결하고 명료한 객체 지향적 설계
4. 자동 메모리 관리
- JVM의 자동관리로 인해 프로그래밍에 집중할 수 있도록 함.
5. 네트워크와 분산처리, 멀티 쓰레드를 지원한다.
- 라이브러리 제공으로 인해 구현이 쉽우며, 여러 쓰레드에 대한 스케쥴링은 자바 인터프리터가 담당한다.
6. 동적로딩
- 필요한 시점에 클래스를 로딩하여 사용가능
- 일부 클래스가 변경되어도 전체 어플리케이션을 다시 컴파일 하지 않아도 됨
- 어플리케이션 변경사항이 발생하여도 비교적 적은 작업으로 처리할 수 있는 유연한 어플리케이션을 작성할 수 있음
1. 클래스
1) 클래스란 무엇인가?
- 정의 : 객체를 정의해 놓은것, 객체생성하기 위한 틀, 속성과 기능으로 정의, 데이터와 함수의 결합
- 용도 : 객체를 생성하는 것
2) 객체란?
- 정의: 실제로 존재하는 것, 사물 또는 개념
- 용도 : 객체가 가지고 있는 기능과 속성에 따라 다름
- 유형의 객체 : 자동차, 의자, 책상 등
- 무형의 객체 : 수학공식, 프로그램 에러와 같은 논리나 개념
3) 객체와 인스턴스
- 클래스로부터 객체를 만드는 과정을 클래스의 인스턴스화 라고 함
- 어떤 클래스로부터 만들어진 객체를 그 클래스의 인스턴스라고 함
- 객체는 모든 인스턴스를 대표하는 포괄적인 의미를 갖고, 인스턴스는 어떤 클래스로부터 만들어진 것인지를 강조하는 구체적인 의미를 가짐
4) 어떻게 사용하는가?
- 클래스명 변수명 ; //클래스의 객체를 참조하기 위한 참조변수 선언
변수명 = new 클래스명(); // 클래스의 인스턴스를 생성 후, 객체의 주소를 참조변수에 저장
class TvController{
public static void main(String[] args){
Tv t; //Tv 클래스 타입의 참조변수 t를 선언
t = new Tv(); // Tv인스턴스를 생성한 후 , 생성된 Tv인스턴스 주소를 t에 저장
t.power(); // Tv타입의 t 참조변수를 이용하여 Tv인스턴스의 power 메소드 호출
}
}
class Tv{
boolean power;
void power(){boolean power = !power);
}
2. 메서드와 변수
1) 메서드와 변수는 무엇인가?
- 메서드 정의 : 어떤 작업을 수행하기 위한 명령문의 집합
- 메서드 용도 : 반복적으로 사용되는 코드를 줄이기 위함
-변수 : 단 하나의 값을 저장할 수 있는 저장공간(메모리)
계산을 하기 위해 변수를 사용하지 않고 값을 직접 사용할 수 도 있지만, 의미있는 이름의 변수에 값을 저장하여 사용하는 것이 더 바람직하다
2) 선언 위치에 따른 변수 종류
class Tv{
boolean power; //인스턴스 변수 - 클래스 영역
static int channel; // 클래스 변수(static 변수, 공유 변수) - 클래스 영역
void soundUp(){
int sound=7; // 지역 변수 - 메서드 영역
}
}
- 클래스 변수 :
변수 앞에 static을 붙인 변수, 모든 인스턴스가 공통된 저장(변수)공간을 공유하게 됨
클래스 변수는 인스턴스를 생성하지 않고도 언제든지 바로 사용할 수 있는 특징
'클래스이름.클래스변수'와 같은 형식으로 사용
프로그램이 종료될때까지 유지되며, public을 앞에 붙이면 같은 프로그램 내에서 어디서나 접근 할 수 있는 전역변수의 성격을 가진다.
- 인스턴스 변수 :
클래스 영역에 선언되며, 클래스의 인스턴스를 생성할때 만들어 진다.
인스턴스는 독립된 저장공간을 가지므로 서로 다른 값을 가질 수 있다.
- 지역 변수:
메서드에서 선언되며, 메서드 내에서만 사용될 수 잇다.
지역변수는 반드시 초기화를 해줘야 한다.
메서드가 종료되면 같이 소멸되며, for, while문에서 사용된 지역변수는 지역변수가 선언된 {}내에서만 사용된다.
변수의 종류
선언 위치
생성시기
클래스 변수
클래스 영역
클래스가 메모리에 올라갈 때
인스턴스 변수
인스턴스가 생성되었을때
지역 변수
클래스 영역 이외의 영역
(메서드, 생성자, 초기화 블럭 내부)
변수 선언문이 수행되었을때
3) 어떻게 사용해야되는가?
- 하나의 메서드는 한가지의 기능만 수행하도록 수행하는게 좋다.
- 반복적으로 수행되어야 하는 여러 문장을 하나의 메서드로 정의해 놓으면 좋다.
- 관련된 여러 문장을 하나의 메서드로 만드는것이 좋다.
4) 메서드 작성방법
- 리턴타입 메서드이름 (타입 변수명, 타입 변수명, ...) { 메서드 호출시 수행될 코드..}
- int add(int a, int b){ // 선언부 : 리턴타입 int, 메서드 이름 add(타입 int 변수명 a, int b)
int result = a+b; //메서드 호출시 수행되는 코드 a+b의 결과값을 result에 저장
return result; // 호출한 곳으로 result값 반환
}
5) 메서드 호출방법
- 참조변수. 메서드 이름(); // 메서드에 선언된 매개변수가 없는 경우
- 참조변수.메서드 이름(값1, 값2, ...) //메서드에 선언된 매개변수가 있는 경우
- 위의 1-4의 예저의 t.power(); 는 t라는 참조변수를 이용하여 power() 메서드를 호출하고 있음
3. 오버로딩
1) 오버로딩은 무엇인가?
- 한 클래스 내에 같은 이름의 메서드를 여러개 정의하는 것.
2) 어떤 경우에 왜 사용하는가?
- 내용(코드)은 다르지만, 의미상 같은 일을 하는 메서드가 있을때(메서드의 이름이 같다는 것은 의미상 같은 일을 한다는 것을 뜻함)
- 메서드의 이름을 절약할 수 있다. 하나의 이름으로 여러개의 메서드를 정의할 수 있기 때문이다.
3) 어떻게 사용하는가?
- 메서드 이름이 같아야 한다.
- 매개변수의 개수 또는 타입이 달라야한다.
- 리턴타입은 오버로딩 구현하는데 아무러 영향을 주지 못한다.
int add(int a, int b){}
long add(long a, long, b){}
4. 생성자
1) 생성자란 무엇인가?
-정의 : 인스턴스가 생성될 때 호출되는 '인스턴스 초기화 메서드'이다.
-용도 : 인스턴스 변수의 초기화 작업에 주로 사용되며, 인스턴스 생성시에 실행되어야 할 작업을 위해 사용된다.
2) 어떻게 사용하는가?
- 생성자의 이름은 클래스의 이름과 같아야 한다.
- 생서자는 리턴값이 없다.
3) 인스턴스 생성시 참고
- 클래스 : 어떤 클래스의 인스턴스를 생성할 것인가?
- 생성자 : 선택한 클래스의 어떤 생성자로 인스턴스를 생성할 것인가?
5. 상속
1) 상속이란 무엇인가?
- 정의 : 기존의 클래스를 재사용하여 새로운 클래스를 작성하는 것
- 특징 : 코드의 재사용성을 높이고, 코드의 중복을 제거, 프로그램의 생산성과 유지보수에 기여
2) 상속 받는것은 무엇인가?
- 생성자와 초기화 블럭은 상속되지 않는다. 멤버만 상속된다.
- 자손 클래스의 멤버 개수는 조상 클래스보다 항상 같거나 많다.
3) 어떻게 사용하는가?
- 상속받고자 하는 클래스에 extends 조상 클래스
class Child extends Parent{}
- 상속 관계와 포함관계 :
class Point{int x; int y;}
상속관계 :
class Circle enxtends Point{
int r;
}
포함관계:
class Circle{ class Circle{
int x; Point c = new Point();
int y; -> int r;
int r; }
}
- 클래스간의 관계는 어떻게 설정하나?
is - a(상속관계), has - a(포함관계)를 이용한 관계 결정하기
원(Circle)은 점(Point)이다.(Cicle is a Point)
원(Circle)은 점을 가지고 있다.(Circle has a Point)
6. 오버 라이딩
1) 오버라이딩은 무엇인가?
- 정의 : 조상 클래스로부터 상속받은 메서드의 내용을 변경하는 것
- 용도 : 상속받은 메서드의 기능을 자손 클래스에 맞게 재정의해서 사용한다.
2) 오버라이딩의 조건?
- 이름이 같아야 한다.
- 매개변수가 같아야 한다.
- 리턴 타입이 같아야 한다.
- 접근 제어자는 조상 클래스의 메서드보다 좁은 범위로 변경할 수 없다.
- 조상 클래스의 메서드보다 많은 수의 예외를 선언할 수 없다.
3) 어떻게 사용하는 가?
class Point{
int x;
int y;
String getLocation(){
return "x:"+x+"y"+y;
}
class Point3D extends Point{
int z;
String getLocation(){ // 조상 클래스의 메서드 오버라이딩
return "x:"+x+"y"+y+"z"+z;
}
}
7. 접근 제어자
1) 접근 제어자란?
- 멤버 또는 클래스에 사용되어, 해당 멤버 또는 클래스를 외부에서 접근하지 못하도록 제한하는 역할
- 용도 : 외부로부터 데이터를 보호하기 위해, 내부적으로 사용되는 부분을 감추기 위해
2) 접근 제한 종류
- private : 같은 클래스 내에서만 접근이 가능하다.
- default : 같은 패키지 내에서만 접근이 가능하다.
- protected : 같은 패키지 내에서, 그리고 다른 패키지의 자손 클래스에서 접근이 가능하다.
- public : 접근 제한이 전혀 없다.
3) 제어자의 조합
- 메서드에 static과 abstract를 함께 사용할 수 없다.
static 메서는 몸통이 있는 메서드에만 사용할 수 있기 때문이다.
- 클래스에 abstract와 final을 동시에 사용할 수 없다.
클래스에 사용되는 final은 클래스를 확장할 수 없다는 의미이고, abstract는 상속을 통해서 완선되어야 한다는 뜻이기 때문
- abstract 메서드의 접근 제어자가 private일 수 없다.
abstract 메서드는 자손 클래스에서 구현해줘야 하는데 접근 제어자가 private이면, 자손클래스에서 접근할 수 없기 때문
- 메서드에 private과 final을 같이 사용할 필요는 없다.
접근 제어자가 private인 메서드는 오버라이딩 될 수 없기 때문이다. 이 둘 중 하나만 사용해도 의미가 충분하다
8. 다형성
1) 다형성이란?
- 정의 : 여러가지 형태를 가질 수 있는 능력, 한 타입의 참조변수로 여러 타입의 객체를 참조할 수 있도록 함
class Tv(){ class CaptionTv extends Tv{ class VideoTv extends Tv{
boolean power; int sound;
void power(){ sound(){ void play(){
power = !power; sound++; System.out.println("비디오 재생");
} } }
} } }
- 조상타입의 참조변수로 자손 타입의 인스턴스를 참조 할 수 없다.
Tv t = new CaptionTv();
t.power() //가능
t.sound(); // 자손 타입의 인스턴스 참조 불가
- 반대로 자손 타입의 참조변수로 조상타입의 인스턴스를 참조할 수 는 없다.
CaptionTv c = new Tv(); //컴파일 에러 (실제 자손타입의 멤버개수가 조상타입 멤버개수보다 많아 이를 허용하지 않는다.)
c.sound(); // 이렇게 존재 하지 않는 멤버를 사용할 가능성이 있어 이를 허용하지 않는다.
2) 참조변수의 형변환
Tv t;
CaptionTv c = new CaptionTv();
- 자손타입 -> 조상타입(형변환 생략 가능)
t = c; // 형변환 생략 가능
- 조상타입 -> 자손타입(형변환 생략 불가)
c = (Tv)t; // 형변환 생략 불가능
Tv t = new CaptionTv() // 이것 또한 (Tv)가 생략된 형태이다. 자손타입 => 조상타입
- 형변환은 참조변수의 타입을 변환하는 것이기 때문에 인스턴스에는 아무런 영향을 미치지 않는다.
- 참조변수 형변환을 통해, 참조하고 있는 인스턴스에서 사용할 수 있는 멤버의 범위(개수)를 조절하는 것 뿐이다.
3) instanceof 연산자
- 참조변수가 참조하고 있는 인스턴스의 실제 타입을 알아보기 위해 instance를 사용한다.
void Work(Tv t)
if( t instanceof CaptionTv){
CaptionTv c = (CaptionTv)t;
c.sound();
}else if(t instanceof VideoTv){
VideoTv v = (VideoTv)t;
v.play();
}
}
- 매개변수로 Tv 타입의 t를 받아 t 가 참조하고 있는 인스턴스가 CaptionTv인지 VideoTv인지 확인 후에 해당 자손타입으로 형변환한 후 자손타입의 메서드를 호출하고 있다.
4) 참조변수와 인스턴스 연결
public class test0310 {
public static void main(String[] args) {
Parent p = new Child();
System.out.println("p.x="+p.x);
p.method();
}
}
class Parent{
int x = 100;
void method(){
System.out.println("parent method");
}
}
class Child extends Parent{
int x = 500;
void method(){
System.out.println("x="+x);
System.out.println("this.x = "+this.x);
System.out.println("super.x ="+super.x);
}
}
- 조상타입의 참조변수 p로 x를 호출(p.x)를 호출하면, Parent의 x=100이 나오며(조상타입의 참조변수로는 자손타입의 멤버를 사용할 수 없다.), 메서드인 method()의 경우 참조변수 타입에 관계없이 항상 실제 인스턴스 타입인 Child클래스에 정의된 method() 메서드를 호출한다.
- 인스턴스 변수인 x는 참조변수의 타입에 따라서 값이 달라진다.
Child c = new Child();
System.out.println("c.x="+c.x);
결과 : c.x=500
5) 매개변수의 다형성, 여러종류의 객체를 하나의 배열로 다루기
- 매개변수의 다형성 :
class Tv{ class CaptionTv extends Tv{ class VideoTv extends Tv{
int price super(10000); super(500)
Tv(int price){ } }
this.price = price
}
}
void buy(Tv t){ // 매개변수로 CaptionTv 또는 VideoTv를 받는다.
money = money - t.price;
}
- 여러종류의 객체를 하나의 배열로 다루기
Tv t[] = new Tv[3];
t[0] = new CaptionTv();
t[1] = new VideoTv();
9. 추상클래스(abstract class)
1) 추상클래스란?
- 클래스를 설계도에 비유한다면 추상클래스는 미완성 클래스로 비유할 수 있다.
- 새로운 클래스를 작성하는데 있어 바탕이 되는 조상클래스로서의 중요한 의미
- 추상클래스로 지정되면 인스턴스를 생성할 수 없다.
- abstract class 클래스 이름 // 클래스 이름 앞에 'abstract'를 붙임
2) 추상 메서드
- 선언부만 작성하고, 구현부는 작성하지 않은 상태
10. 인터페이스
1) 인터페이스란?
- 추상 클래스보다 추상화가 높으며, 오직 추상 메서드와 상수만을 멤버로 가질수 있다.
- 다른 클래스를 작성하는데 도움 줄 목적으로 작성된다.
- interface 인터페이스 이름{
public static final 타입 상수이름 = 값;
public abstract 메서드이름(매개변수 목록);
}
- 모든 멤버변수는 public static final 이어야 하며, 이를 생략할 수 있다.
- 모든 메서드는 public abstract 이어야 하며, 이를 생략할 수 있다.
- 개발시간을 단축시킬수 있다.
- 표준화가 가능하다.
- 서로 관계없는 클래스들에게 관계를 맺어줄수 있다.
- 독립적인 프로그래밍이 가능하다.
public class test0310 {
public static void main(String[] args) {
ProductFun pf = new ProductFun();
pf.ProductPlay(new Tv());
pf.ProductPlay(new Video());
}
}
class ProductFun{
void ProductPlay(playInter p){
p.play();
}
}
class Tv implements playInter{
public void play(){
System.out.println("tv paly~~`");
}
}
class Video implements playInter{
public void play(){
System.out.println("video play~~");
}
}
interface playInter{
void play();
}
- 인터페이스 playInter는 실제 구현 내용(Tv, Video)을 감싸고 있는 껍데기 이며, 클래스 ProductFun은 껍데기 안에 어떤 알맹이(클래스)가 들어 있는지 몰라도 된다.