Kotlin this in inner class

Ключевое слово this в Kotlin

В Kotlin ключевое слово this позволяет нам ссылаться на экземпляр класса, функцию которого мы запускаем. Кроме того, есть и другие способы использования выражения this.

Доступ к членам класса с помощью this

Мы можем использовать this как префикс для ссылки на свойства или вызовы функций:

Используя this в Котлин в качестве префикса, мы можем ссылаться на свойства класса. Мы можем использовать это для устранения неоднозначности с локальными переменными с похожими именами.

Мы также можем вызывать функции-члены, используя this.

Доступ к экземпляру класса

Ключевое слово this можно использовать автономно для представления экземпляра объекта:

class Foo < var count = 0 fun incrementCount() < incrementFoo(this) >> private fun incrementFoo(foo: Foo) < foo.count += 2 >fun main() < val foo = Foo() foo.incrementCount() println("Final count = $") >

Здесь this представляет экземпляр самого класса. Например, мы можем передать экземпляр окружающего класса в качестве параметра для вызова функции.

Кроме того, мы можем присвоить экземпляр локальным переменным, используя этот файл.

Делегирование от вторичных конструкторов

В Kotlin вторичные конструкторы должны делегировать полномочия первичному конструктору. Мы можем делегировать с помощью this:

class Car(val id: String, val type: String)

Вторичный конструктор Car делегирует полномочия первичному конструктору. На самом деле мы можем определить любое количество дополнительных конструкторов в теле класса.

Однако все вторичные конструкторы должны делегировать полномочия первичному конструктору или другому вторичному конструктору, используя this.

Внешние экземпляры с квалифицированным this

При автономном использовании this относится к самой внутренней охватывающей области. Но что, если мы хотим получить доступ к экземпляру за пределами этой области? Мы можем сделать это, уточнив this:

Здесь this относится к экземпляру внутреннего класса. Однако, чтобы сослаться на экземпляр внешнего класса, мы уточняем его с помощью [email protected]. Точно так же мы можем обращаться к внешнему экземпляру из внутренних функций расширения или функциональных литералов с приемниками.

Средняя оценка 1 / 5. Количество голосов: 1

Спасибо, помогите другим — напишите комментарий, добавьте информации к статье.

Видим, что вы не нашли ответ на свой вопрос.

Напишите комментарий, что можно добавить к статье, какой информации не хватает.

Источник

Ключевое слово this

Чтобы сослаться на объект, с которым вы работаете, используется ключевое слово this :

  • Внутри класса ключевое слово this ссылается на объект этого класса;
  • В функциях-расширениях или в литерале функции с объектом-приёмником this обозначает объект-приёмник, который передаётся слева от точки.

Если ключевое слово this не имеет определителей, то оно ссылается на область самого глубокого замыкания. Чтобы сослаться на this в одной из внешних областей, используются метки-определители.

this с определителем

Чтобы получить доступ к this из внешней области (класса, функции-расширения или именованных литералов функций с объектом-приёмником), используйте this@label , где @label — это метка области, из которой нужно получить this .

class A < // неявная метка @A inner class B < // неявная метка @B fun Int.foo() < // неявная метка @foo val a = this@A // this из A val b = this@B // this из B val c = this // объект-приёмник функции foo(), типа Int val c1 = this@foo // объект-приёмник функции foo(), типа Int val funLit = lambda@ fun String.() < val d = this // объект-приёмник литерала funLit >val funLit2 = < s: String ->// объект-приёмник функции foo(), т.к. замыкание лямбды не имеет объекта-приёмника val d1 = this > > > > 

Подразумеваемое this

Когда вы вызываете функцию-член для this , вы можете пропустить this часть. Если у вас есть функция, не являющаяся членом, с тем же именем, используйте ее с осторожностью, потому что в некоторых случаях может быть вызвана она.

fun printLine() < println("Функция верхнего уровня") >class A < fun printLine() < println("Функция-член") >fun invokePrintLine(omitThis: Boolean = false) < if (omitThis) printLine() else this.printLine() >> A().invokePrintLine() // Функция-член A().invokePrintLine(omitThis = true) // Функция верхнего уровня 

© 2015—2023 Open Source Community

Читайте также:  Стиль css классы стилей

Источник

