오늘 배운 내용은 생성자와 static 관련 내용들 (static 변수, static 메소드, static 클래스)
상속은 내일 다형성과 오버라이딩 배우면서 같이 정리하는것으로..
아래는 심화문제 풀이..
심화 과제 1
Math와 같은 클래스는 객체를 만들지 않고도 기능들을 만들어 사용할 수 있음을 배웠습니다. 편리한 사용을 위해 본인만의 myHelper 라는 클래스를 만들었다고 가정하겠습니다. 정수 배열을 입력받아 해당 배열의 요소들 중에서 가장 작은 값을 반환하는 정적 메소드를 하나 작성하세요. 요구 사항은 아래와 같습니다.
- 입력으로 주어지는 배열은 비어있지 않다고 가정합니다.
- 정적(static) 메서드를 사용하여 구현하여야 합니다
- 배열의 모든 요소를 반복하여 가장 작은 값을 찾아 반환하여야 합니다.
Main.cs
int min = MyHelper.FindMinimum(new int[]{3,2,10,4,5});
Console.WriteLine("최소값? :" + min);
MyHelper.cs
public static int FindMinimum(int [] intarr)
{
int min = intarr[0];
for (int i = 1; i < intarr.Length-1; i++)
{
if (intarr[i] < min)
{
min = intarr[i];
}
}
return min;
}
심화 과제 2
위의 myHelper 클래스에 정적 메소드를 하나 더 만들겠습니다. 주어진 문자열에서 대문자의 개수를 세는 정적 메소드를 구현하세요. 요구 사항은 아래와 같습니다.
- 입력으로 주어지는 문자열은 비어있지 않다고 가정하겠습니다.
- 정적 메서드를 사용하여 구현하여야 합니다.
- 문자열을 반복하여 대문자의 개수를 세고, 그 개수를 반환하여야 합니다.
- char형의 내장 기능 중, IsUpper를 활용하면 대문자 여부를 확인 가능합니다.
Main.cs
int count = MyHelper.CountUppers("아이A우에B오000bQ");
int count2 = MyHelper.CountUppers("");
Console.WriteLine("대문자 갯수? : " + count);
Console.WriteLine("대문자 갯수? : " + count2);
MyHelper.cs
public static int CountUppers(string someStr)
{
int count = 0;
if (someStr == null)
{
Console.WriteLine("지금 장난해?!");
return count;
}
char[] someCharArr = someStr.ToCharArray();
for (int i = 0; i < someCharArr.Length; i++)
{
if (char.IsUpper(someCharArr[i]))
{
count++;
}
}
return count;
}
심화 과제 3 - 업적 시스템
새로운 cs 파일을 만들고, Achievement 클래스를 생성.
아래 구현 사항을 보다가 필요해보이는 내용이 발견되면 자유롭게 추가 구현 ㄱㄱ
일반 필드 및 프로퍼티
- string Name: 업적 이름
- string Description: 업적 설명
- int Goal: 목표 수치
- int Progress: 현재 진행 수치 (기본값 0)
- bool IsCompleted: 업적 달성 여부 (기본값 false)
static 필드
- int TotalAchievements: 생성된 업적의 총 개수를 저장하는 static 필드
- int CompletedAchievements: 달성된 업적의 총 개수를 저장하는 static 필드
생성자
- 이름, 설명, 목표 수치를 받아 초기화
- 생성자가 호출될 때마다 TotalAchievements를 증가.
메서드
- AddProgress
- 반환 없음. 인자값으로 int value를 받음
- Progress에 value를 더하고 목표 수치에 도달했는지 확인
- 목표를 달성하면:
- IsCompleted를 true로 설정.
- CompletedAchievements를 1 증가.
- “업적 [업적 이름] 달성!” 출력.
- DisplayInfo
- 업적 이름, 설명, 목표 및 진행 상황, 달성 여부를 출력
- 본인 취향껏
- static 메서드: DisplaySummary
- 반환 없음
- 현재 생성된 업적의 총 개수와 달성된 업적의 총 개수를 출력
- 테스트를 위해 메인으로 이동하여 다음을 작성
- Achievement 객체를 3개 생성
- 첫 번째 업적: “초급 도전자”, “점수 100점 달성”, 목표 100
- 두 번째 업적: “중급 도전자”, “점수 500점 달성”, 목표 500
- 세 번째 업적: “고급 도전자”, “점수 1000점 달성”, 목표 1000
- 각 업적의 AddProgress 메서드를 호출하여 진행 상황을 업데이트:
- 첫 번째 업적에 AddProgress 인자값으로 100
- 두 번째 업적에 AddProgress 인자값으로 600
- 세 번째 업적에 AddProgress 인자값으로 800
- 각 업적의 DisplayInfo를 호출하여 현재 상태를 출력.
- DisplaySummary를 호출하여 총 업적 및 달성된 업적 개수를 출력.
Main.cs
Achievement[] achievements = new Achievement[4]
{
new Achievement("10살에 곰을 잡은", "10살에 곰을 잡으면 달성", 10),
new Achievement("초급 도전자", "100점 달성", 100),
new Achievement("중급 도전자", "500점 달성", 500),
new Achievement("고급 도전자", "1000점 달성", 1000)
};
achievements[1].AddProgress(100);
achievements[2].AddProgress(600);
achievements[3].AddProgress(800);
foreach (Achievement ach in achievements)
{
ach.DisplayInfo();
}
Achievement.DisplaySummary();
Achievement.cs
public class Achievement
{
private string _name;
private string _description;
private int _goal;
private int _progress;
private bool _isCompleted;
private static int _totalAchievements;
private static int _completedAchievements;
public Achievement(string name, string description, int goal)
{
_totalAchievements++;
_name = name;
_description = description;
_goal = goal;
}
private void AddCompletedAchievements()
{
_completedAchievements++;
}
public string Name
{
get { return _name; }
set { _name = value; }
}
public string Description
{
get { return _description; }
set { _description = value; }
}
public int Goal
{
get { return _goal; }
set { _goal = value; }
}
public int Progress
{
get { return _progress; }
set { _progress = value; }
}
public bool IsCompleted
{
get { return _isCompleted; }
set { _isCompleted = value; }
}
public void AddProgress(int value)
{
Progress =+ value;
if (Progress >= Goal)
{
Console.WriteLine($"업적 {Name} 달성!");
IsCompleted = true;
AddCompletedAchievements();
}
}
/* 현재 업적 정보 */
public void DisplayInfo()
{
Console.WriteLine("===\t업적\t===");
Console.WriteLine($"{Name}");
Console.WriteLine($"설명 : {Description}");
Console.WriteLine($"목표 : {Goal}");
Console.WriteLine($"현재 상황 : {Progress}");
Console.WriteLine($"달성 여부 : {IsCompleted}");
}
/* 업적 달성 요약 */
public static void DisplaySummary()
{
Console.WriteLine("===\t요약\t===");
Console.WriteLine($"현재 생성된 업적 : {_totalAchievements}");
Console.WriteLine($"현재 달성된 업적 : {_completedAchievements}");
}
}
오늘 나왔던 내용중 재미있던 내용들 정리..
자바의 한정자(final)와 c#의 Sealed 한정자
- Stackoverflow질문글
- Sealed 마소 레퍼런스
- Class
- 자바는 final c#은 sealed로 선언, 동작하는건 동일. 선언하면 클래스의 상속을 막을 수 있다.
- Method
- 자식 클래스에서 재정의 불가능한 메서드 선언.
- 메서드를 virtual이란 키워드로 선언 하지 않는 한 봉인된 메서드에서 방지 가능함? (아마 내일 추가로 배울듯)
- Variables : 요기가 가장 다름
- c#은 변수에 sealed가 없다. 다만 const나 readonly를 통해 변수가 변하지 않는다 / 한번만 대입된다를 보장가능
- 자바에는 매개변수와 필드변수에서 선언하여 바뀌지 않는다 / 한번만 대입된다를 보장 가능.
추가로..
자바 17에서 sealed 키워드가 추가되었는데 Java17 Sealed
이것은 상속을 지정한 클래스에서만 받을수 있도록 하여, c#의 sealed와는 조금 다른것 같다.
한가지 더..
Java 코드
//hello.java
public static void main(String[] args) {
System.out.println("Hello, World!");
System.out.println(SomeStaticThings.staticVariable);
// 자바는? 경고는 뜨는데 되긴됨 ㅋㅋ
SomeStaticThings someStaticVariable = new SomeStaticThings();
System.out.println(someStaticVariable.staticVariable);
someStaticVariable.staticVariable = 3;
someStaticVariable.printStaticVariable();
}
//SomeStaticThings.java
public class SomeStaticThings {
public int a = 0;
public static int staticVariable = 0;
public static void printStaticVariable() {
System.out.println(staticVariable);
}
public int plusInta(){
return a++;
}
}
c# 코드
// program.cs
public static void main(string[] args)
{
Console.WriteLine("Hello, World!");
Console.WriteLine(SomeStaticThings.staticVariable);
SomeStaticThings someStaticVariable = new SomeStaticThings();
// c#은 접근이 안됨 (컴파일러에서 오류 발생)
Console.WriteLine(someStaticVariable.staticVariable);
someStaticVariable.staticVariable = 3;
someStaticVariable.printStaticVariable();
}
// SomeStaticThings.cs
public class SomeStaticThings
{
public int a = 0;
public static int staticVariable = 0;
public static void printStaticVariable()
{
Console.WriteLine(staticVariable);
}
public int plusInta()
{
return a++;
}
}
같은 키워드를 다르게 쓰거나 다른 키워드를 언어마다 살짝씩 다르게 씀.. 재미있지 않나요!?