프로그래밍/Java 정리

Java 8일차 -클래스 배열, 상속

윤도ri 2021. 11. 25. 22:59

>클래스 배열

-객체를 여러개 선언해야 하는 경우 배열 타입으로 한번에 선언 후 사용
-각 객체는 규칙성이 없기 때문에 규칙성을 부여하기 위해서 사용
(한칸 한칸이 하나의 객체)

ex)자동차라는 클래스(추상적인것)을 이용하여 여러가지 차를 객체화 시켜주고 싶은 경우

Car car= new Car("Ferrari", "Red", 65000);

Car car= new Car("K7", "White", 7000);
Car car2= new Car(28000);

 

↑위를 보면 보라색부분이 계속 겹쳐진다. 답답하지 않나? 저 반복적인것을 어떻게 묶지? 

이 때 우리가 떠올릴 수 있는것은 배열이다. 변수처럼  클래스도 똑같이 배열을 만들 수 있다.

 

Car[] garage = {
 new Car("Ferrari", "Red", 65000),
 new Car("K7", "White", 7000),
 new Car(28000)

 

>클래스 배열 선언

          클래스명[ ] 배열명 = {
                          new 생성자(),        //new 생성자()  --->객체
                          new 생성자(),
                          new 생성자(),
                            ...
                        };
           클래스명[ ] 배열명 = new 클래스명[칸수];

 

>클래스 배열 사용

   각 칸이 객체이기 때문에 각 방으로 접근 후 .을 찍고 필드로 접근한다.

 

            배열명[idx].변수
            배열명[idx].메소드()

 

 ex) garbage[ 0 ].name //--> Ferrari

      garbage[ 0 ].engineStart( ); // --->엔진을 키다

 

Tip. 배열이므로 각 객체마다 하는 행동을 한번에 주르륵 출력하고 싶을때 for문을 쓰면 된다.

 ex)for (int i = 0; i < garage.length; i++) {
             garage[i].engineStart();
     }

 Car 배열의 garage에 200 번지 주소값을 갖고있다. 이 주소값의 빈공간으로 가보면 두칸의 공간을 갖고 있을것이다.

new Car()라는것은 생성자로 바로 필드만들면서 주소값을 가져오게 된다. 첫번째 new car()는 300번지 가지고 올것이고

두번째 new Car()는 400번지를 가지고 올것이다.

 

-----------------------------------------------------------------------------------------------------

>상속(inheritance)
1. 기존에 선언된 클래스의 필드를 다른 클래스에서도 사용하고자 할 때
2. 클래스들을 만들다 보니 공통 요소가 보여서 부모로 묶은 후 상속시켜 
주어서 클래스를 편하게 만들고자 할 때

  ex) 토끼의 정보,행동이랑 코끼리의 정보,행동 그대로 넣을경우 

      아 공통요소가 많네..?  아 동물이라는 큰 범위(부모클래스)로 묶어서 토끼와 코끼리 클래스(자식클래스)

      상속시켜주자!!

 

>상속 방법

  class A {
            A의 필드
   }
  class B  extends A {
              B의 필드 
   }
  B obj = new B();
  obj 객체는 실제로 A의 필드와 B의 필드 둘 다 가지고 있다.

A:부모 클래스, 상위 클래스, 슈퍼 클래스,  기반 클래스
B:자식 클래스, 하위 클래스, 서브 클래스,  파생 클래스

 

상속에 대한 예제이다.상속을 받으면 바로 안에 객체까지 다 갖고오게 되는걸까? 잘 생각해보자 부모가 죽기전에 자식에게 상속해줄때 ㅇㅇ숨 넘어가기 직전에 갑자기 상속을 시켜주나? 아니다 그전에 누구에게 나는 죽으면 상속을 시켜줄것이다 라고 미리 약속해둘것이다. 그래서 이 때는 선언만 한것이지 상속한것은 아니다.

 <상속과정>

1.SuperCar mycar = new SuperCar(); 

:SuperCar 생성자 호출하면 첫번째로는 SuperCar의 필드가 복사가 되는것이다. 근데 그 전에 근데 그전에 상속하기로

약속했기때문에 부모 클래스가 먼저 복사가 된다.

2. 그리고 나서 상속된 자식 클래스가 오면서 합쳐진다. 

3.합쳐진 후에 mycar의 주소값에 객체가 담기게 된다. 

 

 SuperCar 클래스를 사용한다라는것은 객체를 찍어내는 행동을 했다는것이다. SuperCar가 객체를 찍어낼때(붕어빵틀로 붕어빵을 찍을때) 상속을 시켜준다. 

 

 

>자바의 다형성(Polymorphism)

말하자면 다양한 형태의 성질이다. 여기에는 두가지 특징이 있다.

 

1.Overloading(오버로딩)

 

:같은 이름의 메소드를 넘쳐서(여러개) 불러오는(선언하는) 기법
매개변수의 개수 혹은 타입이 다르다면 매개변수로 각각을 구별할 수 있기 때문에 같은 이름의 메소드로 여러개 선언할 수 있다.  오버로딩된 메소드를 사용할 시 전달된 값의 타입 혹은 개수로 구분하여 알맞은 메소드가 자동으로 호출된다. 
          ex) println(intx) println(String x)... 

