JAVA-16

이강민·2021년 10월 6일
0

JAVA 기초 1

목록 보기
16/20
post-thumbnail

변수와 상속, 다형성

지금까지 사용한 변수에 대해 알아보고 클래스의 상속과 다형성에 대해 알아보도록 하자
상속을 알아야 기능을 상속 받아 사용 할 때 저장공간과 코드를 줄일 수 있고 필요 시 재정의하여 사용 할 수 있으니 꼭 알아야 파트이다.

변수의 종류

지역변수

Ram의 stack 영역에서 생성

  1. 지역안에서 선언된 변수
  2. 그 영역의 바디를 만났을 때 메모리에서 해제 된다.
  3. 사용자가 직접 초기화 해야한다. ex) String hiMsg = "안녕하세요";
  4. 다른 영역에서 접근 할 수 없기 때문에 보안성이 뛰어나다.

전역변수

Ram의 stack 영역에서 생성

  1. 클래스 영역 안에 있고, 전체 영역에서 사용 가능한 변수
  2. 클래스 영역 외의 어떠한 영역에도 포함되어 있지 않다.
  3. new를 만났을 때 메모리에서 해제된다.
  4. 프로그램 종료 시 메모리에서 해제된다.
  5. 다른 영역에서도 접근 할 수 있기때문에 보안성이 상대적으로 낮다.

Static 변수

Ram의 data영역에서 생성

  1. 컴파일을 하게 되면 가장 먼저 메모리에 올라가고, 어떠한 경우에도 초기화 되지 않는다.
  2. 프로그램 종료 시 멥모리에서 해제 된다.
  3. 메모리에 고정되기 때문에 남용 시 메모리 부족 혹은 프로그램 실행속도에 영향을 미친다.
  4. new를 만나도 초기화 되지 않는다.

코드작성해보기

  1. static 변수 data를 생성하고 f,f2메소드를 사용하고 다른 클래스에서 사용해보자
stack을 이용하여 코드를 작성해보자 
public class VariableTest{
	static int data = 0; //static 변수로 초기화
    void f(){
    	System.out.println(++data);
    } //f()메소드 생성
    void f2(){ 
    data = 20; 
	} // f2()메소드 생성
}
  1. 다른 클래스인 VariableTest2를 만들어 new를 만나도 초기화 되는지 확인해보자
public class VariableTest2 {
	public static void main(String[] args) {
		//객체화 
		VariableTest vt = new VariableTest();
		vt.f();
		vt.f();
		vt.f2();
		vt.f();
		vt = new VariableTest(); //전역변수는 new를 만나면 초기화 된다. 
		vt.f();
	}
}
  1. 다른 클래스를 가져오기 위해 new로 초기화 하여 사용하였고, 다시 new를 만들어 static변수가 초기화되는지 확인한 결과 초기화 되지 않았다. 또한 일반적인 전역변수(static을 제외)로 data를 만들었다면 new를 만나면 초기화 되어 다시 숫자가 시작되었을 것이다.

변수를 알아야되는 이유

상속에 들어가기 전 변수에 대해 알아본 이유는 이 변수의 종류별로 작동하는 원리와 사용방법을 알아야 상속기능을 사용하였을 때 new를 만나 다시 초기화되는 변수인지 아니면 지역변수로 극히 일부로 사용되는 변수인지 이해해야 메소드를 활용하거나 재정의 할때 헷갈리지 않을 수 있다.

상속이란?

상속(inheritance)
부모가 자식에게 재산을 상속하듯 부모클래스가 자식클래스에게 기능을 상속하는 것을 말한다.
기존에 사용중인 클래스의 필드를 다른 클래스에서 계속 사용하고 싶으면 상속 기능 받는다.
그렇게 되면 부모 클래스의 필드를 마치 자신의 것처럼 사용 할 수 있다.

주의사항

  1. 다중 상속은 불가능하다.
  2. 자식은 하나의 부모만 상속 받을 수 있다.

