국비학원 8일차 : 상속, 오버라이딩, 제어자

Digeut·2023년 3월 6일
0

국비학원

목록 보기
8/44

상속

기존 클래스를 재사용해서 새로운 클래스를 작성하는것
코드의 재사용성을 높이고, 코드의 중복을 제거
→ 생산성이 향상, 유지보수성이 향상

조상클래스 : 부모(parent) 클래스, 상위(super) 클래스, 기반(base) 클래스
자손클래스 : 자식(child) 클래스, 하위(sub) 클래스, 파생된(derived) 클래스

생성자는 상속되지 않는다!
자식클래스의 개수는 부모클래스의 개수와 같거나 많다
자바에서는 단일 상속만 된다.

사용방법

class 클래스명 extends 조상클래스명 {...}
class Human{ //⭐부모클래스 / 사람 클래스 
//모든 클래스는 object(최상위 조상클래스)를 상속받고 있다. 
	String name; //인스턴스 선언
	int age;
	String telNumber;
	String country;
	
	/*생성자만들면서 초기화 같이하기*/
    Human() {/*생성자 만들기*/} //기본 생성자
	Human(String name, int age) { //따로 만든 생성자
		this.name = name;
		this.age = age;
		this.telNumber = "010-1111-2222";
		this.country = "Korea";
	}
	
	//메서드
	void eat(String food){
		System.out.println(this.name/*인스턴스가 먹는다를 하기위함*/ 
        + "가 " + food + "를 먹습니다.");
	}
}

//Developer 클래스는 Human의 속성과 기능을 모두 사용가능
class Developer extends/*상속 시 사용*/ Human{ //⭐자손클래스
//직업 클래스에 사람클래스를 받아옴
	String position; //인스턴스 선언
	String language;
	
	🔴Developer(){} //기본 생성자
	✅Developer(String name, int age, String position, String language){
		//super : 부모 클래스를 지칭
		//super() : 부모 클래스의 생성자를 지칭
		//this() : 본인 인스턴스의 생성자 지칭
		super(name, age); //부모 생성자를 지칭
		this.position = position;
		this.language = language;
		
	}
	
	//메서드
	void develope() {
		System.out.println(super/*정확한 위치를 표시해줘야한다*/.name 
        				//this.name으로 해도 같은결과가 나오긴한다
        + "가 "+ this.language + "로 " + this.position + "개발을 합니다.");
	}					
}

public class Inheritance {

	public static void main(String[] args) {
		Developer developer1 = new 🔴Developer()/*기본생성자*/; 
        //인스턴스 생성 및 기본생성자 호출
		developer1.name = "Jhon doe"; //초기화 과정
		developer1.position ="Back end";
		developer1.language = "java";
	
		developer1.eat("사과"); //Jhon doe가 사과를 먹습니다.
        //Human클래스의 eat()메서드를 Developer가 상속받아 사용하므로
        //Jhon doe가 사과를 먹습니다. 로 출력된다.
        
		developer1.develope(); //Jhon doe가 java로 Back end개발을 합니다.
        //Human클래스의 name인스턴스를 Developer가 상속받아서
        //Jhon doe로 출력된다. language와 position은
        //Devleoper의 인스턴스
        //기본 🔴생성자를 호출했으므로 'java로 Back end개발'이 출력
		
		Developer developer2 = 
        		new ✅Developer("Michle", 29, "Front end","Javascript"); 
                //인스턴스 생성 및 생성자 호출(매개변수를 갖는)
		
		developer2.eat("바나나"); //Michle가 바나나를 먹습니다.
        //Dveloper클래스를 받아오는 devloper2지만
        //부모클래스인 Human 클래스의 eat()메서드 사용할수 있다.
        
		developer2.develope(); //Michle가 Javascript로 
        //Front end개발을 합니다. 
        //매개변수를 갖는 ✅생성자를 호출했으므로
        //'Javascript로 Front end개발'이 출력
		
		
	}

}

오버라이딩(Overriding)

조상 클래스로부터 상속받은 메서드의 내용을 변경하는 것
상속받은 메서드를 자손클래스에 맞게 변경 시키고자 할때 오버라이딩을 사용

오버라이딩 조건

  1. 자손 클래스에서 오버라이딩하는 메서드는
    조상 클래스의 메서드와 이름이 같아야 함
  2. 자손 클래스에서 오버라이딩하는 메서드는
    조상 클래스의 메서드와 매개변수가 같아야 함
  3. 자손 클래스에서 오버라이딩하는 메서드는
    조상 클래스의 메서드와 반환타입이 같아야 함

Overloading 🆚 Overriding

오버로딩(overloading)

-기존에 없는 새로운 메서드를 정의하는 것(new)

오버로딩 조건

메서드명이 같아야함
매개변수 개수 혹은 타입이 달라야함
반환 타입은 오버로딩에 영향을 미치지 않는다.

오버라이딩(overriding)

-상속받은 메서드의 내용을 변경하는 것 (change, modify)

class Human { //조상클래스
	String name; //인스턴스 선언
	
	void eat(String food) {
		System.out.println(this.name + "가 " + food + "를 먹습니다");
	}
}

