본문 바로가기

개발일지/Java + Spring

211027 Java - 상속과 오버라이딩, 상속 받고 생성자 호출 방법(3)

public class Sample1027_2 {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		CaptionTv ctv = new CaptionTv();
		ctv.channel = 11;
		ctv.channelUp();
		System.out.println("현재 채널 : " + ctv.channel);
		ctv.displayCaption("hello java..."); 
		ctv.caption = true; //자막을 켰다.
		ctv.displayCaption("hello java..."); //여기서부터 찍힘
		
		
		CaptionTv ctv2 = new CaptionTv();
		ctv2.channel = 11;
		
		ctv2.channelDown();
		ctv2.channelDown();
		ctv2.channelDown();
		ctv2.channelDown();
		
		System.out.println("현재 채널 : " + ctv2.channel);
		ctv2.caption = true;
		ctv2.displayCaption("자막을 시작합니다.");
		//ctv2 인스턴스 선언후 채널 초기값은 11번으로 하고 
		//채널을 7번으로 메서드를 이용하려 변경하고 
		//자막 상태가 on 상태에서 '자막을 시작합니다.'라는 문구 출력
	}

}

class Tv
{
	boolean power; //전원
	int channel; //채널
	
	//Tv(){} 여기서는 매개변수가 없어서 없어도 상관 없음 
	
	void power() {
		power = !power;
	}
	
	void channelUp()
	{
		++channel;
	}
	
	void channelDown()
	{
		--channel;
	}
}

class CaptionTv extends Tv
{
	boolean caption;	//자막 상태
	
	void displayCaption(String text)
	{
		if(caption) //자막이 켜져 있으면
		{
			System.out.println(text); //자막을 찍어주라
		}
	}
}

class Point
{
	int x;
	int y;
	
	String getLocation()
	{
		return "x : " + x + ", y : " + y; 
	}
}

class Point3D extends Point
{
	int z;
	
	String getLocation()
	{
		return "x : " + x + ", y : " + y + ", z : " + z; 
	}
}

public class Sample1027_3 {


	public static void main(String[] args) {
		Point3D p3 = new Point3D();
		p3.x = 10;
		p3.y = 20;
		p3.z = 30;
		
		//오버라이딩을 했기에 3개 다 나온다.
		System.out.println("getLocation : " + p3.getLocation());
		
		Point p = new Point(); //point만 찍힌다.
		System.out.println("p getLocation : " + p.getLocation());
	}

}

자식에서 부모의 것을 상속 받았을 때 출력 하는 방법에는 세 가지가 있다.

class Prent
{
	int x = 50;
}

class Child extends Prent
{
	int x = 40;
	void method()
	{
		int x = 30;
		System.out.println("x : " + x);
		//인스턴스 메소드를 가리킴 x = 20
		System.out.println("this.x : " + this.x);
		//내 클래스에 있는 인스턴스 변수를 가리키기 때문에 x = 20
		System.out.println("super.x : " + super.x);
		//상속 받은 클래스에서 부모 것을 가지고 오는 것이다.
	}
}

public class Sample1027_3 {
	public static void main(String[] args) {
		Child c = new Child();
		c.method();
	}
}

 

Prent 클래스를 상속 받은 Child 클래스에는 메소드가 하나 있다. 반환값이 없는 void method() 메소드에는 출력문이 세개가 오는데...

 

x  -  메소드(지역변수)의 인스턴스 변수를 가리킴

this.x  -  내 클래스에 있는 인스턴스 변수를 가리킴

super.x  -  부모 클래스에 있는 인스턴스 변수를 가리킴

 


상속 받았을 때 생성자에서 생성하기

부모에게서 상속을 받았을 때 모두 쓸 수 있지만 그 중에서 쓸 수 없는 것이 있다. 바로 부모의 생성자와 초기화인데 생성자를 쓸 수 없지만 내부적으로 호출하는 방법은 가능하다. 그래서 이번에 호출 하는 방법을 배워 볼 것이다. 

 

 

※프로젝트를 할 땐 3개로 나누어서 파일을 만들어줘야한다※

class Point
{
	int x = 10;
	int y = 20;
	
//	Point(){}
	
	Point(int x, int y)
	{
		this.x = x;
		this.y = y; 
	}
}

 

인스턴스 변수 x, y이다. 

 

