How do I get value from superclass attribute? - swift

Suppose I have SuperClass and I want to get its attribute value to subclass
class Person {
var name = String()
init(name : String){
self.name = name
}
}
var JonSnow = Person(name : "Jon Snow")
class Ranger : Person {
func getRangerName()->String {
return "Ranger name is \(super.name)"
}
// I want to get name value from super class
}
How do I get name value directly from super class Without reinit the value in subclass ?

You can simply access it self.x
So using your code:
class Person {
var name : String = "Jon Snow"
}
class Ranger : Person {
func printName() {
print(self.name)
}
}
Edit
Here is a full working project with that example implemented: download project

Related

How to use enums for class functions

I'm working on a project and I have created a class to handle the json response to convert it to modal class and change it back to json request with updated data if needed.
Here in the class I'm getting and saving values from and into dictionary. I need to create an enum for the dictionary keys so that there should be less chance for error for complex key formats.
I even tried using like
enum Fields {
case Name
case Email
}
but Fields.Email return Fields object
if I use a protocol of a variable like
protocol someProtocol {
var name: String { get }
}
extension someProtocol {
var name:String {
return String(describing: self)
}
}
and then extend the enum Fields:someProtocol
then I can use it like Fields.name.name or Fields.email.name
But My client will not approve this I want to create an enum so that I can access the string directly like for name I want key "Name" and I should get it liek "Fields.name" or ".name"
So here I have two objectives
first it that I need to create something that can be accessed through class function
second it should be common so that I can use it with multiple classes
third I can access it with less operators
—
class PersonService {
class Update {
var name = ""
var email = ""
var personId = 0
func createDataFrom(dic:[AnyHashable : Any]) -> Update {
let update = Update()
update.name = dictionary["Name"]
update.email = dictionary["Email"]
update.personId = dictionary["Id"]
return update
}
func createDataTo() -> [AnyHashable:Any] {
var ret = [AnyHashable : Any]()
ret["Name"] = name
ret["Email"] = email
ret["Id"] = personId
return ret
}
}
}
Something like that?
enum Fields: String {
case Name = "Name"
case Email = "Email"
}
Print(Fields.Name.rawValue)
result: "Name"
Or
struct Constants {
static let name = "Name"
static let email = "Email"
}
print(Constants.name)
result: "Name"

Why Instance member 'getPerson' cannot be used on type 'GetPerson'

