타닥타닥 개발자의 일상

Kotlin에서 MutableList, File, 상속 이용해서 야구선수 등록 프로그램 만들기 본문

코딩 기록/Kotlin

Kotlin에서 MutableList, File, 상속 이용해서 야구선수 등록 프로그램 만들기

NomadHaven 2022. 1. 30. 21:32

만들 조건

Dao, Dto 만들기. Dto는 Human Dto에서 상속 받은 Pichter Dto, Batter Dto 사용하기.

File 클래스 만들어서 저장 기능 만들기.

 

Dao, Dto, File 별로 별개의 패키지.

Human클래스를 상속 받는 Pichter과 Batter는 같은 Dto 패키지 안에 생성.

 


DTO 패키지

 

부모 클래스인 Human클래스

package dto

open class Human(var number:Int=0,
            var name:String = "",
            var age:Int = 0,
            var height:Double = 0.0) {
            //자식 클래스에서 상속을 반드시 할수 있도록 생성자() 안에 name, age,height 속성을 넣는다.
            //상속 가능하기 위해 open이라는 단어를 class 앞에 붙인다.
        

    override fun toString(): String {
        return "$number -$name -$age -$height-"
    }

}

 

 

Human 클래스를 상속받은 Pichter 클래스

package dto

class Pitcher:Human {

    var win:Int = 0
    var lose:Int = 0
    var defense:Double= 0.0
    //Pictcher클래스에서 새롭게 생긴 속성인 win, lose, defense

    constructor():super(0,"",0,0.0)
    //부모클래스인 Human클래스에서 상속받은 number, name, age, height 속성을 초기화

    constructor(number: Int, name: String, age: Int, height: Double, win:Int, lose:Int, defense:Double) :
            super(number, name, age, height){
                this.win =win
                this.lose =lose
                this.defense = defense
            }
//생성자에서 기입해야될 속성을 나열. 상속받은 속성인 number,name,age, height는 super로, 
//Pitcher 클래스만의 속성인 win, lose, defense는 this로

    override fun toString(): String {
        return super.toString()+"$win-$lose-$defense"
        //Human클래스에서 이미 number, name, age, height의 toString을 override했므로
        설정되지 않은 win, lose, defense 속성만 toString으로 override.
    }

}

 

 

Human 클래스를 상속받은 Batter클래스

 

package dto

class Batter(number:Int, name: String, age:Int , height:Double,var batCount:Int,var hit:Int, var batAvg:Double):
    Human(number,name,age,height) {

//Batter옆의 생성자()에 Human클래스에서 상속받은 number, name, age, height 입력한 뒤
//상속받은 Human 클래스 옆 생성자()에 상속받은 속성 number, name, age, height 입력.
//새롭게 추가된 속성 batCount, hit,batAvg는 새롭게 자료형 정의.

    override fun toString(): String {
        return super.toString() + "$batCount-$hit-$batAvg"
        //Batter클래스에서 새롭게 추가된 속성 batCont, hit, batAvg만 오버라이드. 
    }
}

 

 


저장을 위한 FileData

 

 

package File

import dto.Batter
import dto.Human
import dto.Pitcher
import java.io.*

class FileData {
    //java
    private var file:File? = null
    //새롭게 생긴 File 클래스를 file이란 변수에 저장

    //kotlin
    private var filePath:String? = null
	//파일 경로를 나타내는 문자열은 filePath라는 변수에 저장

    constructor(filename:String){
        val dir = "C:\\myfile" //dir이란 값에 파일 경로 저장. C드라이브의 myfile이란 폴더.
        
        file = File("$dir\\$filename.txt") 
        //file의 경로 및 파일 이름 설정. filename이라는 parameter를 입력받아 파일 이름이 설정.

        filePath = "$dir\\$filename.txt" 
        //dir과 file을 통해 확실한 파일 명과 경로를 filePath 변수로 초기화
        

    }

    fun createFile(){
        if(file!!.createNewFile()){
        //createNewFile은 file이란 클래스에 자동 설정된 메소드
            println(file!!.name+".txt 파일을 생성하였습니다.")
        }else{
            println("파일 생성에 실패하였습니다.")
        }
    }

    fun fileSave(arrStr: Array<String?>){

      /*  val fileWriter = FileWriter(file)
        val bw = BufferedWriter(fileWriter)
        val pw = PrintWriter(bw)

        for(i in arrStr.indices){
            pw.println(arrStr[i])
        }
        pw.close()*/
        
        File(filePath).printWriter().use { out->
            for(str in arrStr){
                out.println(str)
    //filePath 경로에 있는 텍스트 파일에, 
    //파라미터로 입력받은 배열에 있는 내용을한줄씩 출력하여 저장
                
            }
        }

    }

