본문 바로가기
국비 학원 가서 개발새발

국비학원 6일차) 클래스 생성자를 배우다(예습:상속)

by 휴일이 2022. 10. 4.

<생성자>

인스턴스 초기화 메소드.

ㄴ인스턴스 변수의 초기화 작업이나

ㄴ인스턴스 생성시 실행해야하는 작업을 생성자로 만든다

 

 

생성자 조건

1.생성자 이름은 클래스 이름과 같아야함

2.생성자는 리턴값이 없음(그러나 void생략), 오버로딩 가능!

 

클래스이름(타입 변수명, 타입 변수명...) {} //매개변수 있는 생성자

클래스이름() {} //매개변수 없는 생성자

 

생성자는 인스턴스를 생성하지 않음 new 연산자가 함

클래스-어떤 클래스의 인스턴스를 생성할까 고민

생성자-선택 클래스의 어떤 생성자를 이용할까 고민

 

 

<기본 생성자>

클래스에 생성자가 하나도 없다면, 컴파일러가 자동 추가한다

클래스이름() {} //기본 생성자

클래스의 접근 제어자가 public이면 //public 클래스이름() {}

그냥 일단 추가해놓는 게 나음 나중에 상속 나오면 헷갈림

 

 

<매개변수 생성자>

class Car {

String color; String gearType; int door;

Car () {}

Car (String c, String g, int d) {

color = c;

gearType = g;

door = d;

}

이걸 불러온다 치면

Car c = new Car();

c.color = "white";

c.gearType = "auto";

c.door = 4;

이럴 수도 있지만, 생성자를 이용해서

Car c = new Car("white","auto",4)

이 한줄로도 가능 ㄷㄷ

 

 

<생성자에서 다른 생성자 호출- this()>

생성자간에도 다른 생성자를 호출할 수 있음

ㄴ 클래스 이름 대신 this 사용, !!!!!반드시 첫줄에만 호출 가능!!!!!

-생성자 내에거 초기화 작업 도중에 다른 생성자를 호출한다? 얘도 중간에 멤버변수 초기화해서 무의미

ㄴ 그래서 첫줄에만 호출 가능

 

Car() { this("white","auto",4) } //얘랑

Car(String color) { this(color,"auto",4) } //얘랑

Car(String color, String gearType, int door) {  //얘를 호출해서 사용했음

this.color = color;

this.gearType = gearType;

this.door = door;

}

 

<객체 자신을 가리키는 참조변수 this>

매개변수와 인스턴스 변수 이름이 같다면 this.인스턴스변수

this. 사용은 인스턴스 멤버만 사용 가능->static은 사용 불가

ㄴ static은 인스턴스가 없어도 호출 가능해서

static 호출 시점에 인스턴스 멤버가 없을 수도 있음 ㅠㅠ

-모든 인스턴스 변수에는 this. <-이게 앞에 숨겨져 있다네요~~

 

* tihs. -> 인스턴스 자신을 가리키는 참조변수, 인스턴스 주소를 저장!

* this(), this(매개변수) -> 생성자, 같은 클래스 다른 생성자 호출!

 

 

 

<변수의 초기화> -> 변수를 선언하고 값을 저장하는 것

ㄴ 가능하면 선언과 동시에 적절한 값으로 초기화해준다

 

멤버변수(iv,cv) : 초기화 안 해도 기본값으로 초기화 됨

지역변수(lv) : 사용전 반드시 초기화해야함!!!!

 

변수 기본값...

boolean = false

char = '\u0000'

byte,short,int = 0;

long = 0L

float = 0.0f

double = 0.0d or 0.0

참조형 = null

 

 

<멤버 변수 초기화> cv, iv 전역변수

1.클래스 변수cv  -> 인스턴스 변수iv 순으로 초기화

2. 자동 초기화->명시적 초기화(간단)(=) -> 초기화 블럭, 생성자(복잡) {}, static {}

 

(간단)명시적 초기화 : 변수 선언과 동시에 초기화 =을 써서 int a=5; Engine e = new Engine();

(복잡)초기화 블럭 :

ㄴ클래스 초기화 블럭 -> 클래스 변수의 복잡 초기화 static {}

ㄴ인스턴스 초기화 블럭 -> 인스턴스 변수의 복잡 초기화 {} <-거의 안 씀

 

class초기화블럭->main메소드 실행되어 인스턴스 생성되어->인스턴스 초기화 블럭->생성자...

 

class 초기화 블럭은 처음 메모리에 로딩될때만 실행

인스턴스 초기화 블럭은 인스턴스 생성될때마다 실행

배열이나 예외처리가 필요한 경우->클래스 초기화 블럭 static {}

 

 

 

 

<상속> 기존의 클래스를 재사용->새로운 클래스 작성!

1.적은 양의 코드로 새 클래스 작성 가능

2.코드를 공통적으로 관리 가능

->코드 추가, 변경에 용이하여

->코드 재사용성 높이고 코드 중복을 제거! 프로그램 생산성과 유지보수에 기여함

 

class 자손클래스명 extends 조상클래스명 {}

 

class Parent {}

class Child extends Parent {}

 

자손 클래스는 조상 클래스의 모든 멤버 상속 받음

조상클래스? 자손 클래스가 바뀌어도 영향 없음

자손클래스? 조상 클래스가 바뀌면 영향 있음

- 자손 클래스는 조상 클래스의 모든 멤버 상속(단, 생성자와 초기화 블럭은 빼고)

- 자손 클래스 멤버는 조상 클래스보다 같거나 많음(조상꺼 다 가져오고 지도 따로 생성함ㅋㅋ)

자손 클래스가 인스턴스를 생성하면, 조상 클래스 멤버도 함께 생성되어

따로 조상 클래스를 불러오지 않아도 됨

 

 

 

<클래스 간의 관계>

<포함 관계> 상속 말고? 포함하자!

한 클래스의 멤버로, 다른 클래스 타입의 참조변수 선언

Scanner sc = Scannet(System.in) <-이것도 포함관계!

 

class Circle {int x; int y; int r;}

class point {int x, int y}

=

class Circle {point p = new Point(); p.x; p.y; int r; } <-포인트에서 가져와서 사용

 

<클래스간의 관계는 어떻게 결정할까?>

1. ~은 ~이다(is a) 상속

2. ~은 ~을 가지고 있다(has a) 포함

-Circle은 point를 가지고 있다 : 포함

-SportCar은 Car이다 : 상속

-Deck은 Card를 가지고 있다 : 포함

 

<자바는 단일 상속만 가능>

조상은 하나만 허용!!!!

클래스간의 관계를 명확하게 하고, 코드를 더욱 신뢰할 수 있게 한다(C는 다중상속 허용)

 

<Object 클래스-모든 클래스의 조상>

모든 클래스 상속계층도의 최상위에 있는 Object 클래스 (메소드? 11개 있음)

상속 관계가 없는 모든 클래스는 자동으로 Object클래스로 상속된다

Class Tv (extends Object) {}

-> toString(), equals() <-전부 object클래스에 정의되어있음

 

 

 

 

<오버라이딩>

조상 클래스로부터 상속받은 메소드의 내용을 자손이 변경하는 것

 

1.접근 제어자(public 등)은 조상 클래스의 메소드보다 좁은 범위로 변경 불가

public>protected>default>private (보통 같은 범위 사용함)

2. 조상 클래스의 메소드보다 많은 수의 예외 선언 불가

thorws IOException, SQL Exception... // 같거나, 자손이 더 적음

3. 메소드 선언부가 일치해야함, 이름, 매개변수, 반환타입 등...

 

 

<오버로딩vs오버라이딩> 둘 다 완전히 다른 거예요!이름만 비슷

오버로딩 : 기존에 없는 새로운 메소드 정의(new)

오버라이딩 : 상속받은 메소드의 내용 변경(change)

 

class Parent {

void parentMethod() {} <-오버로딩 (new)

}

class Child extends Parent {

void parentMethod() {} <-오버라이딩(조상메소드를 change)

void parentMethod(int i) {} <-오버로딩(new)

void childMethod() {} <-오버로딩(new)

void childMethod(int i) {} <- 오버로딩(new)

void childMethod() {} <-중복정의(error)

}

 

 

<참조변수 super>

자손 클래스에서 조상 클래스로 받은 멤버를 참조하는 데에 사용

this. 처럼, 상속 받은 멤버와 이름이 같을 때 super. 사용

class Parent { int x = 10 }

class Child extends Parent { int x = 20 }

Child의 x = 20, this.x = 20, super.x=10 <-조상꺼임 super는

 

<super() - 조상의 생성자>

생성자는 자손한테 생성이 안 된다고 했죠? 수동 호출해줘야 함

super() <-조상의 생성자 호출

 

class Point { 

int x, y;

Point(int x, int y) { this.x = x; this.y = y; } }

 

class Point3D extends Point {

int z;

Point3D(int x, int y, int z) {

super(x,y);

//this.x = x; this.y = y; 로도 가능하나, 번거로우며...

this.z = z;

}}

 

조상의 멤버는 조상의 생성자를 통해 초기화 하는 것이 좋다!

클래스 자신에 선언 된 변수는, 자신의 생성자가 초기화할 것(필수는 아니나 권장)

ㄴ생성자는 상속이 안 되니 super()로 생성한다

 

 

 

 

-----

너무 졸리다 쉬고 싶다

씻지도 못했는데 오늘만 씻는 거 건너뛰어야겠다

너무피곤하다 세수만 하구 자야지...

728x90