How to change override function return type in Swift - objective-c

#objc public class A: NSObject
{
public func getSomething() -> Something
{
return Something()
}
}
#objc public class B: A{
override public func getSomething() -> SomethingGood
{
return SomethingGood()
}
}
#objc public class C: A{
...
}
#objc public class Something: NSObject{
var name: String=“”
}
#objc public class SomethingGood: Something{
var type_id: Int = 0
}
Swift compiler shows incompatible types for class B's override function. How do I implement the above? I have tried to use Generics but they are not available for Objective-C developer once the library is built.
I want to be able to use:
A.getSomething() and C.getSomething() to return an object of Something
And B.getSomething() to return an object of SomethingGood.
And I don't want to get two same named function which is func getSomething() for B with two different return types.
Any idea?
The code is used in a static library written in Swift. Once the library is compiled, it should be available to both swift and objective-c.

You can't change the return type, or it wouldn't be an override. You can still return SomethingGood in this case, just your function declaration can't show the return type as that.
#objc public class B: A{
override public func getSomething() -> Something
{
return SomethingGood()
}
// now whereever you're calling this, if you know it's SomethingGood, you can cast it
if let somethingGood = b.getSomething() as? SomethingGood {
// do something good
}

Related

How do you resolve circular imports in Kotlin

I'm new to programming in Kotlin and I've already managed to run into the classic circular dependency issue - I know Kotlin can cope with those but I'd like to know how would I go about changing my design to avoid it. What structures or Kotlin functionality should I use in the following?
import MyClass
interface MyInterface {
fun useMyClass(myInstance: MyClass)
}
import MyInterface
class MyClass(myList: List<MyInterface>) {
val storedList: List<MyInterface> = myList
var myValue: Int = 10
}
I would like MyClass to store multiple objects which implement MyInterface, but I would also like each of those objects to reference the class they have been passed to, i.e. each call of useMyClass would have the signature of useMyClass(this).
For example, I could create a class
class ImplementingMyInterfaceClass(): MyInterface {
override fun useMyClass(myInstance: MyClass) {
myInstance.myValue += 10
}
}
and call it somewhere within MyClass:
ImplementingMyInterfaceClass().useMyClass(this)
Technically I could create another construct in the middle which would be used by MyInterface and inherited/implemented by MyClass, but this just doesn't feel correct. Any suggestions?
Note: In my specific issue, it might be helpful to consider each implementation of MyInterface as a sort of a "modifier" (since it will modify the instance of the class) - MyClass instances should be aware of its modifiers and each modifier should be able to modify that instance.
It's going to largely depend on what the interface has to do, but you could limit its function argument to some interface that MyClass implements:
interface MyInterface {
fun increaseSomeValue(someValueHolder: MySubInterface)
interface MySubInterface {
var myValue: Int
}
}
class MyClass(myList: List<MyInterface>): MyInterface.MySubInterface {
val storedList: List<myInterface> = myList
override var myValue: Int = 10
}
Or your interface can take a property argument:
interface MyInterface {
fun increaseSomeValue(someValue: KMutableProperty<Int>)
}
class MyInterfaceImpl: MyInterface {
override fun increaseSomeValue(someValue: KMutableProperty<Int>) {
someValue.setter.call(someValue.getter.call() + 10)
}
}
// from MyClass:
storedList.first().printSomeValue(::myValue)
In other cases where we don't need to both get and set, it could be cleaner to take a more versatile function argument (lambdas could be passed):
interface MyInterface {
fun printSomeValue(valueProvider: () -> Int)
}
class MyInterfaceImpl: MyInterface {
override fun printSomeValue(valueProvider: () -> Int) {
println(valueProvider())
}
}
// from MyClass:
storedList.first().printSomeValue(::myValue)
// or
storedList.first().printSomeValue { 1..10.random() }

Method References to Super Class Method