상속의 선언

상속의 용어

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

상속의 사용

상속을 사용할때는 Class 자식 extends 부모 라고 작성해야한다.

//A:부모 클래스, B: 자식 클래스 
Class A{
	A 필드 
    }
Class B extends A{
	A 필드
    B 필드
    }
    

super

super(); 는 부모클래스의 객체를 초기화하면 자동적으로 생성되는 것으로 자식 클래스에서 부모 클래스의 객체를 그대로 사용하고 싶을때 부모클래스의 객체를 그대로 자식 클래스로 가져온뒤 super(-,-,-);에 초기화 할 값들을 적으면 부모클래스에서 객체가 초기화 된다.

멤버 변수

부모 클래스의 변수들을 자식 클래스에서 상속받을 때 그 변수들을 멤버 변수라고 한다.
각 멤버 변수의 접근 권한에 대해 알아보자

부모 클래스로부터 상속받은 멤버 변수의 접근 권한이 private일때
1. 부모 클래스의 생성자를 호출해서 초기화 시킬 수 있다. ex) super(매개변수)
2. 부모 클래스에 setter메소드를 통해 초기화 시킬 수 있다.
3. 변수에 저장된 값은 getter메소드를 통해 가져온다.

부모 클래스로부터 상속받은 멤버 변수의 접근 권한이 protected일때
1. 자식 클래스에서 접근이 가능하기 때문에 this를 사용해서 초기화 한다.
2. 자식 클래스에서 접근이 가능하므로 getter메소드를 사용하지 않고 변수명으로 값에 직접 접근하면 된다.

자식 클래스의 생성자가 실행되기 전에 부모 클래스의 생성자가 먼저 실행된다. 따라서 실행할 부모 크래스의 생성자를 지정하지 않으면 부모 클래스의 기본 생성자가 자동으로 실행된다.
자동으로 입력되는 super()는 지워도 남았다.

접근권한 중 final로 설정하면 가져올 수는 있지만 값을 변경할 수 없다.

코드 작성해보기

상속기능 간단히 구현하기

  1. alt+shift+s 다음 o를 눌러 자동으로 생성자를 만들고(변수가 있어야함)
    변수는 사용하지 않으니 부모생성자의 내용과 매개변수를 지우고 부모생성자를 출력하는 코드를 적는다. 또한 show메소드를 만들어 B에서 상속받아 재정의 해본다.
class A { 
	int data = 0; //사용하지 않으나 자동 생성하기 위해 만듦
    
    public A(){
    	System.out.println("부모 클래스 생성자")
    }
    void show(){
    System.out.println("A클래스")
    }
    
class B extends A {
	//show 메소드 가져오기(자동으로 override로 만들어짐)
    @Override
	void show() {
		System.out.println("B클래스");
	}
    public class InhTest {
	public static void main(String[] args) {
		B instance = new B(); //기본 생성자가 들어있다. 
		instance.show();
	}
}
	

결과 : "부모 클래스 생성자", "B클래스"
여기서 알 수 있는 내용은 자식 크래스를 사용 할때 부모의 기본 생성자는 따라 온다는 것이고 부모클래스의 메소드를 자식클래스에서 재정의하여 본인 것 처럼 사용 할 수 있다는 것이다.

자동차 기능을 상속받아 보자

  1. 부모클래스를 작성해보자, 멤버 변수에 여러가지 접근권한을 작성해보자
public class Car{
	final int wheel = 4; 
    	public String brand;
        protected String color;
        private int price;
        
public Car(){
	System.out.println("부모 클래스의 기본 생성자");
    }
    
