class RedGuy
constructor : (#name) ->
#nameElem = $ #name
#nameElem.css color : red
class WideRedGuy extends RedGuy
constructor : ->
#nameElem.css width : 900
jeff = new WideRedGuy '#jeff'
I would like #jeff to be both red and wide, but I always get this.name is undefined. How can I extend the constructor (append?) so that I have access to the properties of the original object?
You need to explicitly call super for this to work. Calling super in WideRedGuy will call RedGuy's constructor, after which #nameElem will be properly defined. For a more in-depth explanation, you should consult coffeescript's documentation on the matter.
class RedGuy
constructor : (#name) ->
#nameElem = $ #name
#nameElem.css color : red
class WideRedGuy extends RedGuy
constructor : ->
## This line should fix it
super # This is a lot like calling `RedGuy.apply this, arguments`
#nameElem.css width : 900
jeff = new WideRedGuy '#jeff'
Related
guys, I am learning kotlin. From https://kotlinlang.org/docs/interfaces.html#properties-in-interfaces it says:
Properties declared in interfaces can't have backing fields, and
therefore accessors declared in interfaces can't reference them.
(I think the pronoun "them" at the end of quoted sentence should refer to "properties" rather than "fields". )
However the following code works. It seems that we can refer to properties. Why is print(prop) highlighted as red then?
interface MyInterface {
val prop: Int // abstract
val propertyWithImplementation: String
get() = "foo"
fun foo() {
print(prop) // this is highlighted red but it works. what's does the author want to say?
}
}
class Child : MyInterface {
override val prop: Int = 29
}
fun main() {
val c = Child()
c.foo()
}
Besides, I noticed that in the above example foo is not accessor. So I tried following example and it works too:
interface User {
val email: String
val nickname: String
get() = email.substringBefore('#') // aren't we referring to a property in accessor? why does this work then?
}
So what does the author want to say in here? what does "them" refer to?
"Them" in this sentence means "fields".
Property is basically a getter (setter) and it could be optionally backed by a field. For technical reasons interfaces can't hold fields, so properties in interfaces have to be "fieldless". Property has to be either abstract or its implementation can only use e.g. other properties/functions, but it can't store/read any data directly. Note that referencing other properties does not break above rule, because, as I said, property is mainly a getter/setter, not a field.
print(prop) is highlighted as red, because... well, this is how automatic highlighter colored it... :-)
Is there any way to create an instance of Derived but not call the constructor of Base?
open class Base(p: Int)
class Derived(p: Int) : Base(p)
You actually can do it
import sun.misc.Unsafe
open class Base(p: Int){
init {
println("Base")
}
}
class Derived(p: Int) : Base(p){
init {
println("Derived")
}
}
fun main() {
val unsafe = Unsafe::class.java.getDeclaredField("theUnsafe").apply {
isAccessible = true
}.get(null) as Unsafe
val x = unsafe.allocateInstance(Derived::class.java)
println("X = $x")
}
But don't, this solution is a low-level mechanism that was designed to be used only by the core Java library and not by standard users. You will break the logic of OOP if you use it.
this is not possible. The constructor of the derived class has to call (any) constructor of the base class in order to initialise the content(fields) of the base class.
This is also the same case in Java. Just that the default constructor is called by default (if no parameters are provided in the constructor), but if you have to choose between constructors with parameters, you always have to call them explicitly, because you have to choose which values to pass into the constructor.
You must always call a constructor of a super-class to ensure that the foundation of the class is initialized. But you can work around your issue by providing a no-arg constructor in the base class. Something like this:
open class Base(p: Int?){
val p: Int? = p
constructor(): this(null)
}
class Derived(p: Int) : Base()
The way you handle which constructor of the base class is default and which parameters are nullable, etc. will depend highly on the specific case.
Sealed class in Kotlin can have private constructor only. That means we can call the constructor only in itself:
Sealed classes are not allowed to have non-private constructors (their constructors are private by default).
// `private` and `constructor()` are redundant.
sealed class Expr private constructor()
But, when we utilize sealed class, a sub class have to inherit seald class:
// Above Kotlin 1.1
data class Const(val number: Double) : Expr()
data class Sum(val e1: Expr, val e2: Expr) : Expr()
As you can see the code above, sealed class's private constructor is called outside of sealed class itself. When sub class is instantiated, the constructor of parent(sealed class) will be called before sub class's own constructor is called. Is it just exception to visibility modifiers?
https://kotlinlang.org/docs/reference/visibility-modifiers.html#classes-and-interfaces
For members declared inside a class: private means visible inside this class only (including all its members);
Consider the following code:
open class A private constructor(var name: String){
class B : A("B")
class C : A("C")
}
The above code compiles fine, as the constructor is called inside the class A.
If a class D tries to inherit outside A, it won't compile.
class D : A("D") // Error: Cannot access '<init>': it is private in 'A'
As mentioned on the page Sealed class in Kotlin,
A sealed class can have subclasses, but all of them must be declared in the same file as the sealed class itself. (Before Kotlin 1.1, the rules were even more strict: classes had to be nested inside the declaration of the sealed class).
It seems that kotlin relaxed the requirement of nested classes only.
So, the following code works fine in 1.1+ but would fail in earlier versions:
sealed class A(var name: String)
class B : A("B")
class C : A("C")
whereas the following code would have been required in versions before 1.1, which respects the private constructor.
sealed class A (var name: String){
class B : A("B")
class C : A("C")
}
So, allowing private constructors of sealed classes outside the class (but within the same file) can be considered an enhancement to make the code cleaner.
You can figure out what's happening by taking a look at the generated bytecode (you can do this by going to Tools -> Kotlin -> Show Kotlin Bytecode and then choosing Decompile in the pane that appears.). Decompiling it to Java shows this code for the Expr class:
public abstract class Expr {
private Expr() {
}
// $FF: synthetic method
public Expr(DefaultConstructorMarker $constructor_marker) {
this();
}
}
So there is a non-private constructor for the Expr class generated, with a special parameter. Then, as you'd expect, if you look at the decompiled bytecode of Const for example, you'll see that it calls into this constructor:
public final class Const extends Expr {
public Const(double number) {
super((DefaultConstructorMarker)null);
this.number = number;
}
// other fields and methods ...
}
You still can't subclass Expr from Kotlin, because the Kotlin compiler knows that it's a sealed class from the metadata in the file, and will respect that.
As for Java client code, there you can't access this same constructor yourself because the DefaultConstructorMarker is package-private in the kotlin.jvm.internal package that it's in, so even if you write out the import statement for it manually, the compiler won't allow it.
My guess is that the package-private visibility might only be enforced at compile time, and that's why the Kotlin compiler is able to output the bytecode corresponding to the snippet above (not completely sure though).
I came across the following Kotlin code for an enum:
enum class Section(val position: Int, val textKey: Int, val fragment: Fragment) {
GUIDE(0, R.string.main_pager_guide, QotGuideFragment()),
LEARN(1, R.string.main_pager_learn, QotLearnFragment()),
ME(2, R.string.main_pager_me, QotToBeVisionFragment()),
PREPARE(3, R.string.main_pager_prepare, QotPrepareFragment()),
;
}
However, when I review the Kotlin docs on enums, I don't see anything in it that shows this kind of syntax. The line:
GUIDE(0, R.string.main_pager_guide, QotGuideFragment())
I don't understand how these 3 parameters are used. Also, the enum class Section shows 3 constructor parameters that don't appear to be used.
The official docs on enum are at:
https://kotlinlang.org/docs/reference/enum-classes.html
From https://kotlinlang.org/docs/reference/enum-classes.html:
Each enum constant is an object
so GUIDE is an instance of Section class, meaning an object initialized as
GUIDE(0, R.string.main_pager_guide, QotGuideFragment())
You can get the values that initialized GUIDE, like this:
val guidePosition = Section.GUIDE.position
val guideTextKey = Section.GUIDE.textKey
val guideFragment = Section.GUIDE.fragment
usually your enums will be like that
enum class Section() {
GUIDE,
LEARN,
ME,
PREPARE
}
without any parameters
but in your example the base constructor of the enum has parameters that are set as properties also
enum class Section(**val** position: Int, **val** textKey: Int, **val** fragment: Fragment)
with the keyword val in the constructor you set as property of the class
then it has
GUIDE(0, R.string.main_pager_guide, QotGuideFragment()),
LEARN(1, R.string.main_pager_learn, QotLearnFragment()),
ME(2, R.string.main_pager_me, QotToBeVisionFragment()),
PREPARE(3, R.string.main_pager_prepare, QotPrepareFragment())
so for GUIDE 0 -> position, R.string.main_pager_guide -> textKey and QotGuideFragment -> fragment
The Kotlin documentation says that
All classes in Kotlin have a common superclass Any, that is a default super for a class with no supertypes declared
If I try and explicitly inherit from Any:
class MyClass : Any {
}
The compiler gives an error:
Kotlin: This type has a constructor, and thus must be initialized here
I haven't been able to find the documentation for the Any class. Is it possible to explicitly inherit from Any, and if so, what do you pass it?
You have to call the constructor explicitly:
class MyClass : Any()
THe constructor of Any has no parameters, thus to call it you simply provide the empty parentheses
In case we are extending a class,we need to add brackets(for implicit constructor)
class MyClass : Any()
This is similar to calling
class MyClass extends Any
{
MyClass()
{
super();
}
}
But if we are implementing an interface(interface do not have constructors),syntax should be the following
class MyClass : BaseInterface
In case when you have secondary constructor (key word constructor) you can use the next syntax
class MyClass : Any {
constructor() : super()
}
If the class has no primary constructor, then each secondary constructor has to initialize the base type using the super keyword, or to delegate to another constructor which does that.
Read more here - https://kotlinlang.org/docs/reference/classes.html
P.S. your problem could be solved easily using Android Studio feature - Project quick fix (show intention actions and quick fixes) Win - Alt + Enter, Mac - Option + Enter