Tương đương với các phương thức tĩnh Java trong Kotlin là gì?


619

Không có statictừ khóa trong Kotlin.

Cách tốt nhất để biểu diễn một staticphương thức Java trong Kotlin là gì?



13
Xin lưu ý: Kotlin đã loại bỏ các thống kê theo kiểu Java để khuyến khích các hoạt động mã hóa dễ bảo trì hơn (dám nói là 'tốt hơn'). Các quả cầu tĩnh nói chung chống lại mô hình OOP nhưng chúng có thể khá thuận tiện. Do đó, Kotlin đã cung cấp cho chúng tôi những người bạn đồng hành, một cách thân thiện hơn với OOP.
Nicholas Miller

Kotlin hiện là ngôn ngữ ưa thích để phát triển Android, theo Google.
AFD

@NicholasMiller tại sao nó thân thiện với OOP hơn? Tôi nghĩ rằng nó dễ dàng hơn để đọc và viết mà không cần ghi chú định kỳ của tĩnh (soạn sẵn). Hoặc có một lý do tốt?
Torben G

Câu trả lời:


888

Bạn đặt hàm trong "đối tượng đồng hành".

Vì vậy, mã java như thế này:

class Foo {
  public static int a() { return 1; }
}

sẽ trở thành

class Foo {
  companion object {
     fun a() : Int = 1
  }
}

Sau đó, bạn có thể sử dụng nó từ bên trong mã Kotlin như

Foo.a();

Nhưng từ bên trong mã Java, bạn sẽ cần gọi nó là

Foo.Companion.a();

(Cũng hoạt động từ bên trong Kotlin.)

Nếu bạn không muốn chỉ định Companionbit, bạn có thể thêm @JvmStaticchú thích hoặc đặt tên cho lớp đồng hành của mình.

Từ tài liệu :

Đối tượng đồng hành

Một khai báo đối tượng bên trong một lớp có thể được đánh dấu bằng từ khóa đồng hành:

class MyClass {
   companion object Factory {
       fun create(): MyClass = MyClass()
   }
}

Các thành viên của đối tượng đồng hành có thể được gọi bằng cách sử dụng tên lớp đơn giản là vòng loại:

val instance = MyClass.create()

...

Tuy nhiên, trên JVM, bạn có thể có các thành viên của các đối tượng đồng hành được tạo như các phương thức và trường tĩnh thực sự, nếu bạn sử dụng @JvmStatic chú thích. Xem phần khả năng tương tác Java để biết thêm chi tiết.

Thêm @JvmStaticchú thích trông như thế này

class Foo {
  companion object {
    @JvmStatic
    fun a() : Int = 1;
  }
}

và sau đó nó sẽ tồn tại như một hàm tĩnh Java thực, có thể truy cập từ cả Java và Kotlin như Foo.a() .

Nếu nó không thích Companiontên, thì bạn cũng có thể cung cấp một tên rõ ràng cho đối tượng đồng hành trông như thế này:

class Foo {
  companion object Blah {
    fun a() : Int = 1;
  }
}

sẽ cho phép bạn gọi nó từ Kotlin theo cách tương tự, nhưng từ java như Foo.Blah.a()(cũng sẽ hoạt động trong Kotlin).


4
Trong Kotlin, nó sẽ fun a(): Int { return 1 }hoặc thậm chífun a(): Int = 1
Dmitry Zaytsev

3
@DmitryZaitsev hoặc thậm chí fun a() = 1.
Moira

Nhà máy có nghĩa là gì?
Bagus Aji Santoso

@BagusAjiSantoso Factorytên của đối tượng đồng hành - nhưng cái đó có thể được sử dụng để làm gì? Tôi không có ý tưởng, nhưng tôi đã quan tâm vì vậy tôi đã tạo ra một câu hỏi dành riêng cho điều đó: stackoverflow.com/q/45853459/221955 .
Michael Anderson

1
@ Yajairo87 Tôi nghĩ những gì bạn hỏi quá nhiều để đưa ra nhận xét ở đây - vì vậy tôi đã tạo một câu hỏi giải quyết trực tiếp: stackoverflow.com/questions/47046474/
Michael Anderson

154

