[java] 클래스 기초

ppparkta·2023년 3월 30일
1

멋쟁이사자처럼

목록 보기
1/2

더 보기 좋은 링크

상속

💡 상속은 부모 클래스의 속성과 메소드를 물려받고 자식의 속성과 메소드를 추가로 정의하는 것이다. (단, 부모의 privat은 상속받지 못한다)

상속의 특징

  • 자바는 다중 상속을 허용하지 않는다. 그러므로 하나의 자식 클래스는 하나의 부모 클래스만 상속받을 수 있다.
  • 종류
    • 다단계 상속
    • 계층적 상속

상속 구현

클래스를 상속받기 위해서는 extends 키워드를 사용한다.

//부모클래스
public class Parent {...}
//자식클래스
public class Child extends Parent {...}

주의사항

자식 생성자 내부에 부모 생성자를 호출하는 부분이 반드시 필요하다.

→ 아래 사용 예시에 부모 생성자 호출이 없는 이유: 생성자는 명시적인 생성자가 선언돼있지 않으면 컴파일러가 알아서 기본 생성자를 호출해서 생성한다.

class People{
    String name;
    int age;
    public void printData(){
        System.out.println("이름: " + name + ", 나이: " + age);
    }
}

class Student extends People{
    Student(String name ,int age){
        this.name = name;
        this.age = age;
    }
}

public class Inheritance {
    public static void main(String[] args){
        Student soobin = new Student("양수빈", 24);
        soobin.printData();
    }
}

→ 만약에 부모 객체에 생성자가 있다면 해당 생성자 형식에 맞게 super()를 사용해서 부모 생성자를 호출해야 한다.

class People {
	String name;
	int age;
	People (String name, int age){
		this.name = name;
		this.age = age;
	}
}

class Student extends People{
	int classNum;
	Student(String name, int age, int classNum){
		**super(name, age);**
		this.classNum = classNum;
	}
}

메소드 오버라이딩

메소드 오버라이딩은 부모에게 상식받은 메소드 중 일부를 자식 클래스에서 재정의해서 사용하는 것이다.

메소드 오버라이딩 규칙

  • 재정의할 부모의 메소드와
    • 같은 메소드명
    • 같은 리턴타입
    • 같은 매개변수 리스트
  • 메소드 접근 제한자는 부모보다 더 제한이 강한 것을 사용할 수 없다.
    • ex) 부모 메소드가 public인데 자식이 오버라이딩할 때 private으로 설정 불가

메소드 오버라이딩 구현

오버라이딩한 메소드와 부모 클래스의 메소드를 둘 다 사용하고 싶다면 마찬가지로 super 키워드를 사용하면 된다.

//부모클래스
class People{
    String name;
    int age;
    public void printData() {
        System.out.println("이름: " + name + ", 나이: " + age);
    }
    public int calculate(int num){
        return num * 2;
    }
}

//자식클래스
class Student extends People{
    int class_number;
    Student(String name, int age, int class_number){
        this.name = name;
        this.age = age;
        this.class_number = class_number;
    }
    public void printData(){
        System.out.println("이름: " + name + ", 나이: " + age + ", 반: " + class_number);
    }
    public void printDataTwo(){
        **super.printData();**
    }
    public int calculate(int num){
        return num * num;
    }
}

오버로딩 vs 오버라이딩

오버로딩오버라이딩
메소드명동일동일
매개변수, 타입무조건 달라야 함동일
리턴 타입달라도 됨동일
접근제어자모든 접근 제어자 사용 가능부모 메소드의 접근 제어자보다 더 넓은 범위만 사용 가능
적용 범위같은 클래스 내부상속관계

final

final 키워드는 클래스, 필드, 메소드 선언 시 사용되며 수정이 불가능하도록 만들고 싶은 경우 사용한다.

final 키워드가 붙은 클래스, 메소드는 상속할 수 없고, 오버라이딩 할 수 없다.

다형성

다형성은 동일한 메세지에 객체마다 다른 동작을 하도록 정의하는 것이다.

장점

  • 유지보수 쉬움
  • 재사용성 증가
  • 느슨한 결합 (클래스간 의존성, 결합도 ↓ 확장성, 안정성 ↑)

