생각 두 접시 (10)
2024-06-01 03:11:01

추상 클래스(abstract class)는 실체 클래스들의 공통되는 필드와 메소드를 정의한 클래스이다.

추상 클래스는 실체 클래그의 부모 클래스 역할을 하며 객체로 존재할 수 없다.

 

추상 클래스 용도

1. 실체 클래스의 공통된 필드와 메소드의 이름을 통일

2. 실체 클래스를 작성할 때 시간 절약

3. 실체 클래스 설계 규격을 만들고자 할 때

 

추상 클래스 선언

클래스 선언에 abstract 키워드 사용

New 연산자로 객체를 생성할 수 없기 때문에, 상속을 통해 자식 클래스만 생성이 가능하다.

ex) public abstract class 클래스명 { }

 

추상 클래스의 코든 메소드는 반드시 실체 클래스에서 구현 되어야 한다

'생각 두 접시' 카테고리의 다른 글

[java] 타입 변환과 다형성  (0) 2024.06.01
[java] final  (0) 2024.06.01
[java] 메소드 재정의 @Override  (0) 2024.06.01
[java] Getter / Setter  (0) 2024.05.31
[java] 접근 제한자  (0) 2024.05.31
2024-06-01 02:53:17

다형성: 같은 타입이지만, 실행 결과가 다양한 객체를 이용할 수 있는 성질

 

부모 타입에는 모든 자식 객체가 대입이 가능하다. 그렇기 때문에 자식 타입은 부모 타입으로 자동 타입 변환이 가능하다 (like int -> double O | double -> int X)

 

자동 타입 변환 (Promotion)

부모 클래스 : Animal 

자식 클래스 : Cat

Cat cat = new Cat();

Animal animal = cat; (Animal animal = new Cat() 도 가능)

 

바로 위의 부모가 아니더라도 상속 계층의 상위면 자동 타입 변환이 가능하다. 변환 후에는 부모 클래스 멤버만 접근 가능하다.

 

강제 타입 변환 (Casting)

부모 타입을 자식 타입으로 변환하는 것

조건

자식 타입을 부모 타입으로 자동 변환 후, 다시 자식 타입으로 변환할 때

ex) Cat cat = new Cat();

Animal animal = cat;

cat = (Cat)animal

 

객체 타입 확인 (instanceof)

부모 타입 이면 모두 자식 타입으로 강제 타입 변환할 수 았는 것이 아니다.

ex) Parent parent = new Parent(); // 부모 참조변수 parent가 부모 인스턴스를 참조하는 중

Child child = (Child) parent;  // 따라서 캐스팅의 조건을 충족시키지 못해, 캐스팅 불가능

 

먼저 자식타입인지 확인 후 강제 타입변환을 실행해야 한다.

boolean result = 좌항(객체) instanceof 우항(타입)

'생각 두 접시' 카테고리의 다른 글

[java] 추상 클래스  (0) 2024.06.01
[java] final  (0) 2024.06.01
[java] 메소드 재정의 @Override  (0) 2024.06.01
[java] Getter / Setter  (0) 2024.05.31
[java] 접근 제한자  (0) 2024.05.31
2024-06-01 00:11:27

final 키워드는 다양한 용도로 쓰이는데,

 

1. final 필드 : 수정 불가 필드 

final이 붙은 필드는 더이상 수정이 불가능한 상수의 성질을 갖게 된다.

하지만, c++이나 c#처럼 static의 성질 (메모리 고정) 을 가지지 못하여, static final로 사용해야 한다.

 

2. final 클래스 : 부모로 사용(상속) 불가능

 

3. final 메소드 : 자식이 재정의(Override) 할 수 없는 메소드

'생각 두 접시' 카테고리의 다른 글

[java] 추상 클래스  (0) 2024.06.01
[java] 타입 변환과 다형성  (0) 2024.06.01
[java] 메소드 재정의 @Override  (0) 2024.06.01
[java] Getter / Setter  (0) 2024.05.31
[java] 접근 제한자  (0) 2024.05.31
2024-06-01 00:06:31

메소드 재정의는 부모 클래스의 상속 메소드를 수정해 자식 클래스에서 재정의 하는 것이다.

 

메소드 재정의 조건

- 부모 클래스의 메소드와 동일한 시그니처 ( 리턴 타입, 메소드 이름, 매개변수 리스트 ) 를 가져야 한다.

- 접근 제한을 더 강하게 오버라이딩 불가능하다 ( public -> private X | default -> public 가능) 역은 성립.

- 새로운 예외(Exception) throws 불가 {위의 접근제한과 비슷. 부모 클래스보다 더 포괄적인 에러를 throws 불가}

 

@Override 어노테이션