How to use method references to refer to super class methods?
In Java 8 you can do SubClass.super::method.
What would be the syntax in Kotlin?
Looking forward to your response!
Conclusion
Thanks to Bernard Rocha!
The syntax is SubClass::method.
But be careful. In my case the subclass was a generic class. Don't forget to declare it as those:
MySubMap<K, V>::method.
EDIT
It still doesn't work in Kotlin.
Hers's an example in Java 8 of a method reference to a super class method:
public abstract class SuperClass {
void method() {
System.out.println("superclass method()");
}
}
public class SubClass extends SuperClass {
#Override
void method() {
Runnable superMethodL = () -> super.method();
Runnable superMethodMR = SubClass.super::method;
}
}
I'm still not able to do the same in Kotlin...
EDIT
This is an example how I tried to achieve it in Kotlin:
open class Bar {
open fun getString(): String = "Hello"
}
class Foo : Bar() {
fun testFunction(action: () -> String): String = action()
override fun getString(): String {
//this will throw an StackOverflow error, since it will continuously call 'Foo.getString()'
return testFunction(this::getString)
}
}
I want to have something like that:
...
override fun getString(): String {
//this should call 'Bar.getString' only once. No StackOverflow error should happen.
return testFunction(super::getString)
}
...
Conclusion
It's not possible to do so in Kotlin yet.
I submitted a feature report. It can be found here: KT-21103 Method Reference to Super Class Method
As the documentation says you use it like in java:
If we need to use a member of a class, or an extension function, it
needs to be qualified. e.g. String::toCharArray gives us an extension
function for type String: String.() -> CharArray.
EDIT
I think you can achieve what you want doing something like this:
open class SuperClass {
companion object {
fun getMyString(): String {
return "Hello"
}
}
}
class SubClass : SuperClass() {
fun getMyAwesomeString(): String {
val reference = SuperClass.Companion
return testFunction(reference::getMyString)
}
private fun testFunction(s: KFunction0<String>): String {
return s.invoke()
}
}
Don't know if it is possible to get the reference to super class's function, but here is an alternative to what you want to achieve:
override fun getString(): String = testFunction { super.getString() }
According to Bernardo's answer, you might have something like this. It doesn't have remarkable changes.
fun methodInActivity() {
runOnUiThread(this::config)
}
fun config(){
}
What is more, in the incoming 1.2 version you can use just
::config

Get companion class in companion object

Is there a way to get the javaClass of the companion class inside a companion object without knowing it's name?
I suppose I could get it by doing something like this:
open class TestClass {
companion object {
init {
val clazz = Class.forName(this::class.java.canonicalName.removeSuffix(".Companion"))
}
}
}
However, this does not work for class InheritingClass : TestClass(). It would still give me TestClass, not InheritingClass.
I was hoping for something more straightforward like this::class.companionClass.
Getting the class of the companion object of a given class will look like this:
TestClass::class.companionObject
Here's an example:
class TestClass {
companion object {
fun sayHello() = "Hello world"
}
}
If you want to get the class that contains the companion, since the latter is always an inner class of the former,
class TestClass {
companion object {
fun whichIsMyParentClass() = this::class.java.declaringClass // It'll return TestClass
}
}
And to further simplify, you'll also want to create an extension property:
import kotlin.reflect.KClass
val <T : Any> KClass<T>.companionClass get() =
if (isCompanion)
this.java.declaringClass
else
null
So, whenever you want to get the parent class of the companion object,
class TestClass {
companion object {
fun whichIsMyParentClass() = this::class.companionClass // It'll return TestClass
}
}
The companion class itself has no reference to the actual class as you can see in this bytecode
public final class TestClass$Companion {
private TestClass$Companion() { // <init> //()V
<localVar:index=0 , name=this , desc=LTestClass$Companion;, sig=null, start=L1, end=L2>
L1 {
aload0 // reference to self
invokespecial java/lang/Object <init>(()V);
return
}
L2 {
}
}
public TestClass$Companion(kotlin.jvm.internal.DefaultConstructorMarker arg0) { // <init> //(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
<localVar:index=0 , name=this , desc=LTestClass$Companion;, sig=null, start=L1, end=L2>
<localVar:index=1 , name=$constructor_marker , desc=Lkotlin/jvm/internal/DefaultConstructorMarker;, sig=null, start=L1, end=L2>
L1 {
aload0 // reference to self
invokespecial TestClass$Companion <init>(()V);
return
}
L2 {
}
}
}
The reference is only the other way around (see decompiled kotlin class)
public final class TestClass {
public static final Companion companion = ...
}
So you can either do it as you just did by cutting off the .Companion part of the class name or you reference it by hard with TestClass::class.java (what is in my opinion no problem and the best solution)
If you need to print the class name, you can add simpleName, such as
this::class.java.declaringClass.simpleName