:자료형의 순서나 개수가 다르다면 선언이 가능하다.

public Car(String brand, String color, int price){}

 

public Car(int price, String color, String brand){}  //자료형의 타입을 다르게 함

 

public Car(int price){} //개수를 다르게 하다

 

 

 

 

2.Overriding(오버라이딩)

: 재정의(우선시하다..)

-부모 필드에 a()라는 메소드가 존재한다면 자식 객체 생성시 부모 필드가 먼저 메모리에 올라가게 되므로 부모의 a()가
메모리에 먼저 존재한다. 그 다음 자식 필드를 완성시킬때 똑같은 이름의 a()라는 메소드가 존재한다면 같은 이름으로 
2개가 만들어지는것이 아니라 기존에 만들어진 부모필드의 a()메소드 대신에 자식에서 작성한 내용이 사용된다.
(부모 필드에 있는 a()에 자식에서 작성한 내용이 덮어씌워진다) 그러므로 자식 객체로 a()메소드를 사용하게 되면 재정의된 기능으로 사용하며 이것을 오버라이딩 이라고 한다.
            ex)int data = 5;
               data= 10; 
             syso(data); -->10 이거랑 같은 원리

 ----메소드 이름이랑 매개변수 내용까지 완벽히 같아야함.  

Car 클래스(부모클래스)// 같은이름의 생성자로 오버로딩하는것을 볼 수 있다.

 

SuperCar 클래스(자식 클래스) / 보면 변수도 추가생성, 오버라이딩한 메소드, 추가메소드가 생긴것을 볼수 있다.

 

원래 메소드에 열쇠로 시동끄기가 있었는데 수퍼카를 터치로 시동끄기로 만들고 싶을 수도 있다.그래서 이때 메소드이름과 매개변수까지 같으므로 오버라이딩이 되는것이다. 열쇠로 시동끄기가 사라지고 터치로 시동끄기만 남는것이다.

>자식 클래스의 생성자 호출시 일어나는 일

 자식 클래스의 객체는 자식 생성자를 호출하여 객체화를 진행한다. 자식 생성자를 호출했으므로 자식클래스 내에

필드들이 똑같이 복사되어 하나 생성된다. 만약 자식 클래스의 필드만 메모리에 올라갔다면 자식 객체로 절대 부모 클래스 내부에 있는 필드에는 접근할 수가 없다.따라서 자식 생성자를 호출하게 되면 부모의 필드가 먼저 메모리에 할당되고 그 이후에 자식 필드도 따라 붙는다. 결과적으로 자식 객체는 부모 필드가 메모리에 같이 올라와 있기 때문에 접근할 수 있게된다. 


-->자식 생성자 첫 줄에는 항상 super클래스의 생성자(부모의 기본생성자)가 호출된다.
     명시적으로 적지 않을시에는 보이지 않지만 super(); 호출 

 

:그래서 자식 클래스안에 부모 클래스의 생성자를 그대로 코드를 다시 적을 필요가 없이 super(brand,color,price);를 적어주면 부모클래스의 생성자를 호출하고 있는것이 된다.

 

 

 

>전역변수

: 각 객체마다 하나씩 필드로 존재하는 변수들 

class안에 있고 메소드밖에 있다고 말하기 보단 class는 추상화기 때문에 안에 변수랑 메소드가 있다고 말하기 어려움. 

만들어지는 객체안에 하나하나마다 존재하는 변수들임

 

>static(정적변수)

 static이 붙은 변수, 메소드, 구역 등은 프로그램 실행시 가장 먼저 메모리에 올라간다. static이 붙은 메소드 내부에서는 객체의 필드에 올라가는 일반 전역변수나 일반 메소드는 사용할 수 없다.(아직 메모리에 올라오지 않았기 때문에)

 따라서 static이 붙은 전역변수, Static이 붙은 메소드, 자기 자신 안에 선언된 지역변수만 사용할 수 있다.   

static이 붙은 전역변수, 메소드는 모든 객체가 공유한다. 따라서 static 필드는 클래스 이름으로 직접 접근이 가능하다.
실제로 공유해야 하는 값, 메소드 또는 필드가 필요없는 메소드 경우에는 static을 붙여서 선언한다.
(공유하지 않아야 하는 값들에는 무조건 static을 붙이면 안된다) 

 

 

---> mycar.wheel이면 100번지에 필드로 들어간다. 근데 Car.wheel이 없다. 

mycar의 100번지에 wheel이 없으면 mycar 가 Car타입이니까 Static변수인 Car.wheel 의 변수에 접근하게 되고 -1하면

3이 되게 된다. 한번 할당이 되면 없어질 수가 없다.

'프로그래밍 > Java 정리' 카테고리의 다른 글

Java 9일차 -Up casting, Down casting  (0) 2021.11.26
Java 실습 : 비지니스 프로그램 만들어보기  (0) 2021.11.26
Java 7일차 -클래스  (0) 2021.11.24
Java 6일차 -메소드  (0) 2021.11.23
Java 4일차 -for문  (0) 2021.11.23