컴파일러에게 부모 클래스의 메소드 선언부와 동일한지 검사 지시

 

메소드 재정의 효과

부모 메소드는 숨겨지고, 재정의된 자식 메소드 실행 (super.메소드() 사용시 부모 클래스의 메소드 사용 가능)

예제)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package Practice;
 
public class AirPlane {
    public void land()
    {
        System.out.println("착륙합니다");
    }
    public void Fly()
    {
        System.out.println("일반비행합니다");
    }
    public void takeOff()
    {
        System.out.println("이륙합니다");
    }
}
 
cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package Practice;
 
public class SonicAirplane extends AirPlane {
    public static final int NORMAL = 1;
    public static final int SUPERSONIC = 2;
    
    int flyMode = NORMAL;
    
    @Override
    public void Fly()
    {
        if (flyMode == SUPERSONIC)
            System.out.println("음속비향합니다");
        else
            super.Fly();
    }
}
 
cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package Practice;
 
import week10.SonicAirPlane;
 
public class AirPlaneEx {
    public static void main(String[] args) {
        SonicAirplane sPlane = new SonicAirplane();
        sPlane.takeOff();
        sPlane.Fly();
        sPlane.land();
        
        sPlane.flyMode = SonicAirPlane.SUPERSONIC;
        sPlane.Fly();
        sPlane.flyMode = SonicAirPlane.NORMAL;
        sPlane.Fly();
    }
}
 
cs

 

 

 

'생각 두 접시' 카테고리의 다른 글

[java] 타입 변환과 다형성  (0) 2024.06.01
[java] final  (0) 2024.06.01
[java] Getter / Setter  (0) 2024.05.31
[java] 접근 제한자  (0) 2024.05.31
[java] 패키지  (0) 2024.05.31
2024-05-31 22:51:52

일반적으로 클래스를 선언할 때 필드는 일반적으로 private으로 접근을 제한하고, 메소드를 통해서 필드에 접근해야 한다.

 

Getter

private 필드의 값을 리턴해주는 역할을 한다. 필요한 경우 필드의 값을 가공하기도 한다.

get필드명() 또는 is필드명() {필드 타입이 boolean인 경우} 의 형태를 띈다.

 

Setter

외부에서 주어진 값을 필드 값으로 수정해준다. 필요한 경우 유효성을 검사한다. (필드의 값을 대입만해주고, 증감은 다른 메소드로 하는것이 권장된다.)

set필드명(매개변수) 의 형태를 띈다.

매개변수의 타입은 필드의 타입과 동일해야 한다.

예제)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
package Practice;
 
public class CarBasic {
    // 클래스의 각 필드를 private으로 선언하여 외부 접근을 제한한다
    private String company;
    private String model;
    private String color;
    private int maxSpeed;
    
    // 외부에서 값이 필요한 경우 값을 제공하기 위한 getter() 메소드 정의
    public String getCompany() {
        return company;
    }
    
    public String getModel() {
        return model;
    }
    public String getColor() {
        return color;
    }
    public int getMaxSpeed() {
        return maxSpeed;
    }
    
    // 외부호부터 주어진 값을 필드값으로 덕용하기 위해 setter() 메소드 정의
    // 필요한 경우 외부값의 유효성 검사가 가능하다
    public void setCompany(String company) {
        this.company = company;
    }
    
    public void setModel(String model) {
        this.model = model;
    }
    public void setColor(String color) {
        this.color = color;
    }
    public void setMaxSpeed(int maxSpeed) {
        if (maxSpeed > 250)
            maxSpeed = 250;
        this.maxSpeed = maxSpeed;
    }
}
 
cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package Practice;
 
public class CarBasicEx {
    public static void main(String[] args)    
    {
        CarBasic car = new CarBasic();
        
        car.setCompany("현대");
        car.setModel("소나타");
        car.setColor("회색");
        car.setMaxSpeed(300); // 유효성 검사로 250으로 값 변경
        
        System.out.println(car.getCompany());
        System.out.println(car.getModel());
        System.out.println(car.getColor());
        System.out.println(car.getMaxSpeed());
 
    }
}
 
cs

'생각 두 접시' 카테고리의 다른 글

[java] final  (0) 2024.06.01
[java] 메소드 재정의 @Override  (0) 2024.06.01
[java] 접근 제한자  (0) 2024.05.31
[java] 패키지  (0) 2024.05.31
중복 요소 제거와 특정 키를 기준으로 오름차순 정렬하기  (0) 2024.03.20
2024-05-31 20:34:43

접근제한자는 클래스 및 클래스의 구성 멤버에 대한 접근을 제한하는 역할이다.