May I implement one function of protocol in subclass?

I just modified it. Another problem is that if I want to have a subclass inherit from BaseParticipant, may I re-implement func performEvent inside the subclass?
For example:
class CyclingParticipant: BaseParticipant, Participant
{
init(name: String)
{
super.init(name: name, preferredEvent: Event.CYCLING)
}
func performEvent(event: Event, distance: Distance) throws
{
}
}
but the compiler said "redundant conformance of CyclingParticipant to protocol Participant .
class BaseParticipant: Participant
{
var name: String
var preferredEvent: Event
var raceTime: Int
var couldNotFinish: Bool
//var performedEvent: Event
// in swift, the class accepts protocol must impletment all funcs inside protocol
init(name: String, preferredEvent: Event)
{
self.name = name
self.preferredEvent = preferredEvent
self.raceTime = 0
self.couldNotFinish = false
}
func getName() -> String
{
return self.name
}
func getPreferredEvent() -> Event
{
return self.preferredEvent
}
func isDisqualified() -> Bool
{
return self.couldNotFinish
}
func addTime(addtionalRaceTime:Int) -> Void
{
self.raceTime += addtionalRaceTime
}
func setCouldNotFinish() -> Void
{
self.couldNotFinish = true
}
func performEvent(event: Event, distance: Distance) throws -> Int
{
return 1
}
func getTime() throws
{
}
}
The code of protocol Participant:
protocol Participant
{
func getName() -> String
func getPreferredEvent() -> Event
func isDisqualified() -> Bool
func performEvent(event: Event,distance: Distance) throws ->Int
func addTime(addtionalRaceTime: Int)
func setCouldNotFinish()
func getTime() throws
}
You're missing an implementation of the getTime() function as listed in your Protocol. Also, you should post such questions on Piazza. :P
[Updating to answer reworded question]
The BaseParticipant class already adopts the Participant protocol, so the CyclingParticipant subclass should not declare that it adopts it also, this is causing the redundant conformance error. Because BaseParticipant is already a Participant, any subclass of BaseParticipant will also be a Participant.
Change:
class CyclingParticipant: BaseParticipant, Participant
to:
class CyclingParticipant: BaseParticipant
All declared methods in a Swift protocol are required by default.
getTime() is not implemented

How to specify "own type" as return type in Kotlin