필수조건

  • 상속 관계
  • 오버라이딩
  • 부모 타입으로 자식 객체를 업캐스팅
    • 업캐스팅: 자식 클래스의 객체가 부모 클래스의 타입으로 형변환

주의사항

기본 자료형은 형변환을 하면 실제로 타입이 변하지만 업캐스팅을 한다고 자식 객체가 부모 객체로 타입이 실제로 바뀌는 것은 아니다.

업캐스팅은 부모 클래스형 객체 참조 변수로 자식 클래스의 객체를 참조하는 것이다.

전형적인 방법

  • 메소드의 매개변수로 객체를 주고받을 때
  • 형식 매개변수 → 부모 타입
  • 실 매개변수 → 자식 객체

추상클래스

추상 메소드

메서드 본체를 완성하지 못한 메서드이다. 선언부만 존재하며 구현부는 작성돼있지 않다.
abstract 반환타입 메서드명();

  • 자식 클래스에서 반드시 오버라이딩 해야 사용 가능하다.
  • 추상 메소드가 포함된 클래스를 상속받는 자식 클래스가 반드시 추상 메소드를 구현하도록 하기 위해 만들어진 개념이다.

추상 클래스

추상 클래스는 추상 메소드와 비슷한 개념으로, 주로 **상속 계층에서 자식 멤버의 이름을 통일**하기 위해 사용하는 클래스이다.

abstract class 클래스명 ();

→ 추상 클래스의 생성자는 자식 클래스의 생성자에서 super()을 통해 부르고 초기화한다(앞서 나온 내용과 같음)

클래스 앞에 abstract 키워드를 붙여서 사용할 수 있다. 보통은 하나 이상의 추상 메소드를 포함하지만 없을수도 있다. 추상 클래스는 동작이 정의되어 있지 않은 추상 메서드를 포함하고 있으므로, 인스턴스를 생성할 수 없다.

**abstract** class Abst() ; //추상 클래스 Abst 생성
...
Abst s = ~~new Abst();~~    //추상 클래스는 인스턴스 생성 불가능

추상 클래스 구현

//추상 메소드 포함한 추상 클래스
**abstract** class Shape {
	double pi = 3.14;
	**abstract** void draw();
	public double findArea() {
		return 0.0;
	}
}

//추상 클래스의 자식 클래스
class Circle extends Shape {
	int radius;

	public Circle(int radius) {
		this.radius = radius;
	}
	public void draw() {
		System.out.println("원을 그리다");
	}
	public double findArea() {
		return pi * radius * radius;
	}
}

//추상 클래스 사용
public class AbstractClassDemo {
	public static void main(String[] args) {
		Circle c = new Circle(3);
		c.draw();
		System.out.printf("원의 넓이는 %.1f", c.findArea());
	}
}

정리

  • 추상 메소드를 선언하여 상속을 통해 하위 클래스에서 구현하도록 강제한다
  • 객체(인스턴스)를 생성할 수 없다
  • 그 외에는 일반 클래스와 다르지 않다

인터페이스

인터페이스는 객체를 어떻게 구성해야 하는지 정리한 기본 설계도이다. 객체가 인터페이스를 사용하면, 인터페이스 메소드 구현을 하도록 강제한다.

→ 원래 인터페이스는 상수와 추상 메소드의 집합. 그러나 편의성을 위해 Java8부터 Default, Static, Private 메소드 등 지원

인터페이스 설계

인터페이스는 class의 설계도이기 때문에 존재 목적이 공개이다. 따라서 *접근지정자는 public만 가능하다.

*public을 사용하면 다른 패키지에서도 사용 가능함

접근지정자 **interface** 인터페이스명 {
	**// 1. 상수필드**
	**// 2. abstract 메소드**
	**// 3. default 메소드**
	**// 4. static 메소드**
	**// 5.private 메소드**
}

1. 상수필드

**public static final** 타입 상수명 =;

기본적으로 public static final 타입 상수명 = 값 으로 쓰는 것이 맞지만, 애초에 인터페이스는 상수만 가능하기 때문에 public static final은 생략해도 된다.

2. abstract 메소드

**public abstract** 타입 메소드명(매개변수);

