본문 바로가기

언어/Java

클래스 상속, 오버라이딩

상속 기본 문법

extends : 클래스 상속을 의미

class ManCC {
	String man;
	
	public void Tellyourname() {
		System.out.println("hello"+ man);
	}
}

class BsMan extends ManCC {
	String pos;
	
	public void TellyourInfo() {
		System.out.println("hello"+pos);
		Tellyourname();
	}
}

public class Man{
	
	public static void main(String[] arg) {
		BsMan Make = new BsMan();
		Make.pos="New";
		Make.man="MIN";
		Make.TellyourInfo();
	}
}

BsMan는 Mancc을 상속한다

BsMan : 하위 클래스

Mancc : 상위 클래스

★★★ 클래스 상속 관계 ) 하위 클래스 -> 상위클래스

이때 Mancc부터 println된다

즉 하위 클래스의 인스턴스 생성 시

     상위 클래스, 하위 클래스의 생성자 모두 호출된다

     ,상위 클래스의 생성자가 먼저 호출된다

 

상속에서의 변수 초기화

= 생성자를 사용하여 변수를 초기화한다

class Man2{
	String name;
	public void tellYourName() {
		System.out.println("name :"+ name);
	}
}

class BsMan2 extends Man2{
	String com; //필드
	String pos;
	
	public BsMan2(String name, String com, String pos){ //생성자
		this.com = com; 
		this.pos = pos;
		this.name = name; //상위 클래스 초기화
	}
	
	public void tellYourInfo() {
		System.out.println("com :"+ com);
		System.out.println("pos :"+ pos);
		tellYourName();
	}
}

public class NewFile {
	
	public static void main(String[] arg) {
		
		BsMan2 man = new BsMan2("Min","helloworld","staff");
		man.tellYourInfo();
	}
	
}

super()

: 상위 클래스 호출

class ManCC {
	
	public ManCC() {
		System.out.println("hello2");
	}
}

class BsMan extends ManCC {
	
	public BsMan() {
		super();
		System.out.println("hello1");
	}
}

public class Man{
	
	public static void main(String[] arg) {
		
		new BsMan();
	}
}

 

다른 생성자를 호출하는 코드이므로 첫 줄에서만 허용된다

* 상위클래스가 먼저 호출되기 때문이다

+ 자바는 단일 상속만 지원한다

 

상속관계의 두 클래스는 IS-A 관계여야 한다

예) 하위클래스 : 스마트폰, 상위 클래스 : 모바일폰

이때 하위 클래스는 상위클래스의 특성을 모두 포함한다

 

참고) [초급 JAVA]자바 상속(extends) 예제로 이해하기/ super & super() 이해하기 (tistory.com)

 

[초급 JAVA]자바 상속(extends) 예제로 이해하기/ super & super() 이해하기

자바 상속(extends) 예제로 이해하기/ super & super() 이해하기 By Commin .December 12, 2016 안녕하세요 commin 입니다. 이번 포스팅에서는 자바의 상속(extends)을 예제를 통하여 설명하겠습니다. 상속은..

commin.tistory.com

 

 

클래스 변수, 클래스 메소드 상속 ( Static )

= 접근 수준 지시자가 protected이면 접근 가능하다

class Cake{ 
	
	protected static int number;
	
	public Cake(int number) {
		System.out.println( "cake" + number);
	}
	
}

class CheeseCake extends Cake{ 
	
	public CheeseCake(int number) {
		super(number);
		System.out.println("cheese" + number);
	}
}

class StrawberryCake extends CheeseCake{ 
	
	public StrawberryCake(int number) {
		super(number);
		System.out.println("strawberry" + number);
	}
	
}

public class CallCake {
	
	public static void main(String[] arg) {
		
		new StrawberryCake(3);
	}
	
}

클래스 변수가 하위 클래스 접근을 허용함

 

 

 

메소드 오버라이딩

= 상위 클래스에 정의된 메소드를 하위 클래스에서 다시 정의한다

 

상위 클래스 참조 대상 범위

class Cake2{ //그냥 케익
	
	public void sweet() {
		System.out.println("Cake");
	}
}

class CheeseCake2 extends Cake2{  //케익 + 치즈
	
	public void sour() {
		System.out.println("CheeseCake2");
	}
}

class StrawberryCake2 extends CheeseCake2{  //케익 + 치즈 + 딸기
		
	
	public void millky() {
		System.out.println("StrawberryCake2");
	}
}

public class CallCake2 {
	public static void main(String[] arg) {
		
		Cake2 cake1 =new StrawberryCake2();
		cake1.sweet();
		//cake1.millky();
		//cake1.sour();
		
		StrawberryCake2 cake2 =new StrawberryCake2();
		cake2.sweet();
		cake2.millky();
		cake2.sour();
		
	}
}

Cake2 cake1 = new StrawberryCake2()는 StrawberryCake2에 접근 할 수 없다

 

참조하는 인스턴스 종류 상관없이 참조변수 형에 해당하는 클래스와 그 클래스가 상속하는 상위 클래스에 정의된 메소드 들만 호출 가능하다

 

참조 변수간 대입할 때

Cake2 cake1 =new StrawberryCake2();

Cake2 ca1 = cake1;
//StrawberryCake2 ca2 = cake1; 오류
StrawberryCake2 ca2 = (StrawberryCake2)cake1;