Docs khuyên bạn nên giải quyết hầu hết các nhu cầu cho các hàm tĩnh với các hàm cấp gói . Chúng chỉ đơn giản được khai báo bên ngoài một lớp trong tệp mã nguồn. Gói của một tệp có thể được chỉ định ở đầu tệp với từ khóa gói.

Tờ khai

package foo

fun bar() = {}

Sử dụng

import foo.bar

Hoặc

import foo.*

Bây giờ bạn có thể gọi hàm với:

bar()

hoặc nếu bạn không sử dụng từ khóa nhập khẩu:

foo.bar()

Nếu bạn không chỉ định gói, chức năng sẽ có thể truy cập từ thư mục gốc.

Nếu bạn chỉ có kinh nghiệm với java, điều này có vẻ hơi lạ. Lý do là kotlin không phải là một ngôn ngữ hướng đối tượng nghiêm ngặt. Bạn có thể nói nó hỗ trợ các phương thức bên ngoài các lớp.

Chỉnh sửa: Họ đã chỉnh sửa tài liệu để không còn bao gồm câu về đề xuất các chức năng cấp gói. Đây là bản gốc đã được đề cập ở trên.


8
Lưu ý rằng dưới vỏ bọc, các hàm "cấp cao nhất" hoặc "gói" này thực sự được biên dịch thành lớp riêng của chúng. Trong ví dụ trên, trình biên dịch sẽ tạo một class FooPackagevới tất cả các thuộc tính và hàm cấp cao nhất và định tuyến tất cả các tham chiếu của bạn đến chúng một cách thích hợp. Thông tin thêm từ jetbrains.
Mitchell Tracy

29
+1 Để giải thích cách thực hiện quyền tương đương trong Kotlin thay vì chỉ tương đương với gương tương tự từ Java.
phượng hoàng

1
Đây phải là câu trả lời được chấp nhận hoặc một bản mod nên cập nhật câu trả lời được chấp nhận để chứa các hàm cấp gói
Osama Shabrez

@MitchellTvery Một chút thông tin tuyệt vời! Cảm ơn.
Một Droid

1
Đây là giải pháp tốt hơn cho đến nay. Chỉ muốn làm rõ rằng nơi bạn xác định hàm bar()không quan trọng tên tệp, bạn có thể đặt tên cho nó BarUtils.kthoặc bất cứ điều gì, sau đó như văn bản nói rằng bạn sẽ nhập nó vớiimport <package name>.bar
Mariano Ruiz

33

A. Cách Java cũ:

  1. Khai báo a companion objectđể đặt một phương thức / biến tĩnh

    class Foo{
    companion object {
        fun foo() = println("Foo")
        val bar ="bar"  
        }
    }
  2. Sử dụng :

    Foo.foo()        // Outputs Foo    
    println(Foo.bar) // Outputs bar


B. Cách thức mới của Kotlin

  1. Khai báo trực tiếp trên tệp mà không có lớp trên .kttệp.

    fun foo() = println("Foo")
    val bar ="bar"
  2. Sử dụng methods/variablesvới tên của họ . ( Sau khi nhập chúng )

    Sử dụng :

    foo()        // Outputs Foo          
    println(bar) // Outputs bar     


Nếu tôi đang cố gắng khởi tạo trong một số lớp khác, nó sẽ cho java.lang.ExceptionInInitializerError và tôi đang sử dụng var thay vì val
Sudarshan

4
Các cuộc gọi phương thức cần phải có INSTANCEtừ khóa, như thế này:Foo.INSTANCE.sayFoo()
Raeglan

Tôi nghĩ rằng giải pháp này là cách ưa thích nếu bạn muốn static CLASSkhông chỉ static methdos. Bởi vì với các đối tượng đồng hành, bạn vẫn có thể khởi tạo lớp cha.
Fabriciorissetto

valkhông tĩnh, nó tương đương với static finalJava
Farid

23

Sử dụng đối tượng để biểu diễn val / var / phương thức để tạo tĩnh. Bạn có thể sử dụng đối tượng thay vì lớp singleton. Bạn có thể sử dụng đồng hành nếu bạn muốn tạo tĩnh trong một lớp