I write code in a Cocoa framework and call the function in it from main project. But it fails always returning a message. I fix this in two ways.
First, in main project viewController:
import getPerson
override func viewDidLoad() {
super.viewDidLoad()
var person = GetPersons.getPerson(name: "Jack")
}
Returns:
Instance member 'getPerson' cannot be used on type 'GetPerson'; did you mean to use a value of this type instead
Second:
import getPerson
override func viewDidLoad() {
super.viewDidLoad()
let vc = GetPersons.self
var person = vc.getPerson(name: "Jack")
}
Returns:
Instance member 'getPerson' cannot be used on type 'GetPersons'
What's happening with this? How do I fix it?
In test framework :
import Fundation
public class GetPersons {
public struct Person {
public var name : String = ""
public var age : Int = 0
}
public func getPerson(name : String) -> Person {
var person = Person()
return person
}
}
In your first example, it's telling you that you defined getPerson(name: String) as an instance method. (Presumably because it operates on instance properties.)
You are calling it here as if it were defined as:
static func getPerson(name: String) { ...
The second is saying much the same thing, without guessing what you want to do.
If I understand what you want to do, I think it goes something like this:
class GetPersons {
struct Person {
public var name : String = ""
public var age : Int = 0
}
func getPerson(name : String) -> Person {
var person = Person()
return person
}
}
Then, in your view controller define a property for the instance of GetPersons:
let gp = GetPersons()
then in viewDidLoad:
let person = gp.getPerson(name: "Jack")
Also, is GetPersons in an actual framework, or is it simply a class defined (as it should be) in a separate file?

self.name = name in Swift . I don't understand why this codes are needed

class person {
var name : String
init(name: String) {
self.name = name
}
}
I am learning Swift class chapter
I don't understand why init(name:String) self.name = name code is needed
what the purpose of this code is.
I declared var name: String
and again init(name: String), why is self.name = name needed?
what's different between just var name and self.name = name?
Look into something called variable scope. In your code - there are two "name variables - a class (or instance) variable and a "parameter in your init.
The latter - init(name:) only is in use within your initialization function, meaning the instance has no name without the self.name = name once you've created the instance.
The former is available - to the instance - as long as your instance of the class person is.
To explain further, try this. Change your code to be:
class Person {
var myName : String
var myOtherName : String
init(name: String) {
self.myName = name
}
}
In your app or view controller, do this:
let myPerson = Person(name: "john")
print(myPerson.myName) // prints "jihoon"
print(myPerson.myOtherName) // prints nothing
print(myPerson.name) // generates a build error because name doesn't exist
One last note - in Swift class names are capitalized, so the best name is Person, not person.
Classes and structures must set all of their stored properties to an appropriate initial value by the time an instance of that class or structure is created. Stored properties cannot be left in an indeterminate state.
class person {
var name : String // undetrmined state
init(name: String) {
self.name = name
}
}
class person2 {
var name : String = "default value" // detrmined state
// Now these intializer are not optional. You can use these initializer or not.
init(name: String) {
self.name = name
}
init() {
}
}
// Aother example for optional stored property
class person3 {
var name : String? // detrmined state, because default value for optional is nil
// Now these intializer are not optional. You can use these initializer or not.
init(name: String) {
self.name = name
}
init() {
}
}
For more info read this one Apple Doc

Swift inheritance issue. How to get appropriate class object

I have two classes (to simplify I drop other filed the object is more complicated then the Person):
class Person
{
var name: String = "Default name"
init(object: PersonEntity)
{
name = object.daysMask
}
}
class Employer: Person
{
}
I have function that configure for me a person
func getConiguratedPerson(name: String) -> Person
{
let person = Person()
person.name = name
}
In case if I want to get Person I simple do this:
let person = getConiguratedPerson("Alex")
but what if I need Employer instead and I want to use this function as well
let employer = getConiguratedPerson("Alex") // returns Person as expected but need to have employer instead.
In Objective-C we can simple do this:
Employer *employer = Employer([self getConiguratedPerson:"Alex"]) if I remember.
The mistake is the getConfiguredPerson function. You want an initializer. Initializers return your own class, which is exactly what you want.
class Person {
var name: String = "Default name"
init(name: String) {
self.name = name
}
init(object: PersonEntity) {
self.init(object.daysMask)
}
}
class Employer: Person {}
Now to create a person, you just use Person(name: "Alex") and to get an employer you use Employer(name: "Alex").
Note that this is true in ObjC as well. You shouldn't have getConfiguredPerson there either. You'd should have [Person initWithName:].
You can't use upcasting here, because configured person is not of Employee type, but of Person type. To achieve the desired result I would suggest something like this:
class Person {
var name = "name"
required init() { }
}
class Employee: Person { }
func getPerson<T: Person>(name: String) -> T {
let person = T()
person.name = name
return person
}
let employee: Employee = getPerson("Alex")
or this if type of object returning by factory method depends on input:
func getPerson(name: String) -> Person {
if name != "Alex" {
return Person()
}
return Employee()
}
let employee = getPerson("Alex") as! Employee

Initializers in class swift

What is the difference in initializing a variable:
class Person {
var name = String()
}
instead of:
class Person {
var name : String
init(name: String) {
self.name = name
}
}
thanks
First snippet
You can call
let person = Person()
Second snippet:
You must call
let person = Person(name:"")
to get an instance with an empty name property
PS: "" is easier to write than String()