 //alt+shift+s > o 자동생성, super 지우기
public Car(String brand, String color, int price) {
		this.brand = brand;
		this.color = color;
		this.price = price;
	}

void engineStart(){
	System.out.println("열쇠로 시동 킴");
}

void engineStop(){
	System.out.println("열쇠로 시동 끔");
}

//price는 private이니 getter,setter로 가져오자 
//alt+shift+s > r 

public int getPrice() {
		return price;
	}

public void setPrice(int price) {
		this.price = price;
	}
    
 }
  1. 부모 클래스를 만들었으니 자식클래스를 만들어 부모를 상속받아보고 이때 자식클래스 만의 변수도 추가해보자
public class SuperCar extends Car{
	//SuperCar 클래스 만의 변수 
    String mode;

public SuperCar(){
	System.out.println("자식 클래스의 기본 생성자");
    }

//자식 생성자를 자동으로 만들고 부모의 super를 이용한다. 부모의 멤버변수를 활용하기 위해 
public SuperCar(String brand, String color, int price, String mode){
	super(brand, color, price) //부모의 객체(멤버변수)를 가져옴, 심지어 private도 가능
    	this.mode = mode; //얘는 자동으로 만들어짐
}

//부모의 메소드를 가져와 재정의 해보자 

@Override
void engineStart() {
System.out.println("음성으로 시동 킴");
}
	
@Override
void engineStop() {
System.out.println("음성으로 시동 끔");
}
  1. 자식 메소드를 만들지 않고 우리는 toString을 활용할 것이다.

    toString은 toString을 리턴하고 있으며 해당 변수의 주소값을 보여준다. 이 리턴 값을 자식 클래스의 기본값을 보여주는 메소드로 재정의하여 다음 클래스의 메인메소드에서 사용 할 것이다. toString을 재정의 해보자

...생략
@Override
void engineStop() {
System.out.println("음성으로 시동 끔");
	}

//price는 private로 super를 활용하여 초기화할 수는 있지만 값을 가져오는 것은 get을 사용한다.
@Override
public String toString() {
  return "브랜드 : " + brand + "\n색상 : " + color + "\n가격 : " + getPrice();
}
  1. 이제 다른 클래스에서 클래스 초기화와 toString을 사용해보자.
public class CarTest {
	public static void main(String[] args) {
		SuperCar ferrari = new SuperCar("ferrari", "Red", 45000, "sport"); 
		System.out.println(ferrari.toString());
		System.out.println("모드 : " + ferrari.mode); //toString 재정의 안해서 따로 사용함.
		ferrari.engineStart();
		ferrari.engineStop();
	}
}

다형성

다형성(polymorphism)이란?

다형성이란 하나의 메소드가 서로 다른 클래스에서 다양하게 실행되는 것을 말한다.
다형성을 구현하기 위해서는 다형성을 구현할 메소드를 포함할 클래스에게 부모 클래스가 상속해 줘야 한다. 부모클래스와 자식클래스에 같은 이름의 메소드가 있어야 하고, 자식 클래스에서는 재정의 해야한다.
다형성의 종류에는 Overloading, Override 이 있다.

오버로딩(Overloading)

같은 이름의 메소드지만 매개변수의 갯수 혹은 타입이 다르면 선언이 가능.
같은 클래스 내에서 같은 이름의 메소드를 오버로딩하면 사용가능하다.

//오버로딩
void add(int num1, int num2){
		System.out.println("두 정수의 합");
		System.out.println(num1+num2);
	}
//매개변수의 변화를 줘 같은 이름의 메소드를 사용함. 
void add(int num1, int num2, int num3) {
		System.out.println("세 정수의 곱과 더하기");
		System.out.println(num1*num2+num3);
	}	

오버라이드(Override)

부모클래스에서 정의된 메소드를 매개변수에 상관없이 override를 하면 자식클래스에서 같은 이름과 같은 매개변수의 메소드의 내용을 바꿀 수 있다.

//부모클래스 
void engineStart(){
	System.out.println("열쇠로 시동 킴");
	}
//자식클래스 
@Override
void engineStart() {
System.out.println("음성으로 시동 킴");
	}
profile
AllTimeDevelop

0개의 댓글

관련 채용 정보