    fun fileLoad():List<Human>?{
        val list:MutableList<Human> = ArrayList()
        //배열 불러오기
        
        list?.add(Pitcher(100,"홍길동",24,118.5,10,2,0.1))
        list?.add(Pitcher(1,"성춘향",29,180.1,100,21,0.3))
        list?.add(Batter(2,"안영미",20,175.1,111,214,0.8))
        list?.add(Batter(2,"신봉선",30,185.2,151,724,1.0))
        //배열에 미리 데이터 입력하기
/*
        val fileReader = FileReader(file)
        val br = BufferedReader(fileReader)
        var str = br.readLine()
        while (str != null && str != ""){   // 1001-홍길동-24-181.1-10-2-0.2
            val split = str.split("-".toRegex()).toTypedArray()
            val pos = split[0].toInt()

            var human = if(pos < 2000){ // 투수
                Pitcher(
                    split[0].toInt(),
                    split[1],
                    split[2].toInt(),
                    split[3].toDouble(),
                    split[4].toInt(),
                    split[5].toInt(),
                    split[6].toDouble())
            }
            else{   // 타자
                Batter(
                    split[0].toInt(),
                    split[1],
                    split[2].toInt(),
                    split[3].toDouble(),
                    split[4].toInt(),
                    split[5].toInt(),
                    split[6].toDouble())
            }
            list.add(human)

            str = br.readLine()
        }
        */

        File(filePath).useLines{
            lines -> lines.forEach { //한줄씩 읽어온다는 말
                println(it) //it = 이터레이터
                val split = it.split("-".toRegex()).toTypedArray()
                //[100,"홍길동",24,118.5,10,2,0.1] 이런식의 배열을 Array타입으로 전환
                val pos = split[0].toInt()
                //split[0]은 번호를 나타남. 번호를 정수형으로 변환한 변수가 pos


                var human = if(pos < 2000){ 
                //번호중 2000번 이상인 번호는 없으므로, pos<2000는 단순히 true를 표현하기 위한식임
                //입력된 포지션과 일치하는 형식으로 human이란 변수에 저장.
                    Pitcher(
                        split[0].toInt(),//번호를 0번째 값인 정수형으로
                        split[1], //이름을 1번째 값인 문자형으로
                        split[2].toInt(),//나이을 2번째 값인 정수형으로..
                        split[3].toDouble(),
                        split[4].toInt(),
                        split[5].toInt(),
                        split[6].toDouble())
                }
                else{   
                    Batter(
                        split[0].toInt(),
                        split[1],
                        split[2].toInt(),
                        split[3].toDouble(),
                        split[4].toInt(),
                        split[5].toInt(),
                        split[6].toDouble())
                }
                list.add(human)
                //human이란 변수에 저장된 값을 61번째 줄에서 불러온 배열에 저장
            }
        }

        return list
        //저장된 배열을 반환
    }


}

 

 

 

 


MemberDao

 

 

package dao

import File.FileData
import dto.Batter
import dto.Human
import dto.Pitcher
import java.io.*

class MemberDao {

    //list 리스트 생성하고 초기화
    private var list : MutableList<Human>? = null
    
	//파일 클래스 불러온뒤 fd란 변수에 저장하고 초기화
    private var fd:FileData? = null

    constructor(){
        list = ArrayList<Human>()

        fd = FileData("baseball") 
        //"baseball"은 File클래스에서 만들어놓은 메소드의 파라미터값. 파일이름을 나타내는 문자열.
        
        fd!!.createFile()
		//baseball이라는 이름을 가진 텍스트 파일을 생성
        
        list = fd!!.fileLoad() as MutableList<Human>
        //fileLoad() method를 통해 읽어온 값은 리스트의 값이다.

    }

    fun insert(){
        println(">>선수 등록")
        println("투수(1)/타자(2) 중 등록하고 싶은 포지션 >> ")
        val choice : Int? = readLine()?.toInt()

        //공통 데이터
        print("번호:")
        var number: Int? =  readLine()?.toInt()
        print("이름:")
        var name: String? =  readLine()?.toString()
        print("나이:")
        var age: Int? =  readLine()?.toInt()
        print("신장:")
        var height: Double? =  readLine()?.toDouble()

       var human = if(choice==1){ //투수
           print("승:")
           var win: Int? =  readLine()?.toInt()
           print("패:")
           var lose: Int? =  readLine()?.toInt()
           print("방어율:")
           var defense: Double? =  readLine()?.toDouble()

           Pitcher(number!!,name!!,age!!,height!!,win!!,lose!!,defense!!)

        } else{  //타자
           print("타수:")
           var batCount: Int? =  readLine()?.toInt()
           print("안타수:")
           var hit: Int? =  readLine()?.toInt()
           print("타율:")
           var hitAvg: Double? =  readLine()?.toDouble()

           Batter(number!!,name!!,age!!,height!!,batCount!!,hit!!,hitAvg!!)

        }
        list?.add(human)
    }