object Abc{
     fun sum(a: Int, b: Int): Int = a + b
    }

Nếu bạn cần gọi nó từ Java:

int z = Abc.INSTANCE.sum(x,y);

Trong Kotlin, bỏ qua NGAY LẬP TỨC.


11

Điều này cũng làm việc cho tôi

object Bell {
    @JvmStatic
    fun ring() { }
}

từ Kotlin

Bell.ring()

từ Java

Bell.ring()

8
object objectName {
    fun funName() {

    }
}

5
Mặc dù đoạn mã này có thể là giải pháp, bao gồm một lời giải thích thực sự giúp cải thiện chất lượng bài đăng của bạn. Hãy nhớ rằng bạn đang trả lời câu hỏi cho độc giả trong tương lai và những người đó có thể không biết lý do cho đề xuất mã của bạn.
Narendra Jadhav

5

Bạn cần truyền đối tượng đồng hành cho phương thức tĩnh vì kotlin không có từ khóa tĩnh - Thành viên của đối tượng đồng hành có thể được gọi bằng cách sử dụng tên lớp đơn giản làm vòng loại:

package xxx
    class ClassName {
              companion object {
                       fun helloWord(str: String): String {
                            return stringValue
                      }
              }
    }

4

Có 2 cách bạn có thể áp dụng tĩnh trong Kotlin

Đầu tiên tạo một đối tượng đồng hành dưới lớp

Ví dụ:

class Test{
    companion object{
          fun isCheck(a:Int):Boolean{
             if(a==0) true else false
          }
     }
}

bạn có thể gọi chức năng này là

Test.Companion.isCheck(2)

Một cách khác mà chúng ta có thể sử dụng là tạo một lớp đối tượng

object Test{
       fun isCheck(a:Int):Boolean{
            if(a==0) true else false
       }
}

Chúc mừng mã hóa!


Đối với lần sử dụng đầu tiên (ví dụ Test.Companion.isCheck(2)) IDE hiển thị các cảnh báo và nói Companion reference is redundant. Nó có thể được giảm xuống Test.isCheck(2)và dạng rút gọn gần với java hơn.
VSB

3

Kotlin không có bất kỳ từ khóa tĩnh nào. Bạn đã sử dụng nó cho java

 class AppHelper {
        public static int getAge() {
            return 30;
        }
    }

và cho Kotlin

class AppHelper {
        companion object {
            fun getAge() : Int = 30
        }
    }

Gọi cho Java

AppHelper.getAge();

Gọi cho Kotlin

AppHelper.Companion.getAge();

Tôi nghĩ rằng nó hoạt động hoàn hảo.


3

Tôi muốn thêm một cái gì đó vào câu trả lời ở trên.

Có, bạn có thể định nghĩa các hàm trong các tệp mã nguồn (bên ngoài lớp). Nhưng sẽ tốt hơn nếu bạn xác định các hàm tĩnh bên trong lớp bằng cách sử dụng Đối tượng đồng hành vì bạn có thể thêm nhiều hàm tĩnh hơn bằng cách tận dụng Tiện ích mở rộng Kotlin .

class MyClass {
    companion object { 
        //define static functions here
    } 
}

//Adding new static function
fun MyClass.Companion.newStaticFunction() {
    // ...
}

Và bạn có thể gọi hàm được xác định ở trên vì bạn sẽ gọi bất kỳ hàm nào bên trong Đối tượng đồng hành.


3

Mặc dù hiện tại đã hơn 2 tuổi và có rất nhiều câu trả lời hay, tôi vẫn thấy một số cách khác để có được các trường Kotlin "tĩnh". Dưới đây là một hướng dẫn ví dụ cho staticinterop Kotlin-Java :

Kịch bản 1: Tạo một phương thức tĩnh trong Kotlin cho 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
    }
}

Java

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);
    }
}

Câu trả lời của Michael Anderson cung cấp nhiều chiều sâu hơn điều này, và chắc chắn nên được tham khảo cho kịch bản này.


Kịch bản tiếp theo này xử lý việc tạo các trường tĩnh trong Kotlin để Java không phải tiếp tục gọi KotlinClass.foo()cho những trường hợp mà bạn không muốn có hàm tĩnh.