다른 클래스에서 클래스를 사용하지 못하도록 막거나 (클래스 제한)

클래스로부터 객체를 생성하지 못하도록 막거나 (생성자 제한)

특정 필드와 메소드를 숨김 처리한다 (필드 / 메소드 제한)

 

defaul

클래스 선언 시 아무 제한자도 명시하지 않았다면 자동적으로 컴파일러가 붙이는 제한자.

같은 패키지 내부에서만 호출이 가능하다                                                                                                

 

public 

접근의 제한이 없어, 모든 패키지에서 호출이 가능하다.

 

protected

같은 클래스 내부에서는 public 취급, 

자식 클래스가 아닌 다른 패키지의 클래스는 접근이 제한된다.

private

클래스 내부에서만 호출이 가능하다.

1
2
3
4
5
6
7
8
9
10
11
12
package Practice;
 
public class ClassA {
    ClassA c1 = new ClassA(true);
    ClassA c2 = new ClassA(true);
    ClassA c3 = new ClassA("문자열");
    
    ClassA(int data){}
    public ClassA(boolean data) {};
    private ClassA(String data) {};
}
 
cs
1
2
3
4
5
6
7
8
9
10
11
package Practice;
 
public class ClassB {
    ClassA c1 = new ClassA(true);
    ClassA c2 = new ClassA(19);
    // default인 boolean 생성자와
    // public인 int 생성자는 호출이 가능하다.
//    ClassA c3 = new ClassA("문자열");
    // 하지만 private인 문자열 생성자는 호출이 불가능하다.
}
 
cs

 

1
2
3
4
5
6
7
8
9
10
11
12
13
package practice2;
 
import Practice.ClassA;
 
public class ClassB {
    ClassA c1 = new ClassA(true);
    // public 생성자 호출 가능
//    ClassA c2 = new ClassA(12);
    // default 생성자 호출 불가능 : package가 다름
//    ClassA c3 = new ClassA("문자열");
    // private 생성자 호출 불가능
}
 
cs

 

'생각 두 접시' 카테고리의 다른 글

[java] 메소드 재정의 @Override  (0) 2024.06.01
[java] Getter / Setter  (0) 2024.05.31
[java] 패키지  (0) 2024.05.31
중복 요소 제거와 특정 키를 기준으로 오름차순 정렬하기  (0) 2024.03.20
static에 관하여  (0) 2024.03.20
2024-05-31 17:34:31

패키지는 class를 기능별로 묶어서 그룹의 이름을 붙인 것이다.

 

상위패키지.하위패키지.클래스로 이루어진 클래스의 이름의 일부분이기도 한데,

이 때문에 클래스의 이름이 같더라도 패키지의 이름이 다르다면 다른 클래스로 취급된다.

 

클래스는 선언할 때 패키지를 결정하는데, (package packageName) 결정한 클래스와 다른 패키지(폴더) 안에 넣으면 실행되지 않는다 

 

다른 패키지에 있는 클래스를 사용하는 경우 두 가지 방법이 존재한다.

 

 

첫 번째 방법은 패키지 명이 포함된 전체 클래스 이름으로 사용한다.

java.util.Scanner sc = new java.util.Scanner(System.in);

이런 식으로 인스턴스를 만들어서 사용해도 돼지만, 사용하려는 것이 정적 필드/메서드라면 인스턴스 생성 없이 사용해도 된다.

 

두 번째 방법은 import문을 사용하여 패키지를 사용하는 것이다.

패키지 선언과 클래스 선언 사이에 import 상위패키지.하위패키지.클래스; 로 패키지를 지정한다.

ex) impoert java.util.Scanner();

Scanner sc = new Scnaner(Sytem.in);

사용하려는 패키지가 여러개인 경우 클래스별로 import 하는 대신 import.패키지명.*; 을 사용하면 해당 패키지의 모든 클래스를 사용 가능하다.

이 경우 import로 지정된 패키지의 하위 패키지는 import 대상이 아니므로, 사용하고자 한다면 따로 import 해주어야 한다.

 

서로 다른 패키지에 동일한 이름의 클래스가 있는 경우, import문을 사용하였더라도 패키지 이름 전체를 사용해서 기술해야 한다.

 

'생각 두 접시' 카테고리의 다른 글

[java] Getter / Setter  (0) 2024.05.31
[java] 접근 제한자  (0) 2024.05.31
중복 요소 제거와 특정 키를 기준으로 오름차순 정렬하기  (0) 2024.03.20
static에 관하여  (0) 2024.03.20
c#의 빠른 입출력  (0) 2024.03.20
2024-03-20 22:42:44

System.Linq(Language Intergrated Query) 네임스페이스에 속하는 