    fun delete(){
        println("방출할 선수 이름을 입력하시오")
        val name: String? = readLine()
        var findIndex = search(name!!)

        if(findIndex==-1){
            println("검색된 선수가 없습니다.")
            return
        }
        list?.removeAt(findIndex)
        println("선택한 선수를 삭제했습니다.")


    }

    fun select(){
        println("검색할 선수 이름을 입력하시오")
        val name: String? = readLine()
        var findIndex = search(name!!)

        if(findIndex==-1){
            println("검색된 선수가 없습니다.")
            return
        }

        //instanceof =>is
        if(list!![findIndex] is Pitcher){
            println("투수입니다.")
        }else{
            println("타자입니다.")
        }

        println(list!![findIndex].toString())

    }

    fun update(){
        println("수정할 선수 이름을 입력하시오")
        val name: String? = readLine()
        var findIndex = search(name!!)

        if(findIndex==-1){
            println("검색된 선수가 없습니다.")
            return
        }

        println("수정할 데이터를 입력하십시오.")
        if(list!![findIndex] is Pitcher){
            println("승:")
            val win : Int? = readLine()?.toInt()
            println("패:")
            val lose : Int? = readLine()?.toInt()
            println("방어율:")
            val defense : Double? = readLine()?.toDouble()

            val pitcher = list!![findIndex] as Pitcher // val pitcher = (Pitcher)list!![findIndex]
            pitcher.win = win!!
            pitcher.lose = lose!!
            pitcher.defense = defense!!
        }else{ //배터부분 입력
            println("안타:")
            val hit : Int? = readLine()?.toInt()
            println("타수:")
            val batCount : Int? = readLine()?.toInt()
            println("타율:")
            val batAvg : Double? = readLine()?.toDouble()

            val batter = list!![findIndex] as Batter // val pitcher = (Pitcher)list!![findIndex]
            batter.batAvg = batAvg!!
            batter.hit = hit!!
            batter.batCount = batCount!!

        }

    }

    fun allPrint(){
        for(mem in list!!){
            println(mem.toString())
        }
    }

    fun search(name:String):Int{
        var findIndex =-1
        for(i in list!!.indices){
            val h = list!![i]
            if(h.name==name){
                findIndex = i
                break
            }
        }
        return findIndex
    }

    fun fileSave(){
        // list -> array
        // 배열을 생성, 크기만을 설정
        val strArr = arrayOfNulls<String>(list!!.size)
        for (i in list!!.indices){
            strArr[i] = list!![i].toString()
        }
        fd?.fileSave(strArr)
    }

    fun hitAvgSort(){
    //Batter 만으로 리스트 생성
 /*       val sortList:List<Batter>? = list?.filterIsInstance<Batter>()
        if (sortList != null) {
            for(h in sortList){
                println(h.toString())
            }
        }
        //내림차순정렬
        val sorted = sortList?.sortedByDescending { it -> it.batAvg }
        for (h in sorted!!){
            println(h.toString())
        }*/

        //kotlin
        val sortList:List<Batter>? = list?.filterIsInstance<Batter>()?.sortedByDescending { it->it.batAvg }
        if (sortList != null) {
            for(h in sortList){
                println(h.toString())
            }
        }
    }
}

기능을 구현하는 Main클래스
import dao.MemberDao
import kotlin.system.exitProcess

fun main(args: Array<String>) {

    val memDao = MemberDao()

    while(true){
        println(" 메 뉴 ")
        println("1.선수등록")
        println("2.선수삭제")
        println("3.선수검색")
        println("4.선수수정")
        println("5.선수 모두출력")
        println("6.선수명단 저장")
        println("7.타율순으로 정렬")
        println("8.선수등록")
        println(" 메 뉴 번 호 ")
        val choice = readLine()?.toInt()
        when(choice){
            1 -> memDao.insert()
            2 -> memDao.delete()
            3 -> memDao.select()
            4 -> memDao.update()
            5 -> memDao.allPrint()
            6 -> memDao.fileSave()
            7 -> memDao.hitAvgSort()
            8 -> exitProcess(0)
            else ->{}
        }
    }
}
Comments