기존 클래스를 재사용해서 새로운 클래스를 작성하는것
코드의 재사용성을 높이고, 코드의 중복을 제거
→ 생산성이 향상, 유지보수성이 향상
조상클래스 : 부모(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개발'이 출력
}
}
조상 클래스로부터 상속받은 메서드의 내용을 변경하는 것
상속받은 메서드를 자손클래스에 맞게 변경 시키고자 할때 오버라이딩을 사용
-기존에 없는 새로운 메서드를 정의하는 것(new)
메서드명이 같아야함
매개변수 개수 혹은 타입이 달라야함
반환 타입은 오버로딩에 영향을 미치지 않는다.
-상속받은 메서드의 내용을 변경하는 것 (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 기억!