I have a class User which is a subclass of class PFUser:
class User: PFUser {
var isManager = false
}
In one of my methods I receive a PFUser object and I want to cast it to a User object
func signUpViewController(signUpController: PFSignUpViewController!, didSignUpUser user: PFUser!) {
currentUser = user
}
Is this possible?
This type of casting is a downcast. Given an instance of a certain base class where you know there exist subclasses, you can try to downcast with the typecast operator as:
class Base {}
class Derived : Base {}
let base : Base = Derived()
let derived = base as Derived
Keep in mind though, that a downcast can fail:
class Base {}
class Derived : Base {}
class Other : Base {}
let base : Base = Other()
let derived = base as Derived // fails with a runtime exception
You can try a downcast using the optional form of the type as operator as?.
class Base {}
class Derived : Base {}
class Other : Base {}
let base : Base = Other()
// The idiomatic implementation to perform a downcast:
if let derived = base as? Derived {
println("base IS A Derived")
}
else {
println("base IS NOT A Derived") // <= this will be printed.
}
This can also be done by using the following:
object_setClass(baseClass, derivedClass.self)
However it is worth nothing that this uses the objc-runtime library which can introduce odd crashes if not used correctly.
If it's an instance of PFUser, and not an instance of User stored in a variable of PFUser type, no it's not possible.
You can cast an instance of a class to one of its superclasses, but you cannot do the other way (unless the cast type is the actual instance type).
I suggest to implement an initializer in User, taking a PFUser instance as parameter - if that's possible.
However, although I never attempted to do so, I think inheriting from PFUser you'll just run into troubles, as my understanding is that this class is not designed to be inherited as it is for PFObject. I'd suggest looking into making PFUser a property of User - that way you can just assign as needed.
Related
I want to use Kotlin delegation in a particular context.
The delegate should not be passed in the constructor.
I want to keep a reference to the delegate for later use in the code. From within the method that I override, say printMessage(), I still need to call the delegate the same way you'd call super.printMessage() in polymorphic inheritance.
I can do the first by simply instantiating an anonymous delegate in the by clause (class Derived() : Base by BaseImpl(42) using Kotlin's documentation example). However,
this prevents me from accessing the anonymous delegate, as there is no way that I know to reference it.
I want to do something similar to the following. The following however doesn't compile with error 'this' is not defined in this context.
class Derived() : Base by this.b {
val b: Base = BaseImpl(42)
override fun printMessage() {
b.printMessage()
print("abc")
}
}
I do need a separate delegate for each instance of my Derived class. So moving b as a global variable is not an option for me.
The closest I got to what I need is with an optional parameter to the constructor. This is not a good option neither, as I don't want to allow the construction of my Derived class with arbitrary delegates.
You can do this using a private primary constructor and a public secondary constructor:
class Derived private constructor(val b: Base) : Base by b {
constructor(): this(BaseImpl(42))
override fun printMessage() {
b.printMessage()
print("abc")
}
}
If you don't need a reference to the delegate, you can also say simply,
class Derived : Base by BaseImpl(42)
I already made calculator that can compute with integers and real numbers(i made it with go).
Then I want to make it possible to calculate complex and rational numbers by adding those modules.
(it can also calculate when types are mixed)
It can be easy if I check types of operands every time(runtime) and take care of each case, but I want to solve it with dynamic binding. Guys can you tell me the idea of how to solve this problem
I think by dynamic typing, you're probably referring to how in eg C++ and Java, dynamic binding is essentially having reference to a base class that can point to a derived class (because the derived class "is a" base class).
One might say that the base class defines the interface behind which derived classes morph. If the derived classes replace methods of the base class, a reference to the base class can still access those methods in the derived class.
Base class can define some methods to provide some "base" functionality to its derived classes. If those classes don't redefine the method, the base class's method can be called.
In go, both these concepts exist, but they're quite different.
Go has an explicit interface keyword that defines method signatures but no methods. Any value implicitly satisfies that interface if it has methods of the same name with the same signature.
type LivingBeing interface {
TakeInEnergy()
ExpelWaste()
}
The interface type becomes a valid type in the code. We can pass an interface to a function, and without knowing the type satisfying that interface, can call its methods:
func DoLife(being LivingBeing) {
being.TakeInEnergy()
being.ExpelWaste()
}
This is valid code, but not complete code. Unlike with base classes in other languages, interfaces cannot define functions, only their signatures. It is purely and only an interface definition. We have to define the types that satisfy the interface separately from the interface itself.
type Organism struct{}
func (o *Organism) TakeInEnergy() {}
func (o *Organism) ExpelWaste() {}
We now have a type organism that satisfies LivingBeing. It is something like a base class, but if we wanted to build on it, we can't use subclassing because Go doesn't implement it. But Go does provide something similar called embedding types.
In this example I'll define a new organism, Animal, that draws ExpelWaste() from LivingBeing, but defines its own TakeInEnergy():
type Animal struct {
Organism // the syntax for an embedded type: type but no field name
}
func (a *Animal) TakeInEnergy() {
fmt.Printf("I am an animal")
}
What isn't obvious from that code is that because Animal's Organism is not a named field, its fields and methods are accessible directly from Animal. It's almost as if Animal "is an" organism.
However it is *not * an organism. It is a different type, and it would be more accurate to think of object embedding as syntactic sugar to automatically promote Organism's fields and methods to Animal.
Since go is statically and explicitly typed, DoLife cannot take an Organism and then be passed an Animal: it doesn't have the same type:
/* This does not work. Animal embeds organism, but *is not* an organism */
func DoLife(being *Organism) {
being.TakeInEnergy()
being.ExpelWaste()
}
func main() {
var a = &Animal{Organism{}}
DoLife(&Animal{})
}
cannot use &Animal{} (type *Animal) as type *Organism in argument to DoLife
That's why interface exists - so that both Organism and Animal (and indeed, even Plant or ChemotrophBacteria) can be passed as a LivingBeing.
Putting it all together, here's the code I've been working from:
package main
import "fmt"
type LivingBeing interface {
TakeInEnergy()
ExpelWaste()
}
type Organism struct{}
func (o *Organism) TakeInEnergy() {
}
func (o *Organism) ExpelWaste() {}
type Animal struct {
Organism
}
func DoLife(being LivingBeing) {
being.TakeInEnergy()
being.ExpelWaste()
}
func (a *Animal) TakeInEnergy() {
fmt.Printf("I am an animal")
}
func main() {
var a = &Animal{Organism{}}
DoLife(a)
}
There are a few caveats:
Syntactically, If you want to declare an embedded literal you must explicitly provide its type. In my example Organism has no fields so there's nothing to declare, but I still left the explicit type in there to point you in the right direction.
DoLife can call the right TakeInEnergy on a LivingBeing, but Organism's methods cannot. They see only the embedded Organism.
func (o *Organism) ExpelWaste() {
o.getWaste() //this will always be Organism's getWaste, never Animal's
}
func (o *Organism)getWaste() {}
func (a *Animal)getWaste() {
fmt.Println("Animal waste")
}
Simlarly if you pass only the embedded part, then it's going to call its own TakeInEnergy(), not that of Animal; there's no Animal left!
func main() {
var a = &Animal{Organism{}}
DoLife(&a.Organism)
}
In summary,
Define explict interface and use that type wherever you want "polymorphic" behavior
Define base types and embed them in other types to share base functionality.
Don't expect the "base" type to ever "bind" to functions from the "derived" type.
I have the following code setup;
abstract class GenericQuestionEditor() {
protected abstract var data: GenericQuestionData
}
but then when I create EditorSimple() it throws an error when I try to set data to DataSimple(), why?
class EditorSimple(): GenericQuestionEditor() {
override var data = DataSimple()
}
my GenericQeustionData and DataSimple() are setup like this;
abstract class GenericQuestionData {}
class DataSimple: GenericQuestionData() {}
it doesn't complain if I create this function in GenericQuestionEditor()
fun test() {
data = DataSimple()
}
Why do I get an error on data in EditorSimple()? It should recognize it as a subtype and it should be allowed as I understand.
I feel like the answer is found in the kotlin documentation but i'm not sure how to configure it in this case since they are not passed values or part of a collection.
You need to specify the type explicitly:
class EditorSimple(): GenericQuestionEditor() {
override var data: GenericQuestionData = DataSimple()
}
Without the type annotation, the type of data would be inferred to be DataSimple, which doesn't match the type of its super class' data. Even though the types are related, you can't override writable a property with a subtype. Imagine if I did:
class SomeOtherData: GenericQuestionData()
val editor: GenericQuestionEditor = EditorSimple()
editor.data = SomeOtherData() // data is of type GenericQuestionData, so I should be able to do this
But, editor actually has a EditorSimple, which can only store DataSimple objects in data!
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.
While i am reading document of Kotlin, i saw that we should avoid using open properties declared at base class:
It means that, by the time of the base class constructor execution, the properties declared or overridden in the derived class are not yet initialized. If any of those properties are used in the base class initialization logic (either directly or indirectly, through another overridden open member implementation), it may lead to incorrect behavior or a runtime failure. When designing a base class, you should therefore avoid using open members in the constructors, property initializers, and init blocks.
The document said that properties in derived class are not yet initialized when base class's constructor is called. But, how can we access derived class's properties which are not initialized, from base class constructor(I assumed that the incorrect behavior or a runtime failure were caused by this situation)? Is it possible?
I don't know kotlin, but I'm assuming that open is the same as virtual in other languages. It is unsafe to call virtual members in a base class constructor because the base constructor is called before the derived constructor. If the overridden property requires that the derived class be fully initialized it can cause errors because the derived constructor has not yet been called when you are inside the base constructor. At least that is the way it works in .NET languages like C#.
Open functions in Kotlin are functions which can be overridden by a subclass. Generally, it's a good practice to limit a class's inheritance because you should provide a class with it's necessary codes to make it overridable. If your intention is not to let a class to override your base class, then you should make it final. So Kotlin make this easy by making each class and method final by default. You can find a more detailed answer in the Objects and Class chapter of the book Kotlin in Action.
The so-called fragile base class problem occurs when modifications of a base class
can cause incorrect behavior of subclasses because the changed code of the base class no
longer matches the assumptions in its subclasses. If the class doesn’t provide exact rules
for how it should be subclassed (which methods are supposed to be overridden and how),
the clients are at risk of overriding the methods in a way the author of the base class
didn’t expect. Because it’s impossible to analyze all the subclasses, the base class is
"fragile" in the sense that any change in it may lead to unexpected changes of behavior in
subclasses.
To protect against this problem, Effective Java by Joshua Bloch (Addison-Wesley,
2008), one of the best-known books on good Java programming style, recommends that
you "design and document for inheritance or else prohibit it." This means all classes and
methods that aren’t specifically intended to be overridden in subclasses need to be
explicitly marked as final .
Kotlin follows the same philosophy. Whereas Java’s classes and methods are open by
default, Kotlin’s are final by default.
I assume you are asking about this example in Kotlin documentation:
open class Base(val name: String) {
init { println("Initializing a base class") }
open val size: Int =
name.length.also { println("Initializing size in the base class: $it") }
}
class Derived(
name: String,
val lastName: String,
) : Base(name.replaceFirstChar { it.uppercase() }.also { println("Argument for the base class: $it") }) {
init { println("Initializing a derived class") }
override val size: Int =
(super.size + lastName.length).also { println("Initializing size in the derived class: $it")
}
}
Kotlin designers followed good practices learned, from other language mistakes, so they made class, properties, and functions closed by default for overriding or inheriting. why?
let's add the open modifier to the base class property and override it:
open class Base(open val name: String) {
init { println("Initializing a base class") }
open val size: Int =
name.length.also { println("Initializing size in the base class: $it") }
}
class Derived(
override val name: String,
val lastName: String,
) : Base(name.replaceFirstChar { it.uppercase() }.also { println("Argument for the base class: $it") }) {
init { println("Initializing a derived class") }
override val size: Int =
(super.size + lastName.length).also { println("Initializing size in the derived class: $it") }
}
fun main() {
println("Constructing the derived class(\"hello\", \"world\")")
Derived("hello", "world")
}
if you run this code the output will be like below:
Constructing the derived class("hello", "world")
Argument for the base class: Hello
Initializing a base class
**Exception in thread "main" java.lang.NullPointerException
at Base.<init> (File.kt:6)
at Derived.<init> (File.kt:12)
at FileKt.main (File.kt:23)**
The error is happening because this line of code
open val size: Int =
name.length.also { println("Initializing size in the base class: $it") }
Why? when we were trying to initialize the Derived class, first the superclass is initialized first, so the initialization is done by evaluating the super constructor argument, then the properties and init blocks in their declaration order in the class.
when it comes to val size: Int = name.length.also{...} the initialization calls the name property which is overridden by the Derived class, the one that does NOT yet initialize.
so by avoiding marking the base properties by open, you protect the base class client from abusing the class.