안녕하세요.
몇 가지 규칙을 만들어 글을 정리합니다.
단순히 제가 배운 내용을 정리하는 용도의 글입니다.
데브코스 백엔드 과정에서 배운 객체지향 첫 번째 수업을 듣고 정리한 내용이며
기초 강의가 아니기에 자바의 정석을 복습하며 내용을 정리하였습니다.
궁금하고 이상한
새롭게 알게된
그래서 더 찾아본
String str = "Hello World";
여기서 객체는 String이며 그것이 Type입니다.객체는 스스로 동작할 수 있는 환경을 가지고 있어야 하며 외부에 의존적이이지 않고 외부 침략을 제한할 수 있다.
자손 클래스는 조상 클래스의 모든 멤버를 상속받는다.
생성자와 초기화 블럭은 상속되지 않는다. 멤버만 상송된다.
자손 클래스의 멤버 개수는 조상 클래스보다 항상 같거나 많다.
접근제어자가 private 또는 default인 멤버들은 상속되지 않는다가 아니라 상속을 받지만 자손클래스로의 접근이 제한된다.
Java는 단일 상속만을 지원한다.
따라서 다른 클래스로부터 상속받지 않는 모든 클래스들은 자동적으로 Object 클래스를 상속받게 된다. 그렇지만 다른 클래스로부터 상속받는다고 하더라고 계층관계도에 따라 위로 올라가면 마지막에 Object 클래스가 있을 것이다!
super
조상 클래스로부터 상속받은 멤버도 자손 클래스 자신의 멤버이므로 super 대신 this를 사용할 수 있다. 그래도 조상 클래스의 멤버와 자손클래스의 멤버가 중복되어 정의되어 서로 구별해야하는 경우에만 super를 사용하는 것이 좋다.
class Parent {
int x =10;
}
class Child extends Parent {
void method() {
System.out.println("x="+x);
System.out.println("this.x="+this.x);//10
System.out.println("super.x="+super.x);//10
}
}
메서드 역시 super를 써서 호출할 수 있다.
특히 자손 클래스에서 오버라이딩한 경우에 super를 사용
class Point{
int x;
int y;
String getLocation(){
return "x:"+x+",y:"+y;
}
}
class Point3D{
int x;
String getLocation(){
return super.getLocation()+",z:"+z;
}
}
super() : 조상 클래스의 생성자
🤔 그렇다면 포함과 상속의 차이는?
~은 ~이다 -> 상속관계
~은 ~를 가지고 있다 -> 포함관계
🤔 자손들의 공통적인 기능을 가지도록 부모 클래스를 만든다? 오해
기능적인 관점이 아니라 추상과 구체의 관점에서 상속의 관계가 맺어진다
추상클래스 = 미완성 설계도
인터페이스 = 기본 설계도 (더 추상적)
interface 인터페이스이름 {
public static final 타입 상수이름 = 값;
public abstract 메서드이름 (매개변수목록) ;
}
여러 가지 형태를 가질 수 있는 능력을 의미하며 자바에서는 한 타입의 참조변수로 여러 타입의 객체를 참조할 수 있도록 함으로써 다형성을 프로그램적으로 구현하였다.
🕵️조상클래스 타입의 참조변수로 자손클래스의 인스턴스를 참조할 수 있도록 하였다.
모든 참조 변수는 null 또는 4 byte의 주소값이 저장되며, 참조변수의 타입은 참조할 수 있는 객체의 종류와 사용할 수 있는 멤버의 수를 결정한다.
조상타입의 참조변수로 자손타입의 인스턴스를 참조할 수 있다.
반대로 자손타입의 잠조변수로 조상 타입의 인스턴스를 참조할 수는 없다.
서로 상속관계에 있는 클래스 사이에서만 참조변수의 형변환이 가능하다.
따라서 모든 참조변수는 Object 클래스 타입으로 형변환이 가능하다.
자손타입에서 조상 타입으로 가는 up-casting은 형변환 생략 가능
그 반대는 불가능
Car car = null;
FireEngine fe = new FireEngine();
FireEngine fe2 = null;
car = fe;
fe2 = (FireEngine) car;
Tv t = new CaptionTv(); // 이도 (TV)생략된 형태
메서드의 경우 조상 클래스의 메서드를 자손의 클래스에서 오버라이딩한 경우에도 참조 변수의 타입에 관계없이 항상 실제 인스턴스의 메서드가 호출되지만, 멤버변수의 경우 참조변수의 타입에 따라 달라진다.
예시 1)
class BindingTest{
public static void main(String[] args){
Parent p = new Child();
Child c = new Child();
System.out.println("p.x= "+p.x);//100
p.method();//Child method
System.out.println("c.x= "+c.x);//200
c.method();//Parent method
}
}
class Parent{
int x = 100;
void method(){
System.out.println("Parent Method");
}
}
class Child extends Parent {
int x =200;
void method(){
System.out.println("Child Method");
}
}
예시 2)
class BindingTest{
public static void main(String[] args){
Parent p = new Child();
Child c = new Child();
System.out.println("p.x= "+p.x);//100
p.method();//Parent method
System.out.println("c.x= "+c.x);//100
c.method();//Parent method
}
}
class Parent{
int x = 100;
void method(){
System.out.println("Parent Method");
}
}
class Child extends Parent {}
매개 변수의 다형성의 예시
class Product{
int price;
int bonusPoint;
Product(int price){
this.price=price;
bonusPoint = (int) (price/10.0);
}
}
class Tv extends Product {
Tv(){
super(100);
}
public String toString() {return "TV";}
}
class Computer extends Product {
Tv(){
super(200);
}
public String toString() {return "TV";}
}
🤔 인스턴스 타입과 일치하는 참조변수를 사용하면 인스턴스의 멤버들을 모두 사용할 수 있을 텐데 왜 조상타입의 참조변수를 사용해서 인스턴스의 일부 멤버만을 이용하도록 할까?
팀원들에게 물어보았습니다.
저의 관점은List<Integer> list = new ArrayList<>();
List<Integer> list = new LinkedList<>();
ArrayList에서 LinkedList로 바꾸는 상황이라면 위와 같이 코드를 수정하는 과정은 똑같이 일어난다고 생각했기 때문입니다.
하지만 팀원들의 답변을 통해서
더 명확하게 개념을 잡을 수 있었습니다.
결국 모든 코드들은 List의 메서드의 공통적인 부분에 따라 돌아갑니다.
아마도 저는 저 list들을 많은 곳들에 사용하게 될 것입니다.
만약 제가ArrayList<Integer> list = new ArrayList<>();
로 선언하고 LinkedList로 바꾸는 상황이라면 저 한줄의 코드 이외에도
list를 사용한 모든 코드들을 변경해야 합니다.
하지만 공통적인 부분을 하나로 뽑음으로서 코드의 객체지향적인 설계가 가능하게 되어 한줄의 코드 변경만으로 코드를 이전과 같은 설계를 가지도록 유지할 수 있습니다.
객체지향 프로그래밍은 객체에 기능을 나눠서 위임하고 이 객체들간의 관계가 존재한다.
개발자는 객체들간의 관계를 설명할 도구가 필요하고
그것이 UML이다.
아래는 계산기 미션을 하며 그려본 UML이다.
관계를 선으로 나타내며 접근제어자는 +(public),-(private),없음(default)로 나타낸다.
SOLID 잘 지키기 -> 그러나 이를 잘 지키기는 힘드니 개발자들이 이를 잘 지키는 여러가지 방법을 고안했고 그 방법이 디자인 패턴이다
23개의 디자인 패턴이 존재한다.
출처 : https://refactoring.guru/design-patterns/catalog
내용이 길어질거 같아 따로 포스팅하였습니다.
사실은 아직도 객체 지향에 관하여 제대로 알고 있다는 생각이 들지 않습니다.
오늘 배운 내용들은 알고 있지만 알고 있다고 말하기 어렵고
항상 새로운 것들이 생겨납니다.
그래도 제가 항상 노력해야하는 부분은
오늘 배운 내용을 잘 소화하도록 노력하는 것