ไม่มีstatic
คำหลักใน Kotlin
วิธีที่ดีที่สุดในการเป็นตัวแทนของstatic
วิธีการจาวาใน Kotlin คืออะไร?
ไม่มีstatic
คำหลักใน Kotlin
วิธีที่ดีที่สุดในการเป็นตัวแทนของstatic
วิธีการจาวาใน Kotlin คืออะไร?
คำตอบ:
คุณวางฟังก์ชันใน "วัตถุที่เป็นคู่หู"
ดังนั้นรหัส java เช่นนี้:
class Foo {
public static int a() { return 1; }
}
จะกลายเป็น
class Foo {
companion object {
fun a() : Int = 1
}
}
จากนั้นคุณสามารถใช้งานได้จากภายในโค้ด Kotlin เป็น
Foo.a();
แต่จากภายในโค้ด Java คุณจะต้องเรียกมันว่า
Foo.Companion.a();
(ซึ่งยังใช้งานได้จากภายใน Kotlin)
หากคุณไม่ต้องการระบุCompanion
บิตคุณสามารถเพิ่ม@JvmStatic
คำอธิบายประกอบหรือตั้งชื่อคลาสสหายของคุณ
จากเอกสาร :
วัตถุร่วม
การประกาศวัตถุภายในชั้นเรียนสามารถทำเครื่องหมายด้วยคำหลักสหาย:
class MyClass { companion object Factory { fun create(): MyClass = MyClass() } }
สมาชิกของวัตถุที่แสดงร่วมสามารถเรียกได้โดยใช้ชื่อคลาสเป็นตัวระบุ:
val instance = MyClass.create()
...
อย่างไรก็ตามใน JVM คุณสามารถมีสมาชิกของออบเจกต์ร่วมที่สร้างขึ้นเป็นวิธีการและฟิลด์แบบสแตติกจริงหากคุณใช้
@JvmStatic
หมายเหตุประกอบ ดูที่ส่วนการทำงานร่วมกันของ Java สำหรับรายละเอียดเพิ่มเติม
การเพิ่ม@JvmStatic
คำอธิบายประกอบจะมีลักษณะดังนี้
class Foo {
companion object {
@JvmStatic
fun a() : Int = 1;
}
}
แล้วมันจะอยู่เป็นจริงฟังก์ชั่น Java คงสามารถเข้าถึงได้จากทั้ง Java และ Kotlin Foo.a()
เป็น
หากไม่ชอบCompanion
ชื่อคุณก็สามารถระบุชื่อที่ชัดเจนให้กับวัตถุที่แสดงร่วมเช่นนี้:
class Foo {
companion object Blah {
fun a() : Int = 1;
}
}
ซึ่งจะให้คุณโทรจาก Kotlin ด้วยวิธีเดียวกัน แต่จาก java like Foo.Blah.a()
(ซึ่งจะทำงานใน Kotlin ด้วย)
fun a(): Int { return 1 }
หรือแม้กระทั่งfun a(): Int = 1
fun a() = 1
แม้กระทั่ง
Factory
เป็นชื่อของวัตถุร่วม - แต่สิ่งที่สามารถนำมาใช้เพื่อ? ฉันมีความคิด แต่ผมมีความสนใจดังนั้นฉันสร้างคำถามที่ทุ่มเทให้กับว่าstackoverflow.com/q/45853459/221955
เอกสารแนะนำการแก้ปัญหาส่วนใหญ่ของความต้องการสำหรับการทำงานคงที่ที่มีฟังก์ชั่นแพคเกจระดับ พวกมันถูกประกาศนอกคลาสในไฟล์ซอร์สโค้ด แพ็คเกจของไฟล์สามารถระบุได้ที่จุดเริ่มต้นของไฟล์ด้วยคีย์เวิร์ดของแพ็กเกจ
การประกาศ
package foo
fun bar() = {}
การใช้
import foo.bar
อีกทางเลือกหนึ่ง
import foo.*
ตอนนี้คุณสามารถเรียกใช้ฟังก์ชันด้วย:
bar()
หรือถ้าคุณไม่ใช้คำสำคัญที่นำเข้า:
foo.bar()
หากคุณไม่ได้ระบุแพ็คเกจฟังก์ชันจะสามารถเข้าถึงได้จากรูท
หากคุณมีประสบการณ์กับจาวาเพียงอย่างเดียวนี่อาจดูแปลกไปหน่อย เหตุผลคือ kotlin ไม่ใช่ภาษาเชิงวัตถุอย่างเคร่งครัด คุณสามารถพูดได้ว่ามันรองรับวิธีการนอกชั้นเรียน
แก้ไข: พวกเขาได้แก้ไขเอกสารเพื่อไม่รวมประโยคเกี่ยวกับการแนะนำฟังก์ชั่นระดับแพ็คเกจ นี่คือต้นฉบับที่อ้างถึงข้างต้น
class FooPackage
คุณสมบัติและฟังก์ชันระดับบนทั้งหมดและกำหนดเส้นทางการอ้างอิงทั้งหมดของคุณอย่างเหมาะสม ข้อมูลเพิ่มเติมจาก jetbrains
bar()
ไม่สำคัญว่าชื่อไฟล์คุณสามารถตั้งชื่อBarUtils.kt
หรืออะไรก็ตามเมื่อข้อความบอกว่าคุณจะนำเข้ามันด้วยimport <package name>.bar
A. ทางจาวาเก่า:
ประกาศ a companion object
เพื่อใส่เมธอด / ตัวแปรแบบสแตติก
class Foo{
companion object {
fun foo() = println("Foo")
val bar ="bar"
}
}
การใช้:
Foo.foo() // Outputs Foo
println(Foo.bar) // Outputs bar
B. วิธี Kotlin ใหม่
ประกาศโดยตรงบนไฟล์โดยไม่มีคลาสบน.kt
ไฟล์
fun foo() = println("Foo")
val bar ="bar"
ใช้methods/variables
กับของพวกเขาชื่อ ( หลังจากนำเข้า )
ใช้:
foo() // Outputs Foo
println(bar) // Outputs bar
INSTANCE
คำหลักเช่นนี้:Foo.INSTANCE.sayFoo()
static CLASS
static methdos
เพราะด้วยวัตถุที่เป็นเพื่อนคุณยังสามารถสร้างอินสแตนซ์ของคลาส parent ได้
val
ไม่คงที่เทียบเท่ากับstatic final
ใน Java
ใช้วัตถุเพื่อแสดง val / var / method เพื่อสร้างแบบคงที่ คุณสามารถใช้ object แทนคลาส singleton ได้เช่นกัน คุณสามารถใช้คู่หูถ้าคุณต้องการทำให้คงที่ภายในชั้นเรียน
object Abc{
fun sum(a: Int, b: Int): Int = a + b
}
หากคุณต้องการโทรจาก Java:
int z = Abc.INSTANCE.sum(x,y);
ใน Kotlin ไม่สนใจ INSTANCE
มันก็ใช้ได้กับฉันเช่นกัน
object Bell {
@JvmStatic
fun ring() { }
}
จาก Kotlin
Bell.ring()
จาก Java
Bell.ring()
object objectName {
fun funName() {
}
}
คุณต้องส่งวัตถุร่วมสำหรับวิธีการคงที่เพราะ kotlin ไม่มีคำหลักคงที่ - สมาชิกของวัตถุสหายสามารถเรียกได้โดยใช้ชื่อคลาสเป็นตัวระบุ:
package xxx
class ClassName {
companion object {
fun helloWord(str: String): String {
return stringValue
}
}
}
มี 2 วิธีที่คุณสามารถใช้แบบคงที่ใน Kotlin
ก่อนอื่นให้สร้างวัตถุร่วมภายใต้ชั้นเรียน
ตัวอย่างเช่น:
class Test{
companion object{
fun isCheck(a:Int):Boolean{
if(a==0) true else false
}
}
}
คุณสามารถเรียกใช้ฟังก์ชั่นนี้เป็น
Test.Companion.isCheck(2)
อีกวิธีที่เราสามารถใช้คือการสร้างคลาสวัตถุ
object Test{
fun isCheck(a:Int):Boolean{
if(a==0) true else false
}
}
Happy Coding!
Test.Companion.isCheck(2)
) IDE Companion reference is redundant
คำเตือนการแสดงและการพูด มันสามารถลดลงได้Test.isCheck(2)
และรูปแบบที่ลดลงจะใกล้เคียงกับ java เทียบเท่า
Kotlin ไม่มีคำหลักคงที่ใด ๆ คุณใช้มันสำหรับจาวา
class AppHelper {
public static int getAge() {
return 30;
}
}
และสำหรับ Kotlin
class AppHelper {
companion object {
fun getAge() : Int = 30
}
}
โทรหาจาวา
AppHelper.getAge();
โทรหา Kotlin
AppHelper.Companion.getAge();
ฉันคิดว่ามันทำงานได้อย่างสมบูรณ์
ฉันต้องการจะเพิ่มคำตอบข้างบน
ใช่คุณสามารถกำหนดฟังก์ชั่นในไฟล์ซอร์สโค้ด (นอกคลาส) แต่มันจะดีกว่าถ้าคุณกำหนดฟังก์ชั่นแบบคงที่ภายในชั้นเรียนโดยใช้วัตถุ Companionเพราะคุณสามารถเพิ่มฟังก์ชั่นแบบคงที่มากขึ้นโดยการใช้ประโยชน์จากKotlin ส่วนขยาย
class MyClass {
companion object {
//define static functions here
}
}
//Adding new static function
fun MyClass.Companion.newStaticFunction() {
// ...
}
และคุณสามารถเรียกใช้ฟังก์ชันที่กำหนดไว้ข้างต้นได้เนื่องจากคุณจะเรียกใช้ฟังก์ชันใด ๆ ภายในวัตถุที่แสดงร่วม
แม้ว่าตอนนี้จะมีอายุมากกว่า 2 ปีและมีคำตอบมากมาย แต่ฉันก็เห็นวิธีอื่น ๆ ในการรับฟิลด์ "คงที่" Kotlin หายไป นี่คือคำแนะนำตัวอย่างสำหรับ Kotlin-Java static
interop:
สถานการณ์ที่ 1: การสร้างวิธีการคงที่ใน Kotlin สำหรับ Java
Kotlin
@file:JvmName("KotlinClass") //This provides a name for this file, so it's not defaulted as [KotlinClassKt] in Java package com.frybits class KotlinClass { companion object { //This annotation tells Java classes to treat this method as if it was a static to [KotlinClass] @JvmStatic fun foo(): Int = 1 //Without it, you would have to use [KotlinClass.Companion.bar()] to use this method. fun bar(): Int = 2 } }
ชวา
package com.frybits; class JavaClass { void someFunction() { println(KotlinClass.foo()); //Prints "1" println(KotlinClass.Companion.bar()); //Prints "2". This is the only way to use [bar()] in Java. println(KotlinClass.Companion.foo()); //To show that [Companion] is still the holder of the function [foo()] } //Because I'm way to lazy to keep typing [System.out], but I still want this to be compilable. void println(Object o) { System.out.println(o); } }
คำตอบของ Michael Anderson ให้ความลึกมากกว่านี้และควรอ้างอิงสำหรับสถานการณ์นี้อย่างแน่นอน
สถานการณ์จำลองถัดไปนี้จัดการการสร้างฟิลด์สแตติกใน Kotlin เพื่อให้ Java ไม่จำเป็นต้องโทรKotlinClass.foo()
หาเคสที่คุณไม่ต้องการฟังก์ชั่นสแตติก
สถานการณ์ที่ 2: การสร้างตัวแปรแบบคงที่ใน Kotlin สำหรับ Java
Kotlin
@file:JvmName("KotlinClass") //This provides a name for this file, so it's not defaulted as [KotlinClassKt] in Java package com.frybits class KotlinClass { companion object { //This annotation tells Kotlin to not generate the getter/setter functions in Java. Instead, this variable should be accessed directly //Also, this is similar to [@JvmStatic], in which it tells Java to treat this as a static variable to [KotlinClass]. @JvmField var foo: Int = 1 //If you want something akin to [final static], and the value is a primitive or a String, you can use the keyword [const] instead //No annotation is needed to make this a field of [KotlinClass]. If the declaration is a non-primitive/non-String, use @JvmField instead const val dog: Int = 1 //This will be treated as a member of the [Companion] object only. It generates the getter/setters for it. var bar: Int = 2 //We can still use [@JvmStatic] for 'var' variables, but it generates getter/setters as functions of KotlinClass //If we use 'val' instead, it only generates a getter function @JvmStatic var cat: Int = 9 } }
ชวา
package com.frybits; class JavaClass { void someFunction() { //Example using @JvmField println(KotlinClass.foo); //Prints "1" KotlinClass.foo = 3; //Example using 'const val' println(KotlinClass.dog); //Prints "1". Notice the lack of a getter function //Example of not using either @JvmField, @JvmStatic, or 'const val' println(KotlinClass.Companion.getBar()); //Prints "2" KotlinClass.Companion.setBar(3); //The setter for [bar] //Example of using @JvmStatic instead of @JvmField println(KotlinClass.getCat()); KotlinClass.setCat(0); } void println(Object o) { System.out.println(o); } }
หนึ่งในคุณสมบัติที่ยอดเยี่ยมเกี่ยวกับ Kotlin คือคุณสามารถสร้างฟังก์ชั่นและตัวแปรระดับบนสุด สิ่งนี้ทำให้เกิดความปรารถนาในการสร้างรายการ "classless" ของเขตข้อมูลและฟังก์ชันคงที่ซึ่งสามารถใช้เป็นstatic
ฟังก์ชัน / เขตข้อมูลใน Java
สถานการณ์จำลอง 3: การเข้าถึงฟิลด์และฟังก์ชันระดับสูงสุดใน Kotlin จาก Java
Kotlin
//In this example, the file name is "KSample.kt". If this annotation wasn't provided, all functions and fields would have to accessed //using the name [KSampleKt.foo()] to utilize them in Java. Make life easier for yourself, and name this something more simple @file:JvmName("KotlinUtils") package com.frybits //This can be called from Java as [KotlinUtils.TAG]. This is a final static variable const val TAG = "You're it!" //Since this is a top level variable and not part of a companion object, there's no need to annotate this as "static" to access in Java. //However, this can only be utilized using getter/setter functions var foo = 1 //This lets us use direct access now @JvmField var bar = 2 //Since this is calculated at runtime, it can't be a constant, but it is still a final static variable. Can't use "const" here. val GENERATED_VAL:Long = "123".toLong() //Again, no need for @JvmStatic, since this is not part of a companion object fun doSomethingAwesome() { println("Everything is awesome!") }
ชวา
package com.frybits; class JavaClass { void someFunction() { println(KotlinUtils.TAG); //Example of printing [TAG] //Example of not using @JvmField. println(KotlinUtils.getFoo()); //Prints "1" KotlinUtils.setFoo(3); //Example using @JvmField println(KotlinUtils.bar); //Prints "2". Notice the lack of a getter function KotlinUtils.bar = 3; //Since this is a top level variable, no need for annotations to use this //But it looks awkward without the @JvmField println(KotlinUtils.getGENERATED_VAL()); //This is how accessing a top level function looks like KotlinUtils.doSomethingAwesome(); } void println(Object o) { System.out.println(o); } }
การกล่าวถึงที่น่าสังเกตอีกประการหนึ่งที่สามารถใช้ใน Java เป็นเขตข้อมูล "คงที่" คือobject
คลาสKotlin เหล่านี้เป็นพารามิเตอร์ศูนย์เดี่ยวชั้นเรียนที่มีอินสแตนซ์ขี้เกียจเมื่อใช้ครั้งแรก ข้อมูลเพิ่มเติมเกี่ยวกับพวกเขาสามารถพบได้ที่นี่: https://kotlinlang.org/docs/reference/object-declarations.html#object-declarations
อย่างไรก็ตามในการเข้าถึงซิงเกิลINSTANCE
นั้นจะมีการสร้างวัตถุพิเศษซึ่งยุ่งยากในการจัดการตามที่เป็นCompanion
อยู่ ต่อไปนี้เป็นวิธีใช้คำอธิบายประกอบเพื่อให้static
ความรู้สึกสะอาดใน Java:
สถานการณ์ที่ 4: การใช้
object
คลาสKotlin
@file:JvmName("KotlinClass") //This provides a name for this file, so it's not defaulted as [KotlinClassKt] in Java package com.frybits object KotlinClass { //No need for the 'class' keyword here. //Direct access to this variable const val foo: Int = 1 //Tells Java this can be accessed directly from [KotlinClass] @JvmStatic var cat: Int = 9 //Just a function that returns the class name @JvmStatic fun getCustomClassName(): String = this::class.java.simpleName + "boo!" //Getter/Setter access to this variable, but isn't accessible directly from [KotlinClass] var bar: Int = 2 fun someOtherFunction() = "What is 'INSTANCE'?" }
ชวา
package com.frybits; class JavaClass { void someFunction() { println(KotlinClass.foo); //Direct read of [foo] in [KotlinClass] singleton println(KotlinClass.getCat()); //Getter of [cat] KotlinClass.setCat(0); //Setter of [cat] println(KotlinClass.getCustomClassName()); //Example of using a function of this 'object' class println(KotlinClass.INSTANCE.getBar()); //This is what the singleton would look like without using annotations KotlinClass.INSTANCE.setBar(23); println(KotlinClass.INSTANCE.someOtherFunction()); //Accessing a function in the object class without using annotations } void println(Object o) { System.out.println(o); } }
เพื่อให้สั้นคุณสามารถใช้"วัตถุร่วม"เพื่อเข้าสู่โลกคงที่ Kotlin เช่น:
companion object {
const val TAG = "tHomeFragment"
fun newInstance() = HomeFragment()
}
และเพื่อให้ฟิลด์คงที่ให้ใช้"const val"ดังในรหัส แต่พยายามหลีกเลี่ยงคลาสสแตติกเนื่องจากมันสร้างปัญหาในการทดสอบหน่วยโดยใช้ Mockito!
การแปลงที่แน่นอนของวิธีการจาวาแบบคงที่เพื่อเทียบเท่า kotlin จะเป็นเช่นนี้ เช่นที่นี่ชั้น util มีวิธีหนึ่งคงที่ซึ่งจะเทียบเท่าทั้งใน java และ kotlin การใช้@JvmStaticเป็นสิ่งสำคัญ
รหัส Java:
class Util{
public static String capitalize(String text){
return text.toUpperCase();}
}
รหัส Kotlin:
class Util {
companion object {
@JvmStatic
fun capitalize(text:String): String {
return text.toUpperCase()
}
}
}
เพียงคุณต้องสร้างวัตถุร่วมและวางฟังก์ชันไว้ในนั้น
class UtilClass {
companion object {
// @JvmStatic
fun repeatIt5Times(str: String): String = str.repeat(5)
}
}
ในการเรียกใช้เมธอดจากคลาส kotlin:
class KotlinClass{
fun main(args : Array<String>) {
UtilClass.repeatIt5Times("Hello")
}
}
หรือใช้การนำเข้า
import Packagename.UtilClass.Companion.repeatIt5Times
class KotlinClass{
fun main(args : Array<String>) {
repeatIt5Times("Hello")
}
}
ในการเรียกใช้เมธอดจากคลาส java:
class JavaClass{
public static void main(String [] args){
UtilClass.Companion.repeatIt5Times("Hello");
}
}
หรือโดยการเพิ่มคำอธิบายประกอบ @JvmStatic ให้กับวิธีการ
class JavaClass{
public static void main(String [] args){
UtilClass.repeatIt5Times("Hello")
}
}
หรือทั้งสองอย่างโดยการเพิ่มคำอธิบายประกอบ @JvmStatic ให้กับวิธีการและการนำเข้าแบบคงที่ใน java
import static Packagename.UtilClass.repeatIt5Times
class JavaClass{
public static void main(String [] args){
repeatIt5Times("Hello")
}
}
สำหรับ Java:
public class Constants {
public static final long MAX_CLICK_INTERVAL = 1000;}
รหัส Kotlin ที่เทียบเท่า:
object Constants {
const val MAX_CLICK_INTERVAL: Long = 1000}
ดังนั้นสำหรับเทียบเท่าของวิธีการคงที่ Java เป็นระดับวัตถุใน Kotlin
สำหรับ Android ที่ใช้สตริงจากกิจกรรมเดียวไปยังกิจกรรมที่จำเป็นทั้งหมด เหมือนสถิตใน java
public final static String TEA_NAME = "TEA_NAME";
วิธีการที่เท่าเทียมกันใน Kotlin:
class MainActivity : AppCompatActivity() {
companion object {
const val TEA_NAME = "TEA_NAME"
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
กิจกรรมอื่นที่ต้องการคุณค่า:
val teaName = MainActivity.TEA_NAME
ยกเว้นคำตอบของไมเคิลแอนเดอร์สันฉันได้เขียนโค้ดกับอีกสองทางในโครงการของฉัน
คุณสามารถเปลี่ยนตัวแปรทั้งหมดให้เป็นหนึ่งคลาสได้ สร้างไฟล์ kotlin ชื่อ Const
object Const {
const val FIRST_NAME_1 = "just"
const val LAST_NAME_1 = "YuMu"
}
คุณสามารถใช้มันใน kotlin และรหัส java
Log.d("stackoverflow", Const.FIRST_NAME_1)
คุณสามารถใช้ฟังก์ชั่นเสริมของ Kotlin
สร้างไฟล์ kotlin ชื่อ Ext, ด้านล่างรหัสเป็นรหัสทั้งหมดในไฟล์ Ext
package pro.just.yumu
/**
* Created by lpf on 2020-03-18.
*/
const val FIRST_NAME = "just"
const val LAST_NAME = "YuMu"
คุณสามารถใช้มันในรหัส kotlin
Log.d("stackoverflow", FIRST_NAME)
คุณสามารถใช้มันในโค้ดจาวา
Log.d("stackoverflow", ExtKt.FIRST_NAME);
เขียนโดยตรงไปยังไฟล์
ใน Java (น่าเกลียด):
package xxx;
class XxxUtils {
public static final Yyy xxx(Xxx xxx) { return xxx.xxx(); }
}
ใน Kotlin:
@file:JvmName("XxxUtils")
package xxx
fun xxx(xxx: Xxx): Yyy = xxx.xxx()
โค้ดสองชิ้นเหล่านั้นมีค่าเท่ากับหลังการคอมไพล์ (แม้แต่ชื่อไฟล์ที่คอมไพล์แล้ว, file:JvmName
ใช้เพื่อควบคุมชื่อไฟล์ที่คอมไพล์, ซึ่งควรใส่ก่อนการประกาศชื่อแพ็คเกจ)
ใช้@JVMStatic
คำอธิบายประกอบ
companion object {
// TODO: Rename and change types and number of parameters
@JvmStatic
fun newInstance(param1: String, param2: String) =
EditProfileFragment().apply {
arguments = Bundle().apply {
putString(ARG_PARAM1, param1)
putString(ARG_PARAM2, param2)
}
}
}
ให้คุณได้เรียนนักศึกษา และคุณมีหนึ่งคงวิธีgetUniversityName ()และหนึ่งคงข้อมูลที่เรียกว่าtotalStudent
คุณควรประกาศบล็อกวัตถุร่วมภายในชั้นเรียนของคุณ
companion object {
// define static method & field here.
}
จากนั้นชั้นเรียนของคุณดูเหมือน
class Student(var name: String, var city: String, var rollNumber: Double = 0.0) {
// use companion object structure
companion object {
// below method will work as static method
fun getUniversityName(): String = "MBSTU"
// below field will work as static field
var totalStudent = 30
}
}
จากนั้นคุณสามารถใช้วิธีการคงที่และฟิลด์เช่นนี้
println("University : " + Student.getUniversityName() + ", Total Student: " + Student.totalStudent)
// Output:
// University : MBSTU, Total Student: 30
ไม่มีคำหลักคงที่ใน kotlin kotlin docs แนะนำให้ใช้ฟังก์ชั่นระดับแพ็คเกจหากคุณต้องการติดตาม DRY สร้างไฟล์ที่มีนามสกุล. tkและใส่วิธีการของคุณลงไป
package p
fun m(){
//fun body
}
หลังจากรวบรวมmจะมีลายเซ็นของโมฆะสุดท้ายคงที่สาธารณะ
และ
import p.m
☺
คุณสามารถบรรลุฟังก์ชั่นคงที่ใน Kotlin โดยCompanion Objects
วัตถุสหายไม่สามารถประกาศนอกชั้นเรียน
class MyClass{
companion object {
val staticField = "This is an example of static field Object Decleration"
fun getStaticFunction(): String {
return "This is example of static function for Object Decleration"
}
}
}
สมาชิกของวัตถุที่แสดงร่วมสามารถเรียกได้โดยใช้ชื่อคลาสเป็นตัวระบุ:
เอาท์พุท:
MyClass.staticField // This is an example of static field Object Decleration
MyClass.getStaticFunction() : // This is an example of static function for Object Decleration
สมาชิกคงที่และฟังก์ชั่นทั้งหมดควรอยู่ในบล็อกสหาย
companion object {
@JvmStatic
fun main(args: Array<String>) {
}
fun staticMethod() {
}
}
ผู้คนจำนวนมากพูดถึงวัตถุสหายซึ่งถูกต้อง แต่เพื่อให้คุณรู้คุณสามารถใช้วัตถุประเภทใดก็ได้ (โดยใช้คำสำคัญของวัตถุไม่ใช่คลาส) เช่น
object StringUtils {
fun toUpper(s: String) : String { ... }
}
ใช้มันเหมือนกับวิธีคงที่ใด ๆ ใน java:
StringUtils.toUpper("foobar")
รูปแบบดังกล่าวนั้นไร้ประโยชน์ใน Kotlin แต่จุดแข็งอย่างหนึ่งของมันคือการกำจัดความจำเป็นในการเรียนที่เต็มไปด้วยวิธีการคงที่ มันเหมาะสมกว่าที่จะใช้ฟังก์ชั่นสากลส่วนขยายและ / หรือท้องถิ่นแทนขึ้นอยู่กับกรณีการใช้งานของคุณ ที่ที่ฉันทำงานเรามักจะกำหนดฟังก์ชั่นการขยายแบบโกลบอลในไฟล์ flat แยกต่างหากด้วยหลักการตั้งชื่อ: [className] Extensions.kt ie, FooExtensions.kt แต่โดยทั่วไปแล้วเราเขียนฟังก์ชันที่ต้องการใช้ในคลาสปฏิบัติการหรือวัตถุ
ใน Java เราสามารถเขียนในวิธีด้านล่าง
class MyClass {
public static int myMethod() {
return 1;
}
}
ใน Kotlin เราสามารถเขียนได้ด้านล่าง
class MyClass {
companion object {
fun myMethod() : Int = 1
}
}
สหายถูกใช้เป็นแบบคงที่ใน Kotlin
ผู้ให้บริการเอกสาร kotlin สามวิธีในการทำสิ่งแรกคือกำหนดฟังก์ชันในแพ็คเกจโดยไม่มีคลาส:
package com.example
fun f() = 1
ที่สองคือการใช้คำอธิบายประกอบ @JvmStatic:
package com.example
class A{
@JvmStatic
fun f() = 1
}
และที่สามคือการใช้วัตถุสหาย:
package com.example
clss A{
companion object{
fun f() = 1
}
}
หากคุณต้องการฟังก์ชั่นหรือคุณสมบัติที่จะผูกกับคลาสแทนที่จะเป็นอินสแตนซ์ของมันคุณสามารถประกาศมันภายในวัตถุที่เป็นเพื่อนร่วม:
class Car(val horsepowers: Int) {
companion object Factory {
val cars = mutableListOf<Car>()
fun makeCar(horsepowers: Int): Car {
val car = Car(horsepowers)
cars.add(car)
return car
}
}
}
วัตถุสหายคือซิงเกิลและสมาชิกสามารถเข้าถึงได้โดยตรงผ่านชื่อของชั้นที่มี
val car = Car.makeCar(150)
println(Car.Factory.cars.size)
คุณสามารถใช้วัตถุร่วม - kotlinlang
ซึ่งมันสามารถแสดงได้โดยสร้างอินเทอร์เฟซนั้นก่อน
interface I<T> {
}
จากนั้นเราต้องสร้างฟังก์ชั่นภายในอินเทอร์เฟซนั้น:
fun SomeFunc(): T
หลังจากนั้นเราต้องการคลาส:
class SomeClass {}
ภายในคลาสนั้นเราจำเป็นต้องมี Object สหายภายในคลาสนั้น:
companion object : I<SomeClass> {}
ภายใน Companion Object นั้นเราต้องการSomeFunc
ฟังก์ชั่นแบบเก่าแต่เราต้องขับมัน:
override fun SomeFunc(): SomeClass = SomeClass()
ในที่สุดด้านล่างของงานทั้งหมดนั้นเราต้องการบางสิ่งบางอย่างเพื่อเพิ่มพลังให้กับฟังก์ชั่นคงที่เราต้องการตัวแปร
var e:I<SomeClass> = SomeClass()