#8 kotlin classとinterfaces
10500 ワード
kotlinは宣言クラスがswiftよりも簡潔である
Kotlinの書き方、直接プロパティをコンストラクタに定義する
また、コンストラクタでは
他の言語とは異なり、オブジェクト構造(
クラスの各
例:
kotlinバージョン:
別の例:
次のようになります. setterの を表す.
他の言語と通じないところ子クラスが継承する場合、親クラスは構造 を完了する必要がある.
この感覚は少し変で、他の言語と少し違います.swiftで例を挙げます.
kotlinでは、
kotlinコンストラクタのパラメータのため、実際には属性は、継承時に親の属性の初期化が完了していることを確認します(個人的には書き方が少し違和感があります)アクセス修飾子 kotlinのクラスと属性は、デフォルトの修飾子が varおよびval修飾属性 継承関係では、親クラスで
また、親クラスでは
1つのクラスが
kotlinの抽象クラスは他の言語と基本的に類似しており、抽象クラスは抽象属性と抽象方法を持つことができ、サブクラスは抽象クラスで定義された抽象属性と方法を実現しなければならない.
kotlinは他の言語と同様に1つのクラスしか継承できませんが、複数のインタフェースを実現できます.一般書き方 Getter & setter
インタフェースにはプロパティも定義できます.プロパティは
である. . です.
大まかな内容:クラスの定義 初期化ブロック getterとsetter( クラスの継承 注意修飾子の使用 抽象クラス もある.
インタフェースの使用 は、デフォルトのインプリメンテーションまたは抽象的な を提供することができる.はgetterとsetterを使用することができるが、setterでは は使用できない.
補助論理キーワード
// swift
class Dog {
//
var name: String
var weight: Int
init(name: String, weight: Int) {
self.name = name
self.weight = weight
}
}
Kotlinの書き方、直接プロパティをコンストラクタに定義する
// kotlin
class Dog(val name: String, var weight: Int) {}
//
class Dog(name: String, weight: Int) {
val name = name
var weight = weight
}
また、コンストラクタでは
val | var
を使用して属性を定義する必要があります.val
で定義された属性は、付与後は変更できません.すなわち、属性は読み取り専用です.var dog = Dog("Lisa", 20)
dog.weight = 30 // weight var
dog.name = "Doge" // Error val
イニシャルブロック
他の言語とは異なり、オブジェクト構造(
constructor
)が完了した後、データのロードなどの複雑な操作をしたい場合は、init
を使用して追加の操作を実行できます.class Dog(val name: String, var weight: Int) {
// init blocks
//
init {
println("the first init block")
}
init {
println("the second init block")
}
}
Getter and Setter
クラスの各
var
宣言を使用するプロパティには、デフォルトでgetterとsetterが割り当てられていますが、val
宣言を使用するプロパティは、1つのgetterにのみ与えられます.var someProperty: String
get() = field
set(value) {
field = value
}
val readOnlyProperty: String
get() = field
例:
// swift
class Point {
var x = 0.0, y = 0.0
}
class Size {
var width = 0.0, height = 0.0
}
class Rect {
var origin = Point()
var size = Size()
var center: Point {
get {
let centerX = origin.x + (size.width / 2)
let centerY = origin.y + (size.height / 2)
return Point(centerX, centerY)
}
set(newCenter) {
//
origin.x = newCenter - (size.width / 2)
origin.y = newCenter - (size.height / 2)
}
}
}
kotlinバージョン:
// kotlin
class Point(var x: Double = 0.0, var y: Double = 0.0) {}
class Size(var width: Double = 0.0, var height: Double = 0.0) {}
class Rect(var origin: Point = Point(), var size: Size = Size()) {
var center: Point
get() {
val centerX = origin.x + (size.width / 2)
val centerY = origin.y + (size.height / 2)
return Point(centerX, centerY)
}
set(value) {
//
origin.x = value - (size.width / 2)
origin.y = value - (size.height / 2)
}
}
別の例:
// kotlin
class Dog(val name: String, var weight_param: Int) {
var weight = weight_param
set(value) {
// field
if (value > 0) field = value
}
var weightInKgs: Double
// get body =
get() = weight / 2.2
}
次のようになります.
field
は、前方参照属性クラスの継承
他の言語と通じないところ
この感覚は少し変で、他の言語と少し違います.swiftで例を挙げます.
// Swift
//
class Car {
let make: Int
let model: String
init(make: Int, model: String) {
self.make = make
self.model = model
}
func move() {
print("A car is moving")
}
}
//
class ConvertibleCar: Car {
override func move() {
print("A convertible car is moving")
}
}
let myCar = COnvertibleCar(make: 1990, model: "WorksWagen")
myCar.move()
kotlinでは、
// kotlin
open class Car(open val make: Int, open val model: String) {
open fun move() {
println("a car is moving")
}
}
//
class ConvertibleCar(override val make: Int, override val model: String): Car(make, model) {
override fun move() {
println("a convertible car is moving")
}
}
val myCar = ConvertibleCar(1990, "WorksWagen")
myCar.move()
kotlinコンストラクタのパラメータのため、実際には属性は、継承時に親の属性の初期化が完了していることを確認します(個人的には書き方が少し違和感があります)
final
であり、継承され、属性がoverrideになりたい場合は、修飾修飾修飾子をopen
に変更する必要があります.// kotlin
// Car open final
// make, model override, open
open class Car(open val make: Int, open val model: String) {
// override
fun bark() {
println("bark ...")
}
open fun move() {
println("a car is moving")
}
}
//
class ConvertibleCar(override val make: Int, override val model: String): Car(make, model) {
override fun move() {
println("a convertible car is moving")
}
}
val myCar = ConvertibleCar(1990, "WorksWagen")
myCar.move()
val
で宣言された属性を使用し、変更が必要な場合はoverride
のキーワードを使用し、var
で修飾された属性を使用する場合はinit block
で変更できます.// val
open class Car(open val make: Int, open val model: String) {
open val image = "" //
fun bark() {
println("bark ...")
}
open fun move() {
println("a car is moving")
}
}
class ConvertibleCar(override val make: Int, override val model: String): Car(make, model) {
// override
override val image: String = "convertibleCar.jpg"
override fun move() {
println("a convertible car is moving")
}
}
// var
open class Car(open val make: Int, open val model: String) {
// open
var image = "" //
fun bark() {
println("bark ...")
}
open fun move() {
println("a car is moving")
}
}
class ConvertibleCar(override val make: Int, override val model: String): Car(make, model) {
// initializer block
init {
image = "convertibleCar.jpg"
}
override fun move() {
println("a convertible car is moving")
}
}
また、親クラスでは
val
で宣言された属性を使用し、子クラスではvar
でoverrideを行うことができる.ただし、親にはvar
で宣言された属性が使用され、子にはval
でoverrideを使用できません.open class Animal {
open val name: String = ""
}
class Dog: Animal() {
// var name
// setter
override var name = "lily"
}
抽象クラス
1つのクラスが
abstract
を使用する抽象クラスとして宣言する場合、open
を使用して修飾する必要はない.abstract class Animal {}
kotlinの抽象クラスは他の言語と基本的に類似しており、抽象クラスは抽象属性と抽象方法を持つことができ、サブクラスは抽象クラスで定義された抽象属性と方法を実現しなければならない.
abstract class Animal {
abstract val image: String
abstract val food: String
var hunger = 10
abstract fun makeNoise()
abstract fun eat()
open fun roam() {
println("animal is roaming")
}
fun sleep() {
println("animal is sleeping")
}
}
//
abstract class Canine: Animal() {
override fun roam() {
println("the canine is roaming)
}
}
//
//
class Wolf: Canine() {
override val image = "wolf.jpg"
override val food = "meat"
override fun makeNoise() {
println("Hooowwwl")
}
override fun eat() {
println("the wolf is eating $food")
}
}
インタフェース
kotlinは他の言語と同様に1つのクラスしか継承できませんが、複数のインタフェースを実現できます.
interface
のキーワードを使用して、実装を与えることができて、実装を与えないことができます// ,
interface IFlyable {
fun fly()
}
//
// override
interface IFlyable {
fun fly() {
println("I can fly")
}
}
インタフェースにはプロパティも定義できます.プロパティは
get()
で値を返すことができます.インタフェースにコンストラクタがないため、直接値を初期化することはできません.//
interface IFlyable {
fun fly()
// error: Property initializers are not allowed in interfaces
val velocity: Int = 20
}
//
interface IFlyable {
fun fly()
// val var
val velocity: Int
get() = 20
}
setter
では、インタフェースに後方参照フィールドが存在しないため、field
では使用できません.//
interface IFlyable {
fun fly()
// error: Property in an interface cannot have a backing field
var velocity: Int
get() = 20
set(value) {
if value > 0 {
field = value
}
}
}
//
interface IFlyable {
fun fly()
// var val setter
var velocity: Int
get() = 20
set(value) {
if value > 0 {
// field
print("your value is greater than 0")
}
}
}
is & as & when
is
はあるタイプかどうかを判断するために用いる、!is
はこれとは逆(この書き方を初めて見た)abstract class Animal {
abstract val food: String
fun eat() {
println("animal is eating $food")
}
}
class Dog: Animal() {
override val food = "meat"
fun bark() {
println("a dog is barking")
}
}
var a = Dog()
if (a is Dog) {
a.bark()
}
as
:タイプ変換に使用する、is
はインテリジェント変換を実行するが、インテリジェント変換が失敗する場合があり、as
を使用して明示的な変換を行う必要があるinterface IRunable {
fun run()
}
abstract class Animal: IRunable {
abstract val food: String
fun eat() {
println("animal is eating $food")
}
override fun run() {
println("some animal can run")
}
}
class Dog: Animal() {
override val food = "meat"
fun bark() {
println("a dog is barking")
}
}
class Ground {
// var something
var something: IRunable = Dog()
fun showInfo() {
//
// Smart cast to 'Dog' is impossible because 'something' is a mutable property that
// could hae been changed by this time
if (something is Dog) {
something.bark()
}
}
}
// , as
class Ground {
// var something
var something: IRunable = Dog()
fun showInfo() {
if (something is Dog) {
(something as Dog).bark() //
}
}
}
when
:これが他の言語のswitch...case
// 1
var temperature = 30
var isCool: Boolean = when {
temperature > 28 -> false
else -> true
}
// 2 is
when (animal) {
is Dog -> {
// ...
}
is Cat -> {
// ...
}
}
大まかな内容:
field
キーワード)open | final
var & val
属性の違いを修飾し、overrideの場合は注意が必要であり、init blockの使用field
is & !is
as
when