🌱 오늘의 주제 : 객체지향 프로그래밍 규칙 총 정리 (2)
🌱 객체지향 프로그래밍 (2)
- 상속: 기존의 클래스를 재사용하여 새로운 클래스를 작성하는 것.
- 장점 - 적은 양의 코드로 새로운 클래스 작성 가능. 코드의 추가 및 변경이 매우 용이함. 프로그램 생산성과 유지보수에 좋음.
- 구현하는 법 - 자손 클래스 이름 extends 조상 클래스 이름
- class Child extends Parent { }
- 조상 클래스가 변경되면 자손 클래스는 자동적으로 영향을 받게 된다. 반대로, 자손 클래스가 변경되는 것은 조상 클래스에 영향을 주지 못한다.
- 자손 클래스는 조상 클래스의 모든 멤버를 상속받는다. (생성자와, 초기화 블럭은 상속 안됨)
- 자손 클래스의 멤버 개수는 조상 클래스보다 항상 같거나 많다.
- 단일 상속만 허용.
- 클래스 간의 관계 - 포함관계 : 상속이외에도 클래스를 재사용하는 또 다른 방법, 한 클래스의 멤버변수로 다른 클래스 타입의 참조변수를 선언하는 것 // 상속보다 많이 사용. (90%)
- class Circle { Point c = new Point(); int r; }
- 클래스 간에 관계 결정하기
- 상속 관계 - ~은 ~이다. (is - a)
- 포함 관계 - ~은 ~을 가지고 있다. (has - a)
- Object 클래스 - 모든 클래스의 조상
- 모든 클래스는 Object 클래스에 정의된 멤버들을 사용할 수 있다. - 주요 메서드 : toString() , equals(Object o) 등등이 있다.
- 오버라이딩 (overriding) : 조상 클래스로부터 상속받은 메서드의 내용을 변경하는 것.
- 1. 메서드의 선언부(반환타입, 메서드 이름, 매개변수는 조상의 것과 완전히 일치 해야한다.)
- 2. 접근제어자는 조상 클래스의 메서드보다 좁은 범위로 변경 할 수 없다.
- 3. 조상 클래스의 메서드보다 많은 수의 예외를 선언할 수 없다.
- 오버로딩 (overloading) - 기존에 없는 같은 이름의 메서드를 새롭게 정의 하는 것 (new)
- 오버라이딩 (overriding) - 상속받은 메서드의 내용을 변경하는것 (change, modify)
- 참조변수 super : 상속받은 멤버와 자신의 멤버의 이름이 같을 때 super를 붙여서 구별한다.
- super() - 조상의 생성자 : 조상의 생성자를 호출.
- static : 클래스의, 공통적인 의미를 갖고 있다. 멤버변수, 메서드, 초기화 블럭에 사용 가능.
- 인스턴스를 생성하지 않고도 사용 가능.
- final : 마지막의, 변경될 수 없는 의미를 갖고 있다. 클래스, 메서드, 멤버변스, 지역변수에 사용 가능.
- abstract : 추상의, 미완성의 의미를 자고 있다. 클래스, 메서드에 사용 가능.
- 접근 제어자 : 클래스, 멤버변수, 메서드, 생성자에서 사용 가능.
- public > protected (같은 패키지 + 자손) > (default)(같은 패키지) > private(같은 클래스)
- 접근 제어자 사용 이유: 클래스의 내부에 선언된 데이터를 보호하기 위함, 내부적으로만 사용되는 부분을 감추기 위해서
- 객체지향개념의 캡슐화
- get멤버변수이름(getter) - 멤머변수의 값을 반환하는 일
- set멤버변수이름(setter) - 멤버변수의 값을 변경하는 일
- 다형성 (polymorphism) : 조상클래스 참조변수로 자손클래스의 인스턴스를 참조할 수 있는 것. 반대로, 자손타입의 참조변수로 조상타입의 인스턴스를 참조할 수는 없다.
- Tv t = new SmartTv();
- 참조변수의 형변환: 상속관계에 있는 클래스 사이에서만 가능, 즉, 자손타입의 참조변수를 조상타입의 참조변수로, 조상타입의 참조변수를 자손타입의 참조변수로의 형변환 가능.
- Car c = (Car) f;
- 참조변수의 형변환은 변수에 주소값이 변환되는 것이 아니고, 리모컨(참조변수)를 다른 종류의 것으로 바꾸는 것 뿐이다.
- 리모컨을 바꾸는 이유: 사용할 수 있는 멤버 개수를 조절하기 위한 것.
- instanceof연산자 : 참조변수가 참조하고 있는 인스턴스의 실제 타입을 알아보기 위해 사용.(형변환이 가능한지 여부 체크)
- 참조변수 + instanceof + 클래스명
- true and false 중 하나 반환
- if (c instanceof FireEngine) { FireEngine fe = (FireEngine) c;
- 매개변수의 다형성 : 매개변수가 Product타입의 참조변수라는 것은, Product클래스의 자손 타입의 참조변수면 어느 것이나 매개변수로 받아 들 일 수 있다.
- void buy (Product p) { }
- 추상 클래스 : 미완성 설계도 - 완성하지 못한 채로 남겨진 설계도, 미완성 메서드를 포함하고 있다는 의미.
- abstract class 클래스 이름 { }
- 인스턴스 생성 불가.
- 상속을 통해, 자손클래스에서만 완성 될 수 있다.
- 미완성 클래스라도, 어느 정도 틀을 갖춘 상태에서 시작하면 쉽기 때문에 클래스 작성에 도움을 줌.
- abstract class 클래스 이름 { }
- 생성자, 멤버변수, 메서드를 가질 수 있다. 일반 클래스와 다르지 않음.
- 추상 메서드: 선언부만 작성하고 구현부는 작성하지 않은 채로 남겨둔 것.
- /주석을 통해 어떤 기능을 수행할 목적으로 작성하였는지 설명/ abstract 리턴타입 메서드이름();
- 미완성인 이유 - 상속받는 클래스에 따라 메서드의 내용이 달라질 수 있기 때문.
- 자손클래스는 오버라이딩을 통해 조상인 추상클래스의 추상메서드를 모두 구현해주어야 한다.만일 하나라도 구현하지 않는다면, 자손클래스 역시 추상클래스로 지정해주어야 한다.
- abstract class Abstractplayer extends Player { void play(int pos) { } };
- 인터페이스 (interface): 일종의 추상클래스이다. 추상메서드를 갖지만, 추상클래스보다 추상화 정도가 높아서, 추상클래스와 달리 몸통을 갖춘
일반 메서드 또는 멤버변수를 구성원으로 가질 수 없다.- interface 인터페이스이름 { public static final 타입 상수이름 = 값; public abstract 메서드이름(매개변수); }
- 오직, 추상메서드와 상수만을 멤버로 가질 수 있다.
- 구현된 것은 없고, 밑그림만 그려져 있는 기본 설계도이다.
- 다른 클래스를 작성하는데 도움 줄 목적으로 작성된다.
- 접근제어자는 public 또는 default만 사용 가능.
- 모든 멤버변수는 public static final이어야 하며, 이를 생략할 수 있다.
- 모든 메서드는 public abstract 이어야 하며, 이를 생략할 수 있다. (단, static 메서드, default 메서드는 예외)
- static 메서드는 인스턴스와 관계없는 독립적인 메서드라 추가 가능.
- default 메서드(default void newMethod() {})는 추상 메서드의 기본 구현을 제공하는 메서드이므로, 디폴트 메서드가 새로 추가되어도, 해당 인터페이스를 구현한 클래스를 변경하지 않아도 된다.
- 인터페이스 상속 : 인터페이스는 인터페이스로부터만 상속 받을 수 있다. 다중상속 가능.
- 인터페이스의 구현: 인스턴스 생성 불가, 추상메서드의 몸통을 만들어주는 클래스를 작성해야 한다.
- class 클래스이름 implements 인터페이스이름 { // 인터페이스에 정의된 추상메서드를 모두 구현해야 한다.}
- 인터페이스의 메서드 중 일부만 구현한다면, abstract를 붙여서 추상클래스를 선언해야 한다.
- abstract class Fighter implements Fightable { }
- 인터페이스를 이용한 다형성
- 인터페이스의 타입의 참조변수로 이를 구현한 클래스의 인스턴스를 참조 가능.
- 인터페이스 타입으로의 형변환 가능.
- Fightable f = (Fightable) new Fighter();
- Fightable f = new Fighter();
- 메서드의 매개변수의 타입으로도 사용 가능 - 인터페이스를 구현한 클래스의 인스턴스를 매개변수로 제공한다는 의미 ( 인터페이스는 인스턴스가 없기 때문.)
class Fighter extends Unit implement Fightable {
public void move(int x, int y) { }
public void attack(Fightable f) { } -> 다른 문장으로 바꾸면, attack(new Fighter())로 바꿀 수 있음.
}
- public void attack (Fightable f) => public void atack(new Fighter())
- 리턴타입으로 인터페이스를 지정하는 것도 가능. - 메서드가 해당 인터페이스를 구현한 클래스의 인스턴스의 주소를 반환한다는 의미.
Firghtable method() {
Fighter f = new Fighter(); -> 이 두 문장을 한 문장으로 바꾸면 return new FIghter();
return f;
}
- 인터페이스의 장점
- 개발시간을 단축시킬 수 있다.
- 표준화가 가능하다.
- 서로 관계없는 클래스들에게 관계를 맺어 줄 수 있다.
- 독립적인 프로그래밍이 가능하다.
- 내부 클래스(inner class) : 클래스 내에 선언된 클래스이다. 두 클래스가 서로 긴밀한 관계에 있기 때문이다.
- 내부 클래스에서 외부 클래스의 멤버들을 쉽게 접근할 수 있다.
- 코드의 복잡성을 줄일 수 있다.(캡슐화)
class A { // B의 외부 클래스
class B { // A의 내부 클래스
// 객체 생성없이 A의 멤버접근 가능.
}
}
- 내부 클래스의 종류 - 인스턴스 클래스, 스태틱 클래스, 지역 클래스, 익명 클래스
- 익명 클래스(anonymous class) - 이름이 없음. 클래스의 선언과 객체의 생성을 동시에 하기 때문에 단 한번만 사용 가능. 오직 객체만을 생성할 수 있는 일회용 클래스이다.
'Java > 객체지향 프로그래밍 총 정리' 카테고리의 다른 글
Java - 객체지향 프로그래밍 규칙 총 정리 (1) (0) | 2023.02.19 |
---|