컴파일에 참조변수 형만 보기에 ()안에 참조하는 부분을 표기해야 한다

 

메소드 오버라이딩

= 하위 메소드가 상위 메소드를 무력화 시킨다

조건 : 메소드 이름, 메소드 반환형, 메소드 매개변수 선언이 같아야된다

class Cake3{ 
	
	public void yummy() {
		System.out.println("Cake3");
	}
}

class CheeseCake3 extends Cake3{  
	
	public void yummy() {
		System.out.println("CheeseCake3");
	}
}

public class CakeOverrride {
	public static void main(String[] arg) {
		Cake3 c1 = new CheeseCake3();
		CheeseCake3 c2 = new CheeseCake3();
		
		c1.yummy();
		c2.yummy();
	}
}

모두 "CheeseCake3"가 출력된다

 

오버라이딩 됐을 때 상위 메소드 호출하는 방법

: super 키워드를 사용한다

class Cake4{ 
	
	public void yummy() {
		System.out.println("yummyCake");
	}
}

class CheeseCake4 extends Cake4{  
	
	public void yummy() {
		super.yummy();
		System.out.println("yummyCheeseCake");
	}
	
	public void tasty() {
		super.yummy();
		System.out.println("tastyCheeseCake");
	}
}

public class highOverride {
	public static void main(String[] arg) {

		CheeseCake4 c1 = new CheeseCake4();
		
		c1.yummy();
		c1.tasty();
	}
}

 

인스턴스변수, 클래스 변수, 클래스 메소드는 참조변수 형에 따라 접근하기에 오버라이딩 대상이 아니다

 

 

 

instanceof 연산자

= 참조변수가 참조하는 인스턴스의 클래스나 참조하는 인스턴스가 상속하는 클래스를 묻는 연산자이다

class Box{
	public void simpleWrap() {
		System.out.println("Simple Wrapping");
	}
}

class PaperBox extends Box {
	public void paperWrap() {
		System.out.println("Paper Wrapping");
	}
}

class GoldPaperBox extends PaperBox {
	public void goldWrap() {
		System.out.println("Gold Wrapping");
	}
}

public class InterfaceOfOverride {
	public static void main(String[] arg) {
		
		Box box1 = new Box();
		PaperBox box2 = new PaperBox();
		GoldPaperBox box3 = new GoldPaperBox();
		
		WrapBox(box1);
		WrapBox(box2);
		WrapBox(box3);
	}
	
	public static void WrapBox(Box box) {

		if(box instanceof GoldPaperBox) {
			((GoldPaperBox)box).goldWrap(); //Box -> GoldPaperBox 형변환
		}else if (box instanceof PaperBox) {
			((PaperBox)box).paperWrap(); //Box -> PaperBox 형변환
		}else {
			box.simpleWrap();
		}
		
		
	}
}

Box라는 형으로 받아 GoldPaperBox를 상속받으면 GoldPaperBox로 형변환

Box라는 형으로 받아 PaperBox를 상속받으면 PaperBox로 형변환

 

상속 사용 목적

=연관된 일련의 클래스들에 대해 공통적인 규약을 정의할 수 있다

  -> 하나의 배열에 데이터 저장하고 하나의 메소드로 데이터 삭제 및 검색기능을 가능하게 한다

 

package helloworld;

class Friend{
	
	protected String name;
	protected String phone;
	
	public Friend(String na, String ph) {
		name = na;
		phone = ph;
	}
	
	public void showInfo() {
		System.out.println("name : "+ name);
		System.out.println("phone : "+ phone);
	}
}

class UnivFriend extends Friend{
	
	private String major;
	
	public UnivFriend(String na, String ma ,String ph) {
		super(na, ph);
		major = ma;
	}
	
	public void showInfo() {
		super.showInfo();
		System.out.println("major : "+ major);
	}
}

class CompFriend extends Friend{
	
	private String department;
	
	public CompFriend(String na, String de ,String ph) {
		super(na, ph);
		department = de;
	}
	
	public void showInfo() {
		super.showInfo();
		System.out.println("department : "+ department);
	}
}



public class MyFriends2 {
	public static void main(String[] arg) {
		Friend[] frns=new Friend[10];
		int cnt = 0;
		
		frns[cnt++] = new UnivFriend("LEE","computer","010-1234-3434");
		frns[cnt++] = new UnivFriend("SEO","R&D","010-4356-3434");
		frns[cnt++] = new UnivFriend("YOON","computer","010-1234-5474");
		
		for(int i = 0; i < cnt; i++) {
			frns[i].showInfo();
			System.out.println();
		}
		
	}
}

 

 

 

Object 클래스, final선언, @Override

 

object 클래스 = 모든 클래스는 object 클래스를 상속한다

                          그러나 상속 클래스가 존재할땐 object 클래스를 상속하지 않는다

 

final 선언 = 해당 클래스를 다른 클래스에 상속하는걸 원하지 않을 때 추가

                   해당 메소드의 오버라이딩을 허용하지 않을 때

public final class Mylast() { ... }

public final void func(int n) { ... }

 

@Override = 오버라이딩이 목적이라고 컴파일러에 메시지 표시한것

                     오버라이딩이 이뤄지지 않았을 때 오류 메시지를 전해줄 수 있다