Как я могу получить конкретный экземпляр, когда я использую статический метод - PullRequest
0 голосов
/ 14 февраля 2019

Я надеюсь получить конкретный экземпляр, когда использую свой статический метод.Например:

class Food: NSObject {
    var name: String

    class func initFruit() -> Food? {
        let fruitName = NSStringFromClass(self).components(separatedBy: ".").last! as String

        if "Apple" == fruitName {
            return Apple(name: fruitName)
        } else if "Orange" == fruitName {
            return Orange(name: fruitName)
        }
        return nil
    }

    init(name: String) {
        self.name = name
    }

}

class Apple: Food {
}
class Orange: Food {
}

Когда я создаю экземпляр Apple с помощью метода:

let apple = Apple.initFruit() as? Apple

Как получить конкретный экземпляр Apple вместо использования as? Apple ?.Интересно, как изменить метод:

 static func initFruit() -> Food?

Ответы [ 3 ]

0 голосов
/ 14 февраля 2019

Есть несколько проблем с вашим дизайном, позвольте мне попытаться перечислить их:

  • базовые классы не должны знать о своих подклассах, это плохая практика и не масштабируется, так как добавлениеновый подкласс потребует поддержки метода базового класса
  • , статический метод вообще не нужен, по крайней мере в той форме, в которой он написан в вопросе, вы можете просто напрямую вызывать инициализаторы для подклассов

Оставляя все это в стороне, вы можете использовать Self в качестве типа возврата для статического метода, это позволит получить динамические результаты.

class Food: NSObject {
    var name: String

    class func initFruit() -> Self {
        let fruitName = NSStringFromClass(self).components(separatedBy: ".").last! as String

        return self.init(name: fruitName)
    }

    required init(name: String) {
        self.name = name
    }

}

class Apple: Food {
}
class Orange: Food {
}

let apple = Apple.initFruit() // is an Apple, no cast needed
0 голосов
/ 15 февраля 2019

Вдохновленный вопросом Generics in Swift - "Общий параметр 'T' не может быть выведен Я нахожу другой способ решения этого вопроса. Я добавляю метод для вывода определенного типа.

func ascertainFruitType<T>() -> T {
    return self as! T // as! is dangerous
}

Затем метод initFruit изменяется на:

class func initFruit() -> Self {
    let fruitName = NSStringFromClass(self).components(separatedBy: ".").last! as String

    if "Apple" == fruitName {
        return Apple(name: fruitName).ascertainFruitType()
    } else {
        return Orange(name: fruitName).ascertainFruitType()
    }

}
0 голосов
/ 14 февраля 2019

я думаю, что это не очень хорошая идея, потому что Food - это родительский класс, а Apple наследует Food.Apple может знать, что это родительский класс, потому что продлевает еду, а еда - нет.

Итак, если вы хотите создать экземпляр по какой-либо строке или некоторой переменной.Я хотел бы рекомендовать вам принять "Заводской шаблон"

ссылка здесь: https://medium.com/swift-programming/design-patterns-creational-patterns-factory-pattern-in-swift-d049af54235b

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...