Distinct 메소드는 시퀀스에서 중복되는 요소를 제거해준다.

중복되는 요소 제거 후 반환을 IEnumerable<T> 타입으로 한다.

OrderBy 메소드는 인수로 람다 표현식을 받아 오름차순을 하고, 역시 반환을 IEnumerable<T>로 해준다.

반환된 IEnumerable<T> 형식은 리스트면 .ToList(),  배열이면 .ToArray()를 사용하면 다시 원래의 형식으로 돌려놓을 수 있다.

 

-람다 표현식?

람다 표현식 흔히 익명 함수라고 부르는데, 식별자 없이 사용 가능한게 특징이다.

예를들어 sArr = sArr.OrderBy(a => a.Length).ToArr(); 이 코드에서

(a => a.Length) 이 부분이 람다 표현식이다.

a는 OrderBy 메소드에 의해 sArr의 각 요소들을 참조하게 된다.

이 상태에서 => (람다 연산자) 에 의해 a의 길이가 구해지고,

구해진 길이를 토대로 오름차순 정렬이 수행된다.

'생각 두 접시' 카테고리의 다른 글

[java] Getter / Setter  (0) 2024.05.31
[java] 접근 제한자  (0) 2024.05.31
[java] 패키지  (0) 2024.05.31
static에 관하여  (0) 2024.03.20
c#의 빠른 입출력  (0) 2024.03.20
2024-03-20 21:03:46

static 키워드는 변수 / 메소드 / 클래스가 인스턴스에 귀속되지 않고, 클래스에 귀속되게 한다.

사용 시 '인스턴스이름.메소드이름() ' 이 아니라

'클래스이름.메소드이름()'  로 사용해야 한다.

 

c#을 구성하는 최소의 단위인 클래스는 메소드에서 인스턴스화 되어야 한다.

하지만 메소드는 클래스의 바깥에서 따로 존재 할 수 없기 때문에, 인스턴스를 생성하기 위해 인스턴스의 메소드를 사용해야 하는 역설적인 상황이 발생한다.

이럴때 인스턴스 생성 전에 메모리에 올라가는 static을 사용한다.

가장 자주 보는 예시가 바로 static void main(string[] args) - 메인 메소드이다.

참고로 c++의 경우는 함수가 클래스 바깥에서 존재할 수 있다고 하여 메인 '함수' 라고 한다.

'생각 두 접시' 카테고리의 다른 글

[java] Getter / Setter  (0) 2024.05.31
[java] 접근 제한자  (0) 2024.05.31
[java] 패키지  (0) 2024.05.31
중복 요소 제거와 특정 키를 기준으로 오름차순 정렬하기  (0) 2024.03.20
c#의 빠른 입출력  (0) 2024.03.20
2024-03-20 01:34:12

오늘 푼 문제 중 대부분이 입출력 시간을 맞추지 못해 시간 초과로 실패한 경우가 대부분이었다.

 

StringBuilder

StringBuilder는 불변성을 지니는 String 클래스의 단점을 보완하기 위해서 존재한다.

위에서 말했듯이 String 클래스는 불변하기에, 우리가 값을 수정할 때마다 저장공간에 새로운 공간을 받아서 해당 공간에 수정한 값을 집어넣는 방식으로 작동한다. (Reference값 변경)

즉 우리는 String의 값을 수정할 때마다 새로운 저장공간에 새로운 문자열을 '생성' 하고 있는 거다.

하지만 StringBuilder 는 내부적으로 값을 조합하고 삭제해서, 새로운 인스턴스 생성하지 않는다고 한다.

 

StreamReader / Writer

StreamReader와 Writer는 System.IO 네임스페이스에 속하는 클래스로 주로 파일 입출력에 사용된다고 한다.

StreamReader는 어떤 스트림(대표적으로 파일)을 읽어오고,

StreamWriter는 어떤 스트림을 쓴다.

 

OpenStandardInput / Output

간단하게 스트림을 열어주는 메소드다.

이를 통해 스트림을 읽어 들일 수 있거나, 내보낼 수 있다.

 

위의 StreamReader와 조합해서 사용한다.

ex) using var SR = new StreamReader(Console.OpenStandardInput());

      using var SW = new StreamWriter(Console.OpenStandardOutput());

     ...

     Arr[int.Parse(SR.ReadLine())];

     SW.WriteLine(Arr[i]);

'생각 두 접시' 카테고리의 다른 글

[java] Getter / Setter  (0) 2024.05.31
[java] 접근 제한자  (0) 2024.05.31
[java] 패키지  (0) 2024.05.31
중복 요소 제거와 특정 키를 기준으로 오름차순 정렬하기  (0) 2024.03.20
static에 관하여  (0) 2024.03.20