/* * Classes can be added in two ways. * Inheritance -- a la Java -- define a new class that has new properties and and possibly new methods. * Extension -- just add new methods & properties to existing class * This is very much like adding a method to a struct in Go * * @authod gtowell * created: August 5, 2021 */ import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.URL; // open indicates that the class is extendable // without open the class in Java would be equivalent to final // A class to hold a place. open class Place(val zipcode: String, val city:String, val state:String){ override fun toString(): String { return "P ${zipcode} ${city} ${state}" } } // Another class that inherits from Place. // Note the explicit call to the constructor of the extended class open class LocatedPlace(zipcodeP: String, cityP:String, stateP:String, val latitude:Float, val longitude:Float) : Place(zipcodeP, cityP, stateP) { override fun toString(): String { return "LP ${super.toString()} ${latitude} ${longitude}" } } // class PopulatedPlace(zipcodeP: String, cityP:String, stateP:String, latitudeP:Float, longitudeP:Float, val population: Int) : LocatedPlace(zipcodeP, cityP, stateP, latitudeP, longitudeP) { override fun toString(): String { return "PP ${super.toString()} ${population}"; } } // A method that extends the list class. // The central idea here is to return a pointer to the list fun List.pluss(neww: T) : List { return this + neww } // fairly standard method overloading. fun List.pluss(neww:List) : List { return this + neww } // extension properties exist also. Here is one for tail val List.tail: List get() = subList(1, count()) // and one for head. val List.head: T get() = first() fun tstPlaces(ff:List = listOf("00601,STANDARD,ADJUNTAS,PR,PRIMARY,18.16,-66.72,NA-US-PR-ADJUNTAS,false,,,","00601,STANDARD,ADJUNTAS,PR,PRIMARY,,,NA-US-PR-ADJUNTAS,false,,,","00601,STANDARD,ADJUNTAS,PR,PRIMARY,18.16,-66.72,NA-US-PR-ADJUNTAS,false,1,2,3")) : List { return ff.map( { q -> getPlace(q) }) } val getPlace = {line: String -> //println(line) val spl = line.replace("\"","").split(",").toTypedArray(); val lati = spl[5].toFloatOrNull() val longi = spl[6].toFloatOrNull() val popi = spl[10].toIntOrNull() // Could have used an internal function and avoided using any = if (popi != null) { // the !! means that the value is guaranteed to be non-null PopulatedPlace(spl[0], spl[2], spl[3], lati!!, longi!!, popi) } else if (longi !=null) { LocatedPlace(spl[0], spl[2], spl[3], lati!!, longi) } else { Place(spl[0], spl[2], spl[3]) } } fun main() { println(tstPlaces()) fun recurr(pl:List) { if (pl.isEmpty()) return println(pl.head) recurr(pl.tail) } recurr(tstPlaces()) }