인터페이스의 모든 메소드(default, static, private 제외)가 public abstract이기 때문에 public abstract 키워드는 생략할 수 있다.

→ 생략하더라도 컴파일할 때 자동으로 생성해줌

3. default 메소드 (JDK 8부터 사용 가능)

**default** 타입 메소드명(매개변수){  /*구현*/  }

상속받는 클래스에서도 기본적으로 적용 가능하며, 오버라이딩도 가능한 메소드이다. 추상 메소드가 아니기 때문에 강제성이 없다. 필요한 경우에만 오버라이딩해서 사용하면 된다.

4. static 메소드 (JDK 8부터 사용 가능)

**static** 타입 메소드명(매개변수){  /*구현*/  }

인터페이스의 생성 없이 사용할 수 있는 메소드이다. static이기 때문에 오버라이딩할 수 없다.

5. private 메소드 (JDK 9부터 사용 가능)

**private** 타입 메소드명(매개변수){  /*구현*/  }

인터페이스 안에서만 사용 가능한 메소드이다.

인터페이스 특징

장점

  • 인터페이스 준수하면 통합에 신경쓰지 않고 다양한 형태의 클래스 개발 가능
  • 인터페이스로 다중 상속 효과를 간접적으로 얻을 수 있음

인터페이스와 추상 클래스의 차이

공통점

  • 구현부가 없는 추상 메소드를 가짐
  • 추상 클래스 or 인터페이스를 상속받은 자식 클래스에서 추상 메소드를 구현함
  • 자식 클래스에 강제성을 부여함

차이점

  • 추상 클래스: 상속을 받아서 기능을 확장시킴
    • 유전적 유사성이 있을 때 추상 클래스 사용
  • 인터페이스: 구현하는 모든 클래스에 대해 특정 메소드가 반드시 존재하도록 강제함
    • 유전적 유사성이 없는데 특정 행동이 겹치는 경우 인터페이스 사용.
    • 기능을 나타내는 경우가 많음
인터페이스추상 클래스
구현 메소드포함 불가능포함 가능
인스턴스 변수포함 불가능포함 가능
다중 상속가능불가능
디폴트 메소드선언 가능선언 불가능
생성자와 main()선언 불가능선언 가능
상속에서의 부모인터페이스인터페이스, 추상 클래스
접근 범위모든 멤버를 공개추상 메소드 최소한 자식에게 공개

인터페이스 상속과 구현

인터페이스 extends, implements 추가학습 필요

인터페이스 상속

인터페이스는 extends 라는 키워드를 붙여서 상속할 수 있다. 만들어진 인터페이스를 상속하려면 extends 키워드를 사용한다.

interface 자식인터페이스 extends 부모인터페이스 { ... }

인터페이스 구현

인터페이스는 implements 라는 키워드를 붙여서 구현할 수 있다.

class 자식클래스 implements 부모인터페이스 { ... }

상속할 인터페이스가 여러개라면 쉼표(,)로 연결한다 (다중상속 가능, 클래스는 다중상속 불가능)

interface 자식인터페이스 extends 부모인터페이스1, 부모인터페이스2 { ... }
class 자식클래스 implements 부모인터페이스1, 부모인터페이스2 { ... }

~~class 자식클래스 extends 부모클래스1, 부모클래스2 { ... }~~

클래스와 인터페이스의 관계

  • **interface** InterfaceA **extends** classA**interface** InterfaceA **implements** classA 는 불가능

Untitled

인터페이스extends인터페이스
클래스implements인터페이스
클래스extends, implements클래스, 인터페이스클래스는 하나만, 인터페이스는 여러개 상속 가능

자바 run 비활성화 시 참고

만약 src/main/java 안의 자바클래스 run이 비활성화 돼있다면 main클래스 오타 있는지 확인하기. 오타 확인 후 문제 해결되지 않으면 아래의 방법대로 수행

  1. Edit Configurantions… 클릭

  2. Add New Configuration에서 Application 선택

  3. name에 클래스명 적고 Main class에 만든 자바 클래스 입력

  4. APPLY누르고 OK눌러서 종료 (해결)

profile
겉촉속촉

0개의 댓글