별도의 메소드는 존재하지 않음

 

생성자명은 클래스 명과 동일한다. 매개변수는 몇 개가 와도 되고 타입이 달라도 됨. int x, int y 지역변수 

변수명이 중복될 때!! 인스턴스 변수를 가리킬 때는 this.x를 쓴다. 

 

class Point3D extends Point
{
	int z = 30;
	
	Point3D()
	{
		this(100, 200, 300);
		//Point3D 다른 생성자를 의미한다. 매개변수가 3개인
	}
	
	Point3D(int x, int y, int z)
	//생성자에서 생성자 호출하기
	{
		super(x, y);
		//부모의 매개변수가 2개니까 super에서도 매개변수를 넣음
		this.z = z;
	}
}

 

Point 클래스를 상속 받은 자식 클래스이다.

 

생성자 2개

 

this(100, 200, 300);

다른 생성자를 의미한다. 

같은 클래스에 있는 매개 변수가 다른 생성자를 가리킨다. 아래에 있는 생성자를 찾는다는 얘기임

 

매개변수를 받았을 때

여기서 말하는 super는 부모를 말한다. 

super.x;는 부모의 변수임

super(x, y);는 이건 무조건 첫째줄에 온다. 내거의 부모에 있는 매개변수 두개짜리 생성자를 호출하게 됨

this.z = z ; 내 z 인스턴스 변수임

 

 

public class Sample1027_3 {


	public static void main(String[] args) {
		Point3D p3 = new Point3D();
		
		System.out.println("p3.x : " + p3.x);
		System.out.println("p3.y : " + p3.y);
		System.out.println("p3.z : " + p3.z);
	}

}

 

p3.x : 100
p3.y : 200
p3.z : 300

 

Point3D(Child)에서 매개 변수 없는 생성자로 감 this(100,200,300)를 읽었는데 어? 매개변수 3개 어딨지? 아래에 있으니 아래로 내려감    슈퍼(부모)의 매개변수 2개가 있네? 부모님 집에 가봐야겠다!  ▶  부모로 올라가서 값들을 읽어 옴 아~ x와 y 변수가 있구나~ 다시 집에 와야지  ▶  this.z 변수를 초기화 하고 모두 초기화가 끝남    아~ 100, 200, 300 이 값들이 x, y, z에 대한 값이었구나~ 이해를 하고 메인으로 돌아간다.     출력

 

 


순서 따라가보기

class Point
{
	int x = 10;
	int y = 20;
	
//	Point(){}
	
	Point(int x, int y)
	{
		//super() 생략 됨
		System.out.println("3333333333");
		this.x = x;
		this.y = y; 
	}
}

class Point3D extends Point
{
	int z = 30;
	
	Point3D()
	{
		this(100, 200, 300);
		//Point3D 다른 생성자를 의미한다. 매개변수가 3개인
		System.out.println("1111111111");
	}
	
	Point3D(int x, int y, int z)
	//생성자에서 생성자 호출하기
	{
		//super()가 붙어야 하는데 안에 매개 변수가 없으니 내가 따로 만들어줘야한다.
		super(x, y);
		//부모의 매개변수가 2개니까 super에서도 매개변수를 넣음
		//매개변수가 없는 것은 알아서 컴파일러가 super() 만들어준다. 
		System.out.println("2222222222");
		this.z = z;
	}
}


public class Sample1027_3 {


	public static void main(String[] args) {
		Point3D p3 = new Point3D();
		
		System.out.println("p3.x : " + p3.x);
		System.out.println("p3.y : " + p3.y);
		System.out.println("p3.z : " + p3.z);
	}

}
3333333333
2222222222
1111111111
p3.x : 100
p3.y : 200
p3.z : 300

 

 


 

TIP

개발을 하기 전에 무슨 프로그램인지 파악을 해야한다. 그 과정은 코딩을 먼저 보고, 실행을 해서 왜 이 결과가 나오는지 하나하나 따라가서 흐름을 파악한다. 그리고 어떤 프로그램인지 깨닫게 되는 것이다. 

 

디버깅용 프로그램이 따로 있지만 시스템.아웃.프린트가 아직까지는 좋다.

 

이런 흐름을 알게 되면 jdk 메소드는 인터넷에서 찾아서 뽑아 쓰면 됨 

 

추상클래스와 인터페이스