Ben Edwards
09/16/2022, 8:53 AMprivate const val TAG = "BaseActivity"
Which can put just after the imports. Its not defined within a class which seems inconsistent with private being '`private` means that the member is visible inside this class only (including all its members).'. Does it effectively become private to all classes in the file? To go further down the rabbit hole what does 'including all its members' mean? I guess it means function/methods but if so why not just say this?Youssef Shoaib [MOD]
09/16/2022, 9:01 AMJoffrey
09/16/2022, 9:03 AMinternal
is a visibility modifier that forbids access from other modules. The declaration can only be accessed by the files that are compiled at the same time as the file declaring the internal
declarationIts not defined within a class which seems inconsistent with private being '`private` means that the member is visible inside this class only (including all its members).'. Does it effectively become private to all classes in the file?
private
at the top-level means private in the file. The declaration can be used anywhere in the file (including inside classes declared in that file), but not outside the file.
Technically talking about a class is not wrong, because top-level declarations in Kotlin are actually compiled as if they were part of a class. If you have a file called MyFile.kt
, Kotlin will generate a class called MyFileKt
to hold all the top-level declarations from that file. That said, private
at the top level doesn't mean private in that generated class, because other classes in the same file can use those top-level declarations.To go further down the rabbit hole what does 'including all its members' mean? I guess it means function/methods but if so why not just say this?"member" is a specific term that refers to many things a class can hold. It's just the correct vocabulary to use, and it would be quite verbose to cite them all every time. See https://kotlinlang.org/docs/classes.html#class-members In this specific instance, it means that a private thing in a class can still be visible to the body of the classe's methods and constructors, to property initializers, to
init
blocks, and can also be accessed in nested classes and objects, etc.Ben Edwards
09/16/2022, 9:13 AMJoffrey
09/16/2022, 9:17 AMCan other classes inside the file that have instances of the class with the private member access that member?Nope. Private visibility on a declaration at the top-level in a file means that everything else in the file can see it, but private visibility on a class member means that only other members in the same class can see it. Holding an instance of that class from anywhere outside the class only gives you access to the API of the class that have sufficient visibility (internal, public, protected depending on where you are). I hope that makes it clearer. EDIT: here is a quick rule of thumb: if you see
private
, it means the declaration is visible only to things that are in the enclosing block { ... }
and everything nested in it. If there is no enclosing block, consider the whole file. (Note that I haven't thought this rule through, so maybe there are exceptions, but I find it quite neat to help grasp the idea quickly)Ben Edwards
09/16/2022, 9:21 AMJoffrey
09/16/2022, 9:33 AMSo is a module everything in the project (I guess IntelliJ is the same) unless you specifically create multiple modulesI haven't done Android dev in a very long time, but AFAIK now you have a sort of a top-level Gradle module, and then a nested
app
module. But yeah pretty much everything you'll be interested in will be in that single app module, unless you create other modules yourself.
Trying to get my head around when I should use internal, and I guess why? Maybe in my relatively early stage in my learning, I should park this oneEverything
internal
in your app module will indeed be visible in the whole module anyway, so yeah internal
isn't useful when developing in a single-module project.
Creating more modules is often useful for libraries that want to publish separate "things" that can be used independently (the library is thus "modular"). Even in a single project where you build only one thing, it was also useful in the past to split it into multiple modules to benefit for incremental compilation, but now I believe Kotlin supports incremental compilation within single modules too. Modules can only be useful on their own exactly for the purpose of isolating things visibility-wise, making use of internal (because Kotlin doesn't have package-private visibility).Ben Edwards
09/16/2022, 9:44 AMpackage com.funkytwig.flickerbrowser
import android.util.Log
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.Toolbar
private const val TAG = "BaseActivity"
// internal as don't have to be available outside this project
internal const val FLICKER_QUERY = "FLICKER_QUERY"
internal const val PHOTO_TRANSFUR = "PHOTO_TRANSFUR"
open class BaseActivity : AppCompatActivity() {
internal fun activateToolbar(home: Boolean) {
Log.d(TAG, "activateToolbar")
val toolbar = findViewById<View>(R.id.toolbar) as Toolbar
setSupportActionBar(toolbar)
supportActionBar?.setDisplayHomeAsUpEnabled(true) // Set whether home should be displayed as an "up" affordance.
}
}
I guess there is not a benefit of using internal here (drought the course even covers modules, or if it does will be a long way down the road).
Thanks for being very generous with your time.Joffrey
09/16/2022, 9:53 AMinternal
visibility, but I don't know the tutorial so I'm not sure what path they want their readers to followThanks for being very generous with your timeMy pleasure!