Is there a way to specify the return type of a function to be the type of the called object?
e.g.
trait Foo {
fun bar(): <??> /* what to put here? */ {
return this
}
}
class FooClassA : Foo {
fun a() {}
}
class FooClassB : Foo {
fun b() {}
}
// this is the desired effect:
val a = FooClassA().bar() // should be of type FooClassA
a.a() // so this would work
val b = FooClassB().bar() // should be of type FooClassB
b.b() // so this would work
In effect, this would be roughly equivalent to instancetype in Objective-C or Self in Swift.
There's no language feature supporting this, but you can always use recursive generics (which is the pattern many libraries use):
// Define a recursive generic parameter Me
trait Foo<Me: Foo<Me>> {
fun bar(): Me {
// Here we have to cast, because the compiler does not know that Me is the same as this class
return this as Me
}
}
// In subclasses, pass itself to the superclass as an argument:
class FooClassA : Foo<FooClassA> {
fun a() {}
}
class FooClassB : Foo<FooClassB> {
fun b() {}
}
You can return something's own type with extension functions.
interface ExampleInterface
// Everything that implements ExampleInterface will have this method.
fun <T : ExampleInterface> T.doSomething(): T {
return this
}
class ClassA : ExampleInterface {
fun classASpecificMethod() {}
}
class ClassB : ExampleInterface {
fun classBSpecificMethod() {}
}
fun example() {
// doSomething() returns ClassA!
ClassA().doSomething().classASpecificMethod()
// doSomething() returns ClassB!
ClassB().doSomething().classBSpecificMethod()
}
You can use an extension method to achieve the "returns same type" effect. Here's a quick example that shows a base type with multiple type parameters and an extension method that takes a function which operates on an instance of said type:
public abstract class BuilderBase<A, B> {}
public fun <B : BuilderBase<*, *>> B.doIt(): B {
// Do something
return this
}
public class MyBuilder : BuilderBase<Int,String>() {}
public fun demo() {
val b : MyBuilder = MyBuilder().doIt()
}
Since extension methods are resolved statically (at least as of M12), you may need to have the extension delegate the actual implementation to its this should you need type-specific behaviors.
Recursive Type Bound
The pattern you have shown in the question is known as recursive type bound in the JVM world. A recursive type is one that includes a function that uses that type itself as a type for its parameter or its return value. In your example, you are using the same type for the return value by saying return this.
Example
Let's understand this with a simple and real example. We'll replace trait from your example with interface because trait is now deprecated in Kotlin. In this example, the interface VitaminSource returns different implementations of the sources of different vitamins.
In the following interface, you can see that its type parameter has itself as an upper bound. This is why it's known as recursive type bound:
VitaminSource.kt
interface VitaminSource<T: VitaminSource<T>> {
fun getSource(): T {
#Suppress("UNCHECKED_CAST")
return this as T
}
}
We suppress the UNCHECKED_CAST warning because the compiler can't possibly know whether we passed the same class name as a type argument.
Then we extend the interface with concrete implementations:
Carrot.kt
class Carrot : VitaminSource<Carrot> {
fun getVitaminA() = println("Vitamin A")
}
Banana.kt
class Banana : VitaminSource<Banana> {
fun getVitaminB() = println("Vitamin B")
}
While extending the classes, you must make sure to pass the same class to the interface otherwise you'll get ClassCastException at runtime:
class Banana : VitaminSource<Banana> // OK
class Banana : VitaminSource<Carrot> // No compiler error but exception at runtime
Test.kt
fun main() {
val carrot = Carrot().getSource()
carrot.getVitaminA()
val banana = Banana().getSource()
banana.getVitaminB()
}
That's it! Hope that helps.
Depending on the exact use case, scope functions can be a good alternative. For the builder pattern apply seems to be most useful because the context object is this and the result of the scope function is this as well.
Consider this example for a builder of List with a specialized builder subclass:
open class ListBuilder<E> {
// Return type does not matter, could also use Unit and not return anything
// But might be good to avoid that to not force users to use scope functions
fun add(element: E): ListBuilder<E> {
...
return this
}
fun buildList(): List<E> {
...
}
}
class EnhancedListBuilder<E>: ListBuilder<E>() {
fun addTwice(element: E): EnhancedListBuilder<E> {
addNTimes(element, 2)
return this
}
fun addNTimes(element: E, times: Int): EnhancedListBuilder<E> {
repeat(times) {
add(element)
}
return this
}
}
// Usage of builder:
val list = EnhancedListBuilder<String>().apply {
add("a") // Note: This would return only ListBuilder
addTwice("b")
addNTimes("c", 3)
}.buildList()
However, this only works if all methods have this as result. If one of the methods actually creates a new instance, then that instance would be discarded.
This is based on this answer to a similar question.
You can do it also via extension functions.
class Foo
fun <T: Foo>T.someFun(): T {
return this
}
Foo().someFun().someFun()