Kịch bản 2: Tạo một biến tĩnh trong Kotlin cho 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
    }
}

Java

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);
    }
}

Một trong những tính năng tuyệt vời về Kotlin là bạn có thể tạo các hàm và biến cấp cao nhất. Điều này làm cho nó tuyệt vời để tạo danh sách "không có lớp" của các trường và hàm không đổi, lần lượt có thể được sử dụng làm statichàm / trường trong Java.

Kịch bản 3: Truy cập các trường và hàm cấp cao nhất trong Kotlin từ 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!")
}

Java

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);
    }
}

Một đề cập đáng chú ý khác có thể được sử dụng trong Java là các trường "tĩnh" là objectcác lớp Kotlin . Đây là các lớp singleton tham số 0 được khởi tạo một cách lười biếng khi sử dụng lần đầu tiên. Thông tin thêm về họ có thể được tìm thấy ở đây: https://kotlinlang.org/docs/reference/object-declarations.html#object-declarations

Tuy nhiên, để truy cập singleton, một INSTANCEđối tượng đặc biệt được tạo ra, điều này cũng khó xử lý như vậy Companion. Đây là cách sử dụng các chú thích để mang lại staticcảm giác rõ ràng trong Java:

Kịch bản 4: Sử dụng objectcác lớp

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'?"
}

Java

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);
    }
}

3

Để rút ngắn, bạn có thể sử dụng "đối tượng đồng hành" để vào thế giới tĩnh của Kotlin như:

  companion object {
    const val TAG = "tHomeFragment"
    fun newInstance() = HomeFragment()
}

và để tạo một trường không đổi sử dụng "const val" như trong mã. nhưng cố gắng tránh các lớp tĩnh vì nó đang gây khó khăn khi kiểm tra đơn vị bằng Mockito!.


3

Việc chuyển đổi chính xác phương thức tĩnh java thành tương đương kotlin sẽ như thế này. ví dụ Ở đây, lớp produc có một phương thức tĩnh tương đương trong cả java và kotlin. Việc sử dụng @JvmStatic rất quan trọng.

Mã Java:

    class Util{
         public static String capitalize(String text){
         return text.toUpperCase();}
       }

Mã Kotlin:

    class Util {
        companion object {
            @JvmStatic
            fun capitalize(text:String): String {
                return text.toUpperCase()
            }
        }
    }

2

Đơn giản là bạn cần tạo một đối tượng đồng hành và đặt hàm vào đó

  class UtilClass {
        companion object {
  //        @JvmStatic
            fun repeatIt5Times(str: String): String = str.repeat(5)
        }
    }

Để gọi phương thức từ một lớp kotlin:

class KotlinClass{
  fun main(args : Array<String>) { 
    UtilClass.repeatIt5Times("Hello")
  }
}

hoặc sử dụng nhập khẩu

import Packagename.UtilClass.Companion.repeatIt5Times
class KotlinClass{
  fun main(args : Array<String>) { 
     repeatIt5Times("Hello")
  }
}

Để gọi phương thức từ một lớp java:

 class JavaClass{
    public static void main(String [] args){
       UtilClass.Companion.repeatIt5Times("Hello");
    }
 }

hoặc bằng cách thêm chú thích @JvmStatic vào phương thức

class JavaClass{
   public static void main(String [] args){
     UtilClass.repeatIt5Times("Hello")
   }
}

hoặc cả hai bằng cách thêm chú thích @JvmStatic vào phương thức và thực hiện nhập tĩnh trong java

import static Packagename.UtilClass.repeatIt5Times
class JavaClass{
   public static void main(String [] args){
     repeatIt5Times("Hello")
   }
}

2

Đối với Java:

public class Constants {
public static final long MAX_CLICK_INTERVAL = 1000;}

Mã Kotlin tương đương:

object  Constants {
const val MAX_CLICK_INTERVAL: Long = 1000}

Vì vậy, đối với các phương thức tĩnh Java tương đương là lớp đối tượng trong Kotlin.


2

Đối với Android, sử dụng một chuỗi từ một hoạt động cho đến tất cả các hoạt động cần thiết. Giống như tĩnh trong java

public final static String TEA_NAME = "TEA_NAME";