class Developer extends Human { //자손클래스
	
	//⭐Overloading
	void eat() { //이건 오버로딩된것, 같은 클래스에서 
    //같은 이름의 메서드를 여러개 '새로'정의
	System.out.println(super.name + "가 절반만 먹습니다.");
}
	
	//먹는 작업은 같이 하나, 적게 먹는 작업. 오버라이딩 적용
	//⭐Overriding : 개발할 적에 제일 많이 쓴다. 
    //틀을 따라서 뭔가 만들고자 할때 클래스를 상속받아 작업시 필수적으로 사용된다.
	//상속받은 메서드를 자식 클래스에 맞게 '변경'해서 사용하는것
	void eat(String food) {
		System.out.println(super.name + "가 " + food + "를 절반만 먹습니다.");
	}
	

}

public class Overriding {

	public static void main(String[] args) {
		Developer developer = new Developer(); //자식클래스 인스턴스 생성
		developer.name = "John doe"; //Devleloper가 Human상속받아 name 사용
		
		developer.eat("사과"); //오버라이딩한 결과가 출력된다
        //John doe가 사과를 절반만 먹습니다.
		developer.eat(); //오버리딩한 결과가 출력
        //John doe가 절반만 먹습니다.
		
		Human human = new Human(); //부모클래스의 인스턴스 생성
		human.name = "Michle";
		
		human.eat("바나나");
	}

}

이클립스 import 추가 단축키 srtl + space

제어자

클래스, 변수 혹은 메서드의 선언부에서 사용되는 부가적 의미를 추가해주는 키워드

접근 제어자 : public, protect, default, private
기타 제어자 : static, abstract, final

접근 제어자 : 하나의 대상에 여러개의 제어자를 종합해서 사용할 수 있음
단, 접근 제어자는 한 선언에 대하여 한번만 사용할 수 있음. 제어자의 순서는 무관.

접근제어자

멤버 또는 클래스의 접근 권한을 제한하는 제어자
1. private : 같은 클래스 내에서만 접근이 가능
2. default : 같은 패키지 내에서만 접근이 가능
3. protect : 같은 패키지 내에서 그리고 다른 패키지의
자손 클래스에서만 접근이 가능
4. public : 모든 공간에서 접근이 가능
클래스, 멤버변수, 메서드, 생성자 에서 사용된다.

//static 제어자
	// 해당 제어자가 포함되어 있는 선언문은 클래스 단위로 사용가능하도록 함
	// 멤버 변수, 멤버 메서드에서 사용가능
🟢/*private*/ class Example1{
	
	static int number1; //static변수 (인스턴스 생성없이 클래스로 사용가능)
	static void function1() {}
}

//final 제어자
	// 해당 제어자가 포함되어 있는 선언문은 변경이 불가능하도록 함.
	// 클래스, 변수, 메서드에서 사용가능
//클래스 선언문에 final이 포함되면 해당 클래스를 상속하지 못한다.
/*🔴final*/ class Example2{
	//메서드 선언문에 final이 포함되면 해당 메서드를 override하지 못한다.
	final void function2() {
		//변수 선언문에 final이 포함되면 초기화한 후 
        //해당 변수의 값을 변경하지 못한다.
		final int NUMBER2 = 10;
//		NUMBER2 = 12; 불가능
	}
}

//클래스에 🔴final 제어자 입력시
//class Exmaple2_1 extends Example2{ //상속받을수 없다는 오류가 뜬다
//	void function2() {} //오버라이드 하지 못한다는 오류가 뜬다 
//(클래스의 🔴final은 지우고 적용)
//}

//abstract 제어자
// 해당 제어자가 포함되어 있는 선언문은 선언만 되어 있고 
//구현은 되어있지 않음을 나타낸다
//클래스, 메서드에서 사용가능

//클래스 선언문에 abstract가 포함되어 있으면 해당 클래스는 
//구현되지 않은 메서드를 포함하고 있음을 의미한다.
abstract class/*추상클래스*/ Example3{
	//메서드 선언문에 abstract가 포함되어 있으면 
    //해당 메서드는 구현되지 않았음을 의미한다.
	abstract void function3()/*구현부 작성안하고 끝*/;
}

public class Modifier {

	public/*접근제어자*/ static void main(String[] args) {
		🟡/*1*/Example4 example4 = new Example4(); 
        //chapter4.A_AccessModifier의 Example4가져온것
		🟡/*2*/example4.number4 = 10;
		🟡/*3*/example4.function4();
		
//		🟢Example1을 private로 선언시 사용불가하다
		Example1 example1 = new Example1();
		example1.number1 = 10;
		
	}

}
public class 🟡Example4 { //public이 아닌 private로 하면  
						  //🟡/*1*/부분에서 오류가 뜨게 된다
	public int number4; 
    //private로 하면 위의 🟡/*2*/부분에서 오류
	
	public void function4() {}
    //private로 하면 위의 🟡/*3*/부분에서 오류
	
	public Example4() {}
	
	//public과 private 기억!
profile
개발자가 될 거야!

0개의 댓글