Вложенные и внутренние классы

Вы также можете использовать интерфейсы с вложенностью. Возможны любые комбинации классов и интерфейсов: вы можете вкладывать интерфейсы в классы, классы в интерфейсы и интерфейсы в интерфейсы.

interface OuterInterface < class InnerClass interface InnerInterface >class OuterClass

Внутренние классы

Класс, отмеченный как внутренний с помощью слова inner , может иметь доступ к членам внешнего класса. Внутренние классы содержат ссылку на объект внешнего класса.

class Outer < private val bar: Int = 1 inner class Inner < fun foo() = bar >> val demo = Outer().Inner().foo() // == 1 

Подробнее об использовании this во внутренних классах: Qualified this expressions.

Анонимные внутренние классы

Экземпляры анонимного внутреннего класса создаются с помощью объектов-выражений.

window.addMouseListener(object : MouseAdapter() < override fun mouseClicked(e: MouseEvent) < . >override fun mouseEntered(e: MouseEvent) < . >>) 

On the JVM, if the object is an instance of a functional Java interface (that means a Java interface with a single > abstract method), you can create it using a lambda expression prefixed with the type of the interface: > >«`kotlin > val listener = ActionListener < println("clicked") >> «` —>

В JVM если объект является экземпляром функционального Java-интерфейса (т.е. Java-интерфейса с единственным абстрактным методом), вы можете создать его с помощью лямбда-выражения с префиксом — типом интерфейса.

val listener = ActionListener

Источник

Kotlin this in inner class

В Kotlin классы и интерфейсы могут быть определены в других классах и интерфейсах. Такие классы (вложенные классы или nested classes ) обычно выполняют какую-то вспомогательную роль, а определение их внутри класса или интерфейса позволяет разместить их как можно ближе к тому месту, где они непосредственно используются.

Например, в следующем случае определяется вложенный класс:

В данном случае класс Account является вложенным, а класс Person< - внешним.

По умолчанию вложенные классы имеют модификатор видимости public, то есть они видимы в любой части программы. Но для обращения к вложенному классу надо использовать имя внешнего класса. Например, создание объекта вложенного класса:

Если необходимо ограничить область применения вложенного класса только внешним классом, то следует определить вложенный класс с модификатором private:

class Person(username: String, password: String) < private val account: Account = Account(username, password) private class Account(val username: String, val password: String) fun showAccountDetails()< println("UserName: $Password: $account.password") > > fun main()

Классы также могут содержать вложенные интерфейсы. Кроме того, интерфейсы тоже могут содержать вложенные классы и интерфейсы:

interface SomeInterface < class NestedClass interface NestedInterface >class SomeClass

Внутренние (inner) классы

Стоит учитывать, что вложенный (nested) класс по умолчанию не имеет доступа к свойствам и функциям внешнего класса. Например, в следующем случае при попытке обратиться к свойству внешнего класса мы получим ошибку:

class BankAccount(private var sum: Int) < fun display()< println("sum = $sum") >class Transaction < fun pay(s: Int)< sum -= s display() >> >

В данном случае у нас определен класс банковского счета BankAccount, который определяет свойство sum — сумма на счете и функцию display() для вывода информации о счете.

Читайте также:  Javascript print all elements

Кроме того, в классе BankAccount определен вложенный класс Transaction, который представляет операцию по счету. В данном случае класс Transaction определяет функцию pay() для оплаты со счета. Однако в нем мы не можем обратиться в свойствам и функциям внешнего класса BankAccount.

Чтобы вложенный класс мог иметь доступ к свойствам и функциям внешнего класса, необходимо определить вложенный класс с ключевым словом inner . Такой класс еще называют внутренним классом (inner class), чтобы отличать от обычных вложенных классов. Например:

fun main() < val acc = BankAccount(3400); acc.Transaction().pay(2500) >class BankAccount(private var sum: Int) < fun display()< println("sum = $sum") >inner class Transaction < fun pay(s: Int)< sum -= s display() >> >

Теперь класс Transaction определен с ключевым словом inner, поэтому имеет полный доступ к свойствам и функциям внешнего класса BankAccount. Но теперь если мы хотим использовать объект подобного вложенного класса, то необходимо создать объект внешнего класса:

val acc = BankAccount(3400); acc.Transaction().pay(2500)

Совпадение имен

Но что если свойства и функции внутреннего класса называются также, как и свойства и функции внешнего класса? В этом случае внутренний класс может обратиться к свойствам и функциям внешнего через конструкцию this@название_класса.имя_свойства_или_функции :

Например, перепишем случай выше с классами Account и Transaction следующим образом:

fun main() < val acc = BankAccount(3400); acc.Transaction(2400).pay() >class BankAccount(private var sum: Int) < fun display()< println("sum = $sum") >inner class Transaction(private var sum: Int) < fun pay()< this@BankAccount.sum -= this@Transaction.sum display() >> >

Источник

Kotlin this

Kotlin this

In this article, we will discuss Kotlin this expression with a few examples to make it simpler and easier to understand.

2. Kotlin this in class

In short, this keyword points to the current scope.

Consider we have a Student class that has the name and department instance variables. It also has a print method to print the name value.

Now let’s create an instance temp for the Student class inside the main function. Then invoke the print function using the instance.

Here, this expression inside the print function points to the enclosing instance or object temp . You can access your current scope variables using this keyword inside the class.

class Student(private var name: String, private var department: String) < fun resetStudent(name:String, department: String) < this.name = name this.department = department >fun print() < println(name) >> fun main()

The this keyword helps to eliminate the confusion between class variables and parameters with the same name. The parameters of the methods or constructors of a class can have the same name as one of the class’s fields. In this case, we say the parameter shadows the field, meaning the parameter takes precedence.

In the above code, resetStudent method contains parameters that exactly match the class variables. So, inside the function, any reference to name or department by default points to the parameter scope. For example, name refers to parameter variable name whereas this.name refers to the class instance variable.

However, you can omit this inside the print function as there are no variable conflicts like in resetStudent function.

Читайте также:  Php functions with html forms

2. Kotlin this in Extension function

The this keyword points to the current receiver of the extension function. Extension function allows to add more functionality to the existing classes, without inheriting them or using any design patterns.

We declare the extension function by using a prefix receiver type (class name) followed by a dot and then the name of the extension function. The receiver refers to the class being extended.

Let’s take an extension function example.

fun String.getFileFormat(): String

In the above code, we are adding a new extension function getFileFormat to the String class that can take a file name as input and returns the file format (txt, jpg. ). We can invoke this function from our code on any String object.

Here, the receiver or class type is String. Inside the main function, we have a fileName string variable and we are calling getFileFormat extension function on the fileName string.

Now, this keyword inside the extension function refers to the fileName receiver object (the one passed before the dot).

3. Qualified this in Kotlin

Assume you have an inner class B inside the outer class A like below. Here, we have two scopes: outer class scope and inner class scope. See our article on Kotlin nested and inner class to know about the Kotlin inner class.

Class B has a function foo that prints the square of the value c. Now, c refers to the B’s variable c. What if you want to refer to the A’s variable c. How can you refer to the outer class variables from your inner class scope?

Qualified this (this@label) helps us to achieve it by allowing us to refer to the scope we want. The implicit label for the scope would be the class or function name.

Let’s see the below examples to understand this better.

3.1. Qualified this for class scope

In the below code, we have two classes A and B. A class is the outer scope class with implicit label @A (class name) whereas B class is the inner class scope with implicit label @B.

Inside the foo function, qualified this@A points to the outer class A and this@B points to the inner class B.

3.2. Qualified this for extension function

In the below example, foo is an extension function for the receiver Int . Therefore, the name of the extension function @foo is the implicit label here and this@foo would refer to the receiver object.

4. Implicit this in Kotlin

You can skip when you call a member function on thi s or refer to the innermost scope variables.

In the below code, we have skipped this for the reference name inside the print function as there are no conflicts. It implicitly refers to the current object.

class Student(private var name: String, private var department: String) < fun print() < println(name) >> fun main()

In the below code, we skipped this keyword while referring to the current receiver object. Even without this keyword, the subStringAfterLast implicitly points to the current receiver object and execute on it.

fun String.getFileFormat(): String = substringAfterLast(‘.’, «») fun main(args: Array)

5. Conclusion

In this article, we have discussed the Kotlin this with examples.

Источник

Оцените статью