Could the Swift Jedi help me, I'm new to Swift.
There is class A and class B.
Is it possible to get the name (var name = Class A() ) of an instance of class A in the code of class B, which would then be added to the array.
You can get the class of an object, using type(of: ...). Example:
class A {
func test() {
print (type(of: self))
}
}
class B : A{
}
let a = A()
a.test()
let b = B()
b.test()
However, this information is available only at runtime and not at compile time. You may for example display the name of the class. But you cannot dynamically create an array or a variable of that class.
If you need this, you need to design your classes using some kind of polymorphism. If all the classes have a base class in common, you can just define an array of the base class. If not, you may consider letting the classes of your design share some common protocol:
protocol MySpecs {
func test()
}
class AA : MySpecs {
...
}
class BB : MySpecs {
...
}
var mylist = [ MySpecs ]()
mylist.append(AA())
mylist.append(BB())
for x in mylist {
x.test()
}
There are other possibilities. But unless you provide more details it'll be difficult to be more specific in the recommendations.
My code:
open class Club(name: String, country: String)
class FemaleClub(): Club()
var femaleClub = FemaleClub("Blue", "Australia")
Why is the above code not possible?
Why does it have the error
no value passed for parameter name
and
no value passed for parameter country
in my subclass? The values are set when I initiate femaleClub.
In your example parent class Club has primary constructor which is, by language specification, must be called either from secondary constructors of the same class or primary constructor of subclasses to initialize parameters defined in primary constructor. If you don't want to call a primary constructor of a parent class from subclasses you have a couple of options:
Set default values to parameters of primary constructor:
open class Club(name: String = "DefaultName", country: String = "Country") {
}
In this case you will not be able to call primary constructor with params:
// this is not possible
var femaleClub = FemaleClub("Blue", "Australia")
Create secondary constructor in parent class which calls primary constructor:
open class Club(name: String, country: String) {
constructor(): this("Name", "Country")
}
But also you won't be able to call FemaleClub("Blue", "Australia").
To be able to call constructor with parameters of a subclass FemaleClub("Blue", "Australia") you need explicitly define them in primary constructor of the subclass and call parent's primary constructor, i.e.:
class FemaleClub(name: String, country: String): Club(name, country) {}
There are some problems with your code:
FemaleClub does not have a constructor which accepts two arguments, even if the base class has one.
The primary constructor of the inherited class should call the primary constructor of the base class. Because your base class accepts two non-nullable arguments, you have to provide them to it, otherwise your code wont compile.
These issues can be fixed in the following way:
class FemaleClub(name: String, country: String): Club(name, country) {
}
About Kotlin classes and inheritance, read here Classes and Inheritance and here Kotlin Inheritance.
You can use at least four approaches to get what you want:
First approach (default values):
open class Club(var name: String = "Blue", var country: String = "Australia") { }
public class FemaleClub(): Club() { }
fun main() {
var femaleClub = FemaleClub()
println("RESULT: ${femaleClub.country}")
}
// RESULT: Australia
Second approach (passing values):
open class Club(var name: String, var country: String) { }
class FemaleClub(): Club("Green", "NZ") { }
fun main() {
var femaleClub = FemaleClub()
println("RESULT: ${femaleClub.country}")
}
// RESULT: NZ
Third approach (init block):
open class Club(name: String, country: String) {
var name: String = "Blue"
var country: String = "Australia"
init {
this.name = name
this.country = country
}
}
class FemaleClub(): Club("Green", "NZ") { }
fun main() {
var femaleClub = FemaleClub()
println("RESULT: ${femaleClub.country}")
}
// RESULT: NZ
Fourth approach (class sec.constructor):
open class Club {
var name: String
var country: String
constructor(name: String = "Blue", country: String = "Australia") {
this.name = name
this.country = country
}
}
class FemaleClub(): Club() { }
fun main() {
var femaleClub = FemaleClub()
println("RESULT: ${femaleClub.country}")
}
// RESULT: Australia
In FemaleClub you are not specifying what should be passed to Club as its 2 String arguments, name and country.
And you are not specifying anywhere that FemaleClub takes 2 strings as constructor arguments, so the last line wont work either.
You need to invoke the constructor (primary/secondary) from the class you want to inherit from.
Club only has one constructor, the primary constructor. It takes two strings as parameters. Club does not have an empty constructor.
So, it cannot be invoked as Club().
I would propose two changes.
1) Make name and country of Club properties
open class Club(name: String, country: String)
2) Declare parameters in FemaleClub's primary constructor
Since you want to be able to specify values for name and country when you instantiate FemaleClub it would be a good idea to give the primary constructor of FemaleClub name and country as parameters.
Additionally I would recommend using named parameters when passing on the values, since you can easily mix up the two strings (resulting in passing name as country and country as name.
class FemaleClub(name: String, country: String): Club(name = name, country = country)
I'm stuck.
I try to make right code's architect but I can not solve following case:
I have some base class and inherited from it class like:
class BaseClass {
var name: String
init(name: String) {
self.name = name
}
}
class ChildClass: BaseClass {
var otherName: String
init(otherName: String) {
self.otherName = otherName
}
}
And the following function:
func someFunc() -> BaseClass {
let a = ChildClass.init(otherName: "NAME")
return a
}
How can I get the parameter "otherName"?
The available parameter is only one - "name", but I want to get "otherName":
let b = someFunc()
b.PARAMETERS
You can use:
(b as! ChildClass).otherName
Your function returns your object as BaseClass object, so you can't access any of ChildClass methods. In order to access ChildClass methods, you need to cast your object to ChildClass using as!, as we know it is a ChildClass object. After that you'll be able to access all the parameters of ChildClass.
I would like to get the class of an object in a macro so that I can access its static variables:
// autoBuild macro adds static field "id_ : Int" to all subclasses
class Base {
}
class Child1 extends Base {
public function new() {}
}
class Child2 extends Base {
public function new() {}
}
class Container {
public function addChild(index: Int, object: Base) {}
macro function add(object: ???) {
// find out class of on object
// ???
// var id = class.id_;
this.addChild(id, object);
}
}
Desired usage:
var c = new Container();
c.add(new Child1());
c.add(new Child2());
You can use Context.typeof() to get the expression's type - then you need to do a bit of pattern matching to find out the type's name. The following only works with classes because it only matches TInst, but could be extended:
import haxe.macro.Context;
import haxe.macro.Expr;
class Container {
// [...]
public macro function add(self:Expr, object:Expr):Expr {
var name = switch (Context.typeof(object)) {
case TInst(_.get() => t, _): t.name;
case _: throw "object type not found";
}
return macro $self.addChild($i{name}.id_, $object);
}
}
This will generate the following code:
var c = new Container();
c.addChild(Child1.id_, new Child1());
c.addChild(Child2.id_, new Child2());
Note that accessing _id via it's unqualified name is only safe if it's actually imported (or toplevel) - in practice you'd want to use t.pack in combination with $p{} to generate the fully qualified path.
I want to get access to an argument in a private constructor without using mutable variables:
class Class1 {
val strArgPublic = // get strArg argument from the private constructor. How?
private def this(strArg: String) = {
//.....
}
}
I want not only get strArg and return it, but change it a little bit and return a new modified copy of it.
How can I do this?
There is not only private constructor in your class. There is also a public constructor. You should decide what will be a value of strArgPublic after public constructor. If there is should be no public constructor you should define your class like this:
class Class1 private(strArg: String) {
val strArgPublic = transform(strArg)
}
If there should be a parameterless public constructor you could define one as auxiliary constructor:
class Class1 private(strArg: String) {
val strArgPublic = transform(strArg)
def this() = this("default")
}