Cách tiếp cận tương đương trong 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)
    }
}

Một hoạt động khác cần giá trị:

val teaName = MainActivity.TEA_NAME

2

ngoại trừ câu trả lời của Michael Anderson, tôi có mã hóa theo hai cách khác trong dự án của mình.

Đầu tiên:

bạn có thể trắng tất cả các biến cho một lớp. đã tạo một tệp kotlin có tên Const

object Const {
    const val FIRST_NAME_1 = "just"
    const val LAST_NAME_1 = "YuMu"
}

Bạn có thể sử dụng nó trong mã kotlin và java

 Log.d("stackoverflow", Const.FIRST_NAME_1)

Thứ hai:

Bạn có thể sử dụng chức năng mở rộng của Kotlin đã
tạo một tệp kotlin có tên Ext , bên dưới mã là tất cả mã trong tệp Ext

package pro.just.yumu

/**
 * Created by lpf on 2020-03-18.
 */

const val FIRST_NAME = "just"
const val LAST_NAME = "YuMu"

Bạn có thể sử dụng nó trong mã kotlin

 Log.d("stackoverflow", FIRST_NAME)

Bạn có thể sử dụng nó trong mã java

 Log.d("stackoverflow", ExtKt.FIRST_NAME);

1

Viết chúng trực tiếp vào tập tin.

Trong Java (xấu xí):

package xxx;
class XxxUtils {
  public static final Yyy xxx(Xxx xxx) { return xxx.xxx(); }
}

Trong Kotlin:

@file:JvmName("XxxUtils")
package xxx
fun xxx(xxx: Xxx): Yyy = xxx.xxx()

Hai đoạn mã đó được cân bằng sau khi biên dịch (ngay cả tên tệp đã biên dịch, file:JvmNameđược sử dụng để kiểm soát tên tệp đã biên dịch, phải được đặt ngay trước khi khai báo tên gói).


7
Bạn đã quên "Kotlin (xấu xí)" ... KOTLINE: đối tượng đồng hành {val handler = object: Handler (Looper.getMainLooper ()) {] ..... JAVA: Handler tĩnh handler = new Handler (Looper.getMainLooper () ) {};
CmosBattery

1

Sử dụng @JVMStaticchú thích

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)
                }
            }
}

1

Hãy để bạn có một sinh viên lớp . Và bạn có một phương thức tĩnh getUniversityName () và một trường tĩnh được gọi là TotalStudent .

Bạn nên khai báo khối đối tượng đồng hành bên trong lớp của bạn.

companion object {
 // define static method & field here.
}

Sau đó, lớp của bạn trông giống như

    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
    }
}

Sau đó, bạn có thể sử dụng các phương thức tĩnh và các trường như thế này.

println("University : " + Student.getUniversityName() + ", Total Student: " + Student.totalStudent)
    // Output:
    // University : MBSTU, Total Student: 30

1

Không có từ khóa tĩnh trong kotlin. tài liệu kotlin khuyên bạn nên sử dụng các hàm cấp gói nếu bạn muốn theo DRY. Tạo một tệp có đuôi .kt và đặt phương thức của bạn vào đó.

package p
    fun m(){
    //fun body
    }

sau khi biên dịch m sẽ có một chữ ký của khoảng trống tĩnh cuối cùng

import p.m


0

Bạn có thể đạt được chức năng tĩnh trong Kotlin bằng Đối tượng đồng hành

  • Thêm đồng hành vào khai báo đối tượng cho phép thêm chức năng tĩnh vào đối tượng mặc dù khái niệm tĩnh thực tế không tồn tại trong Kotlin.
  • Một đối tượng đồng hành cũng có thể truy cập tất cả các thành viên của lớp, bao gồm cả các hàm tạo riêng.
  • Một đối tượng đồng hành được khởi tạo khi lớp được khởi tạo.
  • Một đối tượng đồng hành không thể được khai báo bên ngoài lớp.

    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"
            }
    
        }
    }

Các thành viên của đối tượng đồng hành có thể được gọi bằng cách sử dụng tên lớp đơn giản là vòng loại:

Đầu ra:

MyClass.staticField // This is an example of static field Object Decleration

MyClass.getStaticFunction() : // This is an example of static function for Object Decleration

0

Tất cả thành viên tĩnh và chức năng phải nằm trong khối đồng hành

  companion object {
    @JvmStatic
    fun main(args: Array<String>) {
    }

    fun staticMethod() {
    }
  }

0

Rất nhiều người đề cập đến các đối tượng đồng hành, đó là chính xác. Nhưng, chỉ để bạn biết, bạn cũng có thể sử dụng bất kỳ loại đối tượng nào (sử dụng từ khóa đối tượng, không phải lớp), vd

object StringUtils {
    fun toUpper(s: String) : String { ... }
}

Sử dụng nó giống như bất kỳ phương thức tĩnh nào trong java:

StringUtils.toUpper("foobar")

Kiểu mẫu đó là vô dụng trong Kotlin, một trong những điểm mạnh của nó là nó thoát khỏi sự cần thiết của các lớp chứa đầy các phương thức tĩnh. Thay vào đó, thích hợp hơn để sử dụng các chức năng toàn cầu, mở rộng và / hoặc cục bộ, tùy thuộc vào trường hợp sử dụng của bạn. Nơi tôi làm việc, chúng tôi thường định nghĩa các hàm mở rộng toàn cầu trong một tệp phẳng, riêng biệt với quy ước đặt tên: [className] Extended.kt tức là FooExtensions.kt. Nhưng thông thường hơn, chúng ta viết các hàm trong đó chúng cần thiết bên trong lớp hoặc đối tượng vận hành của chúng.


0

Trong Java, chúng ta có thể viết theo cách dưới đây

class MyClass {
  public static int myMethod() { 
  return 1;
  }
}

Trong Kotlin, chúng ta có thể viết theo cách dưới đây

class MyClass {
  companion object {
     fun myMethod() : Int = 1
  }
}

một người bạn đồng hành được sử dụng như tĩnh trong Kotlin.


0

Nhà cung cấp tài liệu kotlin có ba cách để làm điều đó, đầu tiên là định nghĩa hàm trong gói, không có lớp:

package com.example

fun f() = 1

thứ hai là sử dụng chú thích @JvmStatic:

package com.example

class A{
@JvmStatic
fun f() = 1
}

và thứ ba là sử dụng đối tượng đồng hành:

package com.example

clss A{
companion object{
fun f() = 1
}
}

-1

Nếu bạn cần một hàm hoặc một thuộc tính được gắn với một lớp chứ không phải là các thể hiện của nó, bạn có thể khai báo nó bên trong một đối tượng đồng hành:

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
        }
    }
}

Đối tượng đồng hành là một singleton và các thành viên của nó có thể được truy cập trực tiếp thông qua tên của lớp chứa

val car = Car.makeCar(150)
println(Car.Factory.cars.size)

Có vẻ như câu trả lời được chấp nhận đã mô tả các đối tượng đồng hành. Vì vậy, rất nhiều câu trả lời khác. Câu trả lời của bạn có cung cấp điều gì mới không?
Sneftel

để làm rõ thêm, bạn có thể kiểm tra nó ở đây kotlinlang.org/docs/tutorials/kotlin-for-py/ mẹo
asad mahmood

-2

Bạn có thể sử dụng Đối tượng đồng hành - kotlinlang

Nó có thể được hiển thị bằng cách tạo Giao diện đầu tiên

interface I<T> {

}

Sau đó, chúng ta phải tạo một chức năng bên trong giao diện đó:

fun SomeFunc(): T

Sau đó, chúng tôi cần một lớp học:

class SomeClass {}

bên trong lớp đó, chúng ta cần một đối tượng đồng hành bên trong lớp đó:

companion object : I<SomeClass> {}

bên trong Đối tượng đồng hành đó, chúng ta cần SomeFuncchức năng cũ đó , nhưng chúng ta cần vượt qua nó:

override fun SomeFunc(): SomeClass = SomeClass()

Cuối cùng, bên dưới tất cả các công việc đó, Chúng tôi cần một cái gì đó để cung cấp năng lượng cho hàm Tĩnh đó, Chúng tôi cần một biến:

var e:I<SomeClass